Битрикс экспорт данных – автоматическое обновление через cron

В данной статье речь пойдет про автоматическое обновление данных и про 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 часов, а вы уже выставляйте сколько необходимо.

автор: Dmitriy

З 2011 року займаюся веб-розробкою. Зараз я – PHP Full Stack Developer.
Обговорити ваш проект, а також дізнатися більше про мене ви можете на цьому сайті:
dev.forwww.com

Email: dmitriyribka@gmail.com

8 коментаря

  1. экспорт делается через CATALOG_PATH2EXPORTS
    как в этом случае можно программно изменить название товара?
    (нужно сделать некие манипуляции, сформировать название из параметров)

    1. я бы вам советовал копать в сторону событий 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, т.к. если вы совершите ошибку в коде это сломает весь сайт

  2. Тех поддержка посоветовала так:

    Можно кастомизировать скрипт экспорта, чтобы в нём написать код обработки названия.

    Для этого нужно скопировать файлы /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

    Но было бы здорово если вы это показали по шагам, в следующем уроке

  3. Большое спасибо за статью! Особенно про пункт “Нужно указать ID профиля экспорта”. Только у Вас об этом прочитала и всё заработало

    1. Судя по описанию, ошибка больше серверная. Если вы не используете OPcache в своем коде, попробуйте обратится к тех. поддержке вашего хостинга.

Залишити коментар до Евгения Скасувати коментар