Нет прав писать в одноименную тему [URL=https://dev.1c-bitrix.ru/support/forum/forum26/topic72154/]https://dev.1c-bitrix.ru/support/forum/forum26/topic72154/[/URL] поэтому напишу здесь. Да и моя ситуация касается ручной загрузки, хотя думаю, что в прямой загрузке из 1С будет что-то подобное.
Столкнулся с той же ситуацией - не удаляются старые товары, которых нет в выгрузке на сайт.
У нас выгрузка из 1С по ряду причин делается через самописный обмен. Он еще не доделан до конца и выгрузка выполняется в файлы, которые надо вручную импортировать через админку (импорт XML).
При этом в отдельный файл выгружается справочник. Он загружается нормально, с удалением отсутствующих записей, а товары и цены - нет.
Решил попробовать разобраться. За точку старта взял 24 сообщение в той ветке в котором написано место, где непосредственно происходит косяк. Процитирую кусок сообщения:
[QUOTE]суть косяка "почему не удаляются отсутствующие товары" в том что на шаге "чистки" инфоблока (7 или 8 ) происходит ранний выход из метода класса, который ответственный за это.
деактивация (или удаление) происходит в методе CIBlockCMLImport::DeactivateElement , сам класс лежит в /bitrix/modules/iblock/classes/general/cml2.php
ранний выход происходит потому что дойдя до первого же return-условия оно оказывается "true"[TABLE][TR][TH]Код[/TH][/TR][TR][TD]if(array_key_exists("bUpdateOnly", $this->next_step) && $this->next_step["bUpdateOnly"])
return $counter;[/TD][/TR][/TABLE][/QUOTE]
Оказалось, что bUpdateOnly всегда установлен в true, т.к. в свойство записано строковое значение, а не булево. А оно всегда true, когда заполнено, даже если там указано "false".
Строковым же оно получается, т.к., как я понял, для выполнения каждого шага импорта страница, его делающая циклически вызывает саму себя, передавая параметры через $_POST. А через него передаются только строки.
Как избавиться от ошибки.
Два варианта.
1. Если у вас самописная выгрузка, то можно поправить тег XML
<Каталог СодержитТолькоИзменения="false">
убрав из него "СодержитТолькоИзменения="false"", т.е. оставить только <Каталог>
В этом случае свойство bUpdateOnly создаваться не будет и условие станет ложным по первой части.
2. Исправить ошибку в коде.
Редактируем файл папка_сайта/bitrix/modules/iblock/admin/iblock_xml_import.php. Это та самая страница импорта.
Находим в начале файла блок кода, в котором как раз преобразовываются типы значений свойств
[CODE]//Initialize NS variable which will save step data
if(array_key_exists("NS", $_POST) && is_array($_POST["NS"]))
{
$NS = $_POST["NS"];
if(array_key_exists("charset", $NS) && $NS["charset"] === "false") $NS["charset"] = false;
if(array_key_exists("PREVIEW", $NS) && $NS["PREVIEW"] === "false") $NS["PREVIEW"] = false;
if(array_key_exists("bOffer", $NS) && $NS["bOffer"] === "false") $NS["bOffer"] = false;
}
[/CODE]
И добавляем в него еще одну строку:
[CODE]//Initialize NS variable which will save step data
if(array_key_exists("NS", $_POST) && is_array($_POST["NS"]))
{
$NS = $_POST["NS"];
if(array_key_exists("charset", $NS) && $NS["charset"] === "false") $NS["charset"] = false;
if(array_key_exists("PREVIEW", $NS) && $NS["PREVIEW"] === "false") $NS["PREVIEW"] = false;
if(array_key_exists("bOffer", $NS) && $NS["bOffer"] === "false") $NS["bOffer"] = false;
if(array_key_exists("bUpdateOnly", $NS) && $NS["bUpdateOnly"] === "false") $NS["bUpdateOnly"] = false;
}
[/CODE]
После этого начинает нормально отрабатываться вторая часть условия.
Столкнулся с той же ситуацией - не удаляются старые товары, которых нет в выгрузке на сайт.
У нас выгрузка из 1С по ряду причин делается через самописный обмен. Он еще не доделан до конца и выгрузка выполняется в файлы, которые надо вручную импортировать через админку (импорт XML).
При этом в отдельный файл выгружается справочник. Он загружается нормально, с удалением отсутствующих записей, а товары и цены - нет.
Решил попробовать разобраться. За точку старта взял 24 сообщение в той ветке в котором написано место, где непосредственно происходит косяк. Процитирую кусок сообщения:
[QUOTE]суть косяка "почему не удаляются отсутствующие товары" в том что на шаге "чистки" инфоблока (7 или 8 ) происходит ранний выход из метода класса, который ответственный за это.
деактивация (или удаление) происходит в методе CIBlockCMLImport::DeactivateElement , сам класс лежит в /bitrix/modules/iblock/classes/general/cml2.php
ранний выход происходит потому что дойдя до первого же return-условия оно оказывается "true"[TABLE][TR][TH]Код[/TH][/TR][TR][TD]if(array_key_exists("bUpdateOnly", $this->next_step) && $this->next_step["bUpdateOnly"])
return $counter;[/TD][/TR][/TABLE][/QUOTE]
Оказалось, что bUpdateOnly всегда установлен в true, т.к. в свойство записано строковое значение, а не булево. А оно всегда true, когда заполнено, даже если там указано "false".
Строковым же оно получается, т.к., как я понял, для выполнения каждого шага импорта страница, его делающая циклически вызывает саму себя, передавая параметры через $_POST. А через него передаются только строки.
Как избавиться от ошибки.
Два варианта.
1. Если у вас самописная выгрузка, то можно поправить тег XML
<Каталог СодержитТолькоИзменения="false">
убрав из него "СодержитТолькоИзменения="false"", т.е. оставить только <Каталог>
В этом случае свойство bUpdateOnly создаваться не будет и условие станет ложным по первой части.
2. Исправить ошибку в коде.
Редактируем файл папка_сайта/bitrix/modules/iblock/admin/iblock_xml_import.php. Это та самая страница импорта.
Находим в начале файла блок кода, в котором как раз преобразовываются типы значений свойств
[CODE]//Initialize NS variable which will save step data
if(array_key_exists("NS", $_POST) && is_array($_POST["NS"]))
{
$NS = $_POST["NS"];
if(array_key_exists("charset", $NS) && $NS["charset"] === "false") $NS["charset"] = false;
if(array_key_exists("PREVIEW", $NS) && $NS["PREVIEW"] === "false") $NS["PREVIEW"] = false;
if(array_key_exists("bOffer", $NS) && $NS["bOffer"] === "false") $NS["bOffer"] = false;
}
[/CODE]
И добавляем в него еще одну строку:
[CODE]//Initialize NS variable which will save step data
if(array_key_exists("NS", $_POST) && is_array($_POST["NS"]))
{
$NS = $_POST["NS"];
if(array_key_exists("charset", $NS) && $NS["charset"] === "false") $NS["charset"] = false;
if(array_key_exists("PREVIEW", $NS) && $NS["PREVIEW"] === "false") $NS["PREVIEW"] = false;
if(array_key_exists("bOffer", $NS) && $NS["bOffer"] === "false") $NS["bOffer"] = false;
if(array_key_exists("bUpdateOnly", $NS) && $NS["bUpdateOnly"] === "false") $NS["bUpdateOnly"] = false;
}
[/CODE]
После этого начинает нормально отрабатываться вторая часть условия.