[QUOTE]
Константин Кривенко написал:
[QUOTE] Алексей Огурцов написал:
А у меня не удаляются товары, которых нет в файле импорта через xml, что только не пробовал - результат нулевой[/QUOTE]
вот решение но на свой страх и риск.
у меня инфоблок использовался в качестве "буфера" а не сразу "боевого" инфоблока, основная логика импорта была в обработчике после выгрузки который переносил данные из буфера в боевой с нужной структурой.
т.к. времени на "научный тык" не особо есть - решил по другому, "в лоб".
дальше рассказываю конкретно про свой случай
------------
суть косяка "почему не удаляются отсутствующие товары" в том что на шаге "чистки" инфоблока (7 или 8 ) происходит ранний выход из метода класса, который ответственный за это.
деактивация (или удаление) происходит в методе CIBlockCMLImport::DeactivateElement , сам класс лежит в /bitrix/modules/iblock/classes/general/cml2.php
ранний выход происходит потому что дойдя до первого же return-условия оно оказывается "true"[CODE] if(array_key_exists("bUpdateOnly", $this->next_step) && $this->next_step["bUpdateOnly"])
return $counter; [/CODE]расследовать же почему $this->next_step["bUpdateOnly"] установился в тру я не хотел.
получается мне нужно отредактировать класс, однако следуя гайдам - править движок нехорошо.
решение заключается в том чтобы расширить класс системы своим классом, на время поменять этот параметр в false (чтобы не выходить из метода раньше чем следует), выполнить метод, потом вернуть все как было.
сам объект класса инстанцируется в 5 местах в component.php в bitrix:catalog.import.1c. - а менять компоненты битрикса тоже нехорошо - значит надо его откопировать.
порядок действий такой:
1. создать свой класс который расширяет \CIBlockCMLImport.
где и как он будет лежать физически - неважно. главное - файл должен быть подключен заранее до того как начнет работу компонент, в котором будут создаваться объекты этого класса (напрямую require в начале component.php или заранее через init.php > vendor/autoload.php как у нормальных людей)
пусть будет класс такой \MyProjectNameSpace\MySuperImport
2. скопировать bitrix:catalog.import.1c в свое пространство имен (например myproject:catalog.import.1c )
2.1. заменить все (на всякий случай) конструкторы CIBlockCMLImport на конструкторы своего класса \MyProjectNameSpace\MySuperImport в своем cкопированном компоненте myproject:catalog.import.1c (component.php)
конструктор выглядит примерно так[CODE] $obCatalog = new CIBlockCMLImport; [/CODE]и станет [CODE] $obCatalog = new \MyProjectNameSpace\MySuperImport; [/CODE]
3. создать файл куда будет стучаться 1с (или вы, руками, через [URL=https://yadi.sk/d/bKWfDG5hkMsnk]отладочный скрипт bx_1c_import.php[/URL] ).
кто то скажет - такой файл уже есть, это же /bitrix/admin/1c_exchange.php.
по факту так - однако это опять часть движка а его править "не айс". поэтому можно его тоже откопировать, прям тут же рядом, и обозвать например /bitrix/admin/1c_exchange_my_superfix.php.
3.1 по факту в файле есть всего лишь подключение другого скрипта, т.е. "делегирование" всей логики другому файлу.
однако для того чтобы не делать такую же чушь - надо скопировать в файл контент "делегированного" файла "/bitrix/modules/sale/admin/1c_exchange.php" , и просто заменить вызов в ветке
$type=='catalog' вместо bitrix:catalog.import.1c на свой myproject:catalog.import.1c . примерно на строке 66[CODE] elseif($type=="catalog")
{
$APPLICATION->IncludeComponent("bitrix:catalog.import.1c", "", Array( [/CODE]тогда обработка выгрузки каталога будет совершаться своим компонентом из п2
4. в классе MySuperImport сделать оверрайд метода DeactivateElement примерно таким образом:
[CODE] namespace MyProjectNameSpace;
class MySuperImport extends \CIBlockCMLImport
{
public function DeactivateElement($action, $start_time, $interval)
{
$saved = $this->next_step["bUpdateOnly"];
$this->next_step["bUpdateOnly"] = false;
$return = parent::DeactivateElement($action, $start_time, $interval);
$this->next_step["bUpdateOnly"] = $saved;
return $return;
}
}
[/CODE]5. не забыть о подключении класса \MyProjectNameSpace\MySuperImport до начала работы компонента
[/QUOTE]
[B]$this->next_step["bUpdateOnly"][/B][B] [/B]- тут сохраняется значение атрибута "[B]СодержитТолькоИзменения[/B]" во время импорта.
В файлах с товарами и группами в метаданных атрибут "СодержитТолькоИзменения" у тега "Каталог" должен быть равен false т.е [B]<Каталог СодержитТолькоИзменения="false"> [/B]тогда в этом случае штатные механизмы импорта отработают как надо, без необходимости что то модифицировать