Цитата |
---|
Алексей Огурцов написал: А у меня не удаляются товары, которых нет в файле импорта через xml, что только не пробовал - результат нулевой |
у меня инфоблок использовался в качестве "буфера" а не сразу "боевого" инфоблока, основная логика импорта была в обработчике после выгрузки который переносил данные из буфера в боевой с нужной структурой.
т.к. времени на "научный тык" не особо есть - решил по другому, "в лоб".
дальше рассказываю конкретно про свой случай
------------
суть косяка "почему не удаляются отсутствующие товары" в том что на шаге "чистки" инфоблока (7 или 8 ) происходит ранний выход из метода класса, который ответственный за это.
деактивация (или удаление) происходит в методе CIBlockCMLImport::DeactivateElement , сам класс лежит в /bitrix/modules/iblock/classes/general/cml2.php
ранний выход происходит потому что дойдя до первого же return-условия оно оказывается "true"
Код |
---|
if(array_key_exists("bUpdateOnly", $this->next_step) && $this->next_step["bUpdateOnly"]) return $counter; |
получается мне нужно отредактировать класс, однако следуя гайдам - править движок нехорошо.
решение заключается в том чтобы расширить класс системы своим классом, на время поменять этот параметр в 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)
конструктор выглядит примерно так
Код |
---|
$obCatalog = new CIBlockCMLImport; |
Код |
---|
$obCatalog = new \MyProjectNameSpace\MySuperImport; |
3. создать файл куда будет стучаться 1с (или вы, руками, через
кто то скажет - такой файл уже есть, это же /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
Код |
---|
elseif($type=="catalog") { $APPLICATION->IncludeComponent("bitrix:catalog.import.1c", "", Array( |
4. в классе MySuperImport сделать оверрайд метода DeactivateElement примерно таким образом:
Код |
---|
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; } } |