В данной статье речь пойдет про автоматическое обновление данных и про cron, но главное – как это реализовать в 1С-Битрикс.
Как автоматизировать выгрузку данных в Битриксе
Все наши выгрузки лежат по адресу Администрирование – Магазин – Настройки – Экспорт данных. Мы уже затрагивали этот раздел в статье Выгрузка товаров в Яндекс Маркет. Я не буду рассказывать вам, как создавать свои профили, рассмотрим ситуацию, когда у вас уже настроены профили и вы вручную выгружаете товары, постоянно кликая на пункт меню Экспортировать.
Для начала привяжем к cron`у наш профиль:
После этого у вас появиться папка с файлом
/bitrix/crontab/crontab.cfg
А также, файл
/bitrix/php_interface/include/catalog_export/cron_frame.php
Что важно учесть в этом файле:
На самой первой строке мы видим путь к php, в моем случае это
#!/usr/bin/php -q
Далее, мы указываем путь к корню сайта, в моем случае это
/var/www/admin/data/www/site.ru
После этого, обязательно укажите переменную $siteID
$siteID = 's1';
Но и на этом еще не всё 🙂 . Нужно указать ID профиля экспорта, этот ID можно глянуть на странице в админке:
/bitrix/admin/cat_export_setup.php?lang=ru
Указываем нашу переменную с ID:
$profile_id = 20;
И в итоге получаем файл cron_frame.php со следующим содержимым:
#!/usr/bin/php -q <?php $_SERVER["DOCUMENT_ROOT"] = "/var/www/admin/data/www/site.ru"; $DOCUMENT_ROOT = $_SERVER["DOCUMENT_ROOT"]; $siteID = 's1'; // your site ID - need for language ID define("NO_KEEP_STATISTIC", true); define("NOT_CHECK_PERMISSIONS",true); define("BX_CAT_CRON", true); define('NO_AGENT_CHECK', true); if (preg_match('/^[a-z0-9_]{2}$/i', $siteID) === 1) { define('SITE_ID', $siteID); } else { die('No defined site - $siteID'); } require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php"); if (!defined('LANGUAGE_ID') || preg_match('/^[a-z]{2}$/i', LANGUAGE_ID) !== 1) die('Language id is absent - defined site is bad'); set_time_limit (0); if (CModule::IncludeModule("catalog")) { $profile_id = 9; //PROFILE ID if (isset($argv[1])) $profile_id = (int)$argv[1]; if ($profile_id<=0) die('No profile id'); $ar_profile = CCatalogExport::GetByID($profile_id); if (!$ar_profile) die(); $strFile = CATALOG_PATH2EXPORTS.$ar_profile["FILE_NAME"]."_run.php"; if (!file_exists($_SERVER["DOCUMENT_ROOT"].$strFile)) { $strFile = CATALOG_PATH2EXPORTS_DEF.$ar_profile["FILE_NAME"]."_run.php"; if (!file_exists($_SERVER["DOCUMENT_ROOT"].$strFile)) { die(); } } $arSetupVars = array(); $intSetupVarsCount = 0; if ($ar_profile["DEFAULT_PROFILE"] != 'Y') { parse_str($ar_profile["SETUP_VARS"], $arSetupVars); if (!empty($arSetupVars) && is_array($arSetupVars)) { $intSetupVarsCount = extract($arSetupVars, EXTR_SKIP); } } global $arCatalogAvailProdFields; $arCatalogAvailProdFields = CCatalogCSVSettings::getSettingsFields(CCatalogCSVSettings::FIELDS_ELEMENT); global $arCatalogAvailPriceFields; $arCatalogAvailPriceFields = CCatalogCSVSettings::getSettingsFields(CCatalogCSVSettings::FIELDS_CATALOG); global $arCatalogAvailValueFields; $arCatalogAvailValueFields = CCatalogCSVSettings::getSettingsFields(CCatalogCSVSettings::FIELDS_PRICE); global $arCatalogAvailQuantityFields; $arCatalogAvailQuantityFields = CCatalogCSVSettings::getSettingsFields(CCatalogCSVSettings::FIELDS_PRICE_EXT); global $arCatalogAvailGroupFields; $arCatalogAvailGroupFields = CCatalogCSVSettings::getSettingsFields(CCatalogCSVSettings::FIELDS_SECTION); global $defCatalogAvailProdFields; $defCatalogAvailProdFields = CCatalogCSVSettings::getDefaultSettings(CCatalogCSVSettings::FIELDS_ELEMENT); global $defCatalogAvailPriceFields; $defCatalogAvailPriceFields = CCatalogCSVSettings::getDefaultSettings(CCatalogCSVSettings::FIELDS_CATALOG); global $defCatalogAvailValueFields; $defCatalogAvailValueFields = CCatalogCSVSettings::getDefaultSettings(CCatalogCSVSettings::FIELDS_PRICE); global $defCatalogAvailQuantityFields; $defCatalogAvailQuantityFields = CCatalogCSVSettings::getDefaultSettings(CCatalogCSVSettings::FIELDS_PRICE_EXT); global $defCatalogAvailGroupFields; $defCatalogAvailGroupFields = CCatalogCSVSettings::getDefaultSettings(CCatalogCSVSettings::FIELDS_SECTION); global $defCatalogAvailCurrencies; $defCatalogAvailCurrencies = CCatalogCSVSettings::getDefaultSettings(CCatalogCSVSettings::FIELDS_CURRENCY); CCatalogDiscountSave::Disable(); include($_SERVER["DOCUMENT_ROOT"].$strFile); CCatalogDiscountSave::Enable(); CCatalogExport::Update($profile_id, array( "=LAST_USE" => $DB->GetNowFunction() ) ); }
Как автоматически запускать все выгрузки в 1С-Битрикс
Раньше я думал, что запустив цикл, мы решим нашу проблему. Но, потом выяснилось, что решение немного другое. Пообщавшись с тех. поддержкой выяснилось – штатно запускается только 1 ID профиля. Поэтому вывод – мы либо передаем ID в самой строке через крон, либо вешаем запуск файлов, которые являются копией файла cron_frame.php.
Что меняется в самих копиях? Я создал несколько копий файла cron_frame.php (назвал их cron_frame_9.php и т.д.), а в самих файлах поменял только ID. При этом создал необходимое количество заданий в самом cron.
Важно! Как узнать что все работает? В админке у вас может писать что все ваши выгрузки обновились, и вы наивно в это поверите 🙂 . Но, показателем будет именно дата изменения файлов, которые расположены в папке /bitrix/catalog_export/
Конечно, это более долгий способ, и можно просто передавать ID в самом запросе. Чтобы запускать несколько профилей экспорта, нужно выполнить команды:
/usr/bin/php /var/www/admin/data/www/site.ru/bitrix/php_interface/include/catalog_export/cron_frame.php > 1 /usr/bin/php /var/www/admin/data/www/site.ru/bitrix/php_interface/include/catalog_export/cron_frame.php > 2 /usr/bin/php /var/www/admin/data/www/site.ru/bitrix/php_interface/include/catalog_export/cron_frame.php > 3
где 1,2,3 – это id профиля экспорта.
Не забудьте поменять значение переменной profile ID в файле крон_фрейм.пхп, если вы выбрали этот вариант, без создания лишних копий этого файла:
$profile_id = $argv[1];
$argv — Массив переданных скрипту аргументов.
Последнее, но не менее важное – как настроить cron на хостинге?
В админ панели вашего хостинга, вам нужно зайти в Планировщик (cron) нажать кнопку Создать и прописать в поле Команда:
/usr/bin/php /var/www/admin/data/www/site.ru/bitrix/php_interface/include/catalog_export/cron_frame.php
А в поле Период задать интервал времени, через который скрипт будет запускаться:
Тут особых рекомендаций не будет, себе я выставил каждые 12 часов, а вы уже выставляйте сколько необходимо.
экспорт делается через CATALOG_PATH2EXPORTS
как в этом случае можно программно изменить название товара?
(нужно сделать некие манипуляции, сформировать название из параметров)
я бы вам советовал копать в сторону событий http://dev.1c-bitrix.ru/api_help/iblock/events/onbeforeiblockelementupdate.php или http://dev.1c-bitrix.ru/api_help/iblock/events/onafteriblockelementupdate.php
которые записываются в файле /bitrix/php_interface/init.php – настоятельно рекомендую править этот файл не через сайт а через FTP, т.к. если вы совершите ошибку в коде это сломает весь сайт
Тех поддержка посоветовала так:
Можно кастомизировать скрипт экспорта, чтобы в нём написать код обработки названия.
Для этого нужно скопировать файлы /bitrix/modules/catalog/load_export/csv_new_run.php и /bitrix/modules/catalog/load_export/csv_new_setup.php, переименовать их, например, в csv_new_custom_run.php и csv_new_custom_setup.php, и переместить в папку /bitrix/php_interface/include/catalog_export/.
В итоге в административной части сайта у вас появится дополнительный профиль импорта csv и он не будет перетираться обновлениями.
Вносить правки нужно в файл /bitrix/php_interface/include/catalog_export/csv_new_custom_run.php
Но было бы здорово если вы это показали по шагам, в следующем уроке
/usr/bin/wget -O /dev/null http://site.ru/scripts/activate.php
еще один вариант записи в кроне
Большое спасибо за статью! Особенно про пункт “Нужно указать ID профиля экспорта”. Только у Вас об этом прочитала и всё заработало
Спасибо за комментарий 🙂 Рад, что статья пригодилась)
Что делать если при попытке запустить выгрузку, получаю сообщение:
“Cannot load Zend OPcache – it was already loaded” ???
Что это означает?
Судя по описанию, ошибка больше серверная. Если вы не используете OPcache в своем коде, попробуйте обратится к тех. поддержке вашего хостинга.