[QUOTE]Алексей Огурцов написал:
А у меня не удаляются товары, которых нет в файле импорта через xml, что только не пробовал - результат нулевой[/QUOTE]
вот решение но на свой страх и риск.
у меня инфоблок использовался в качестве "буфера" а не сразу "боевого" инфоблока, основная логика импорта была в обработчике после выгрузки который переносил данные из буфера в боевой с нужной структурой.
т.к. времени на "научный тык" не особо есть - решил по другому, "в лоб".
дальше рассказываю конкретно про свой случай
------------
суть косяка "почему не удаляются отсутствующие товары" в том что на шаге "чистки" инфоблока (7 или 8 ) происходит ранний выход из метода класса, который ответственный за это.
деактивация (или удаление) происходит в методе [B]CIBlockCMLImport::DeactivateElement[/B] , сам класс лежит в /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. [B]создать свой класс который расширяет \CIBlockCMLImport. [/B]
где и как он будет лежать физически - неважно. главное - файл должен быть подключен заранее до того как начнет работу компонент, в котором будут создаваться объекты этого класса (напрямую require в начале component.php или заранее через init.php > vendor/autoload.php как у нормальных людей)
[B]пусть будет класс такой \MyProjectNameSpace\MySuperImport[/B]
2. [B]скопировать bitrix:catalog.import.1c в свое пространство имен[/B] (например [B]myproject:catalog.import.1c[/B])
2.1. [B]заменить [/B]все (на всякий случай)[B] конструкторы CIBlockCMLImport на конструкторы своего класса \MyProjectNameSpace\MySuperImport в своем cкопированном компоненте myproject:catalog.import.1c (component.php)[/B]
конструктор выглядит примерно так[CODE]$obCatalog = new CIBlockCMLImport;[/CODE]и станет [CODE]$obCatalog = new \MyProjectNameSpace\MySuperImport;[/CODE]
3. [B]создать файл куда будет стучаться 1с[/B] (или вы, руками, через [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 по факту в файле есть всего лишь подключение другого скрипта, т.е. "делегирование" всей логики другому файлу.
однако для того чтобы не делать такую же чушь - надо [B]скопировать в файл контент "делегированного" файла [/B][B]"/bitrix/modules/sale/admin/1c_exchange.php"[/B], и просто [B]заменить [/B][B]вызов [/B]в ветке
$type=='catalog' [B]вместо bitrix:catalog.import.1c на свой myproject:catalog.import.1c[/B]. примерно на строке 66[CODE]elseif($type=="catalog")
{
$APPLICATION->IncludeComponent("bitrix:catalog.import.1c", "", Array([/CODE]тогда обработка выгрузки каталога будет совершаться своим компонентом из п2
4. [B]в классе MySuperImport [/B][B]сделать оверрайд метода DeactivateElement[/B] примерно таким образом:
[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. [B]не забыть о подключении класса \MyProjectNameSpace\MySuperImport [/B][B]до начала работы компонента
[/B]
А у меня не удаляются товары, которых нет в файле импорта через xml, что только не пробовал - результат нулевой[/QUOTE]
вот решение но на свой страх и риск.
у меня инфоблок использовался в качестве "буфера" а не сразу "боевого" инфоблока, основная логика импорта была в обработчике после выгрузки который переносил данные из буфера в боевой с нужной структурой.
т.к. времени на "научный тык" не особо есть - решил по другому, "в лоб".
дальше рассказываю конкретно про свой случай
------------
суть косяка "почему не удаляются отсутствующие товары" в том что на шаге "чистки" инфоблока (7 или 8 ) происходит ранний выход из метода класса, который ответственный за это.
деактивация (или удаление) происходит в методе [B]CIBlockCMLImport::DeactivateElement[/B] , сам класс лежит в /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. [B]создать свой класс который расширяет \CIBlockCMLImport. [/B]
где и как он будет лежать физически - неважно. главное - файл должен быть подключен заранее до того как начнет работу компонент, в котором будут создаваться объекты этого класса (напрямую require в начале component.php или заранее через init.php > vendor/autoload.php как у нормальных людей)
[B]пусть будет класс такой \MyProjectNameSpace\MySuperImport[/B]
2. [B]скопировать bitrix:catalog.import.1c в свое пространство имен[/B] (например [B]myproject:catalog.import.1c[/B])
2.1. [B]заменить [/B]все (на всякий случай)[B] конструкторы CIBlockCMLImport на конструкторы своего класса \MyProjectNameSpace\MySuperImport в своем cкопированном компоненте myproject:catalog.import.1c (component.php)[/B]
конструктор выглядит примерно так[CODE]$obCatalog = new CIBlockCMLImport;[/CODE]и станет [CODE]$obCatalog = new \MyProjectNameSpace\MySuperImport;[/CODE]
3. [B]создать файл куда будет стучаться 1с[/B] (или вы, руками, через [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 по факту в файле есть всего лишь подключение другого скрипта, т.е. "делегирование" всей логики другому файлу.
однако для того чтобы не делать такую же чушь - надо [B]скопировать в файл контент "делегированного" файла [/B][B]"/bitrix/modules/sale/admin/1c_exchange.php"[/B], и просто [B]заменить [/B][B]вызов [/B]в ветке
$type=='catalog' [B]вместо bitrix:catalog.import.1c на свой myproject:catalog.import.1c[/B]. примерно на строке 66[CODE]elseif($type=="catalog")
{
$APPLICATION->IncludeComponent("bitrix:catalog.import.1c", "", Array([/CODE]тогда обработка выгрузки каталога будет совершаться своим компонентом из п2
4. [B]в классе MySuperImport [/B][B]сделать оверрайд метода DeactivateElement[/B] примерно таким образом:
[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. [B]не забыть о подключении класса \MyProjectNameSpace\MySuperImport [/B][B]до начала работы компонента
[/B]