Скрипт синхронизации цен из 1С в miniShop2 на MODX Revo

выглядит костыльно, на зато работает очень шустро

Скрипт предназначен для обновления остатков по торговым точкам, ну и заодно цен розничных и в интернет-магазине, из базы 1С. Данные передаются через промежуточный файл .csv.

Скрипт укладывается по времени в 1-2 секунды. То есть остатки можно синхронизировать хоть каждую минуту. К сожалению 1С не может похвастаться таким же быстродействием...

Сам скрипт:

<?php
header('Content-Type: text/html; charset=utf8');
mb_internal_encoding("UTF-8"); // Установка внутренней кодировки скрипта UTF-8
setlocale(LC_ALL, "ru_RU.UTF-8");
if(isset($_GET['DEBUG'])) define('DEBUG', true);
else  define('DEBUG', false);

// Конфиг
$allow_col_num	=	9; // Количество колонок во входном файле
$path	=	dirname(__file__).'/';
$file_input = '/home/domain.ru/www/1c_import.csv'; // Этот файл генерируется скриптом в самой 1C
$file_buffer = 'buffer.csv';
$file_errorlog = 'errors.csv';
$file_refresh['spb'] = 'refresh.spb.dat';
$tablename['spb'] = 'import_temp_spb';
require_once $path.'pdo.config.php';		// Подключение конфига БД
extract($dbconfig);
$prefix = 'modx_'; // Префикс таблиц ".$prefix."

// Инициализация
define('MODX_API_MODE', true); // API MODX
require_once $_SERVER['DOCUMENT_ROOT'].'/index.php'; // MODX
$modx->getService('error','error.modError');
$modx->setLogLevel(modX::LOG_LEVEL_INFO);
$modx->setLogTarget(XPDO_CLI_MODE ? 'ECHO' : 'HTML');
$arr=file($file_input);
$count=0;

// Функции
function logWrite($str, $fh=null)
{
	if(DEBUG) print "log: $str\n";
	// TODO:  Запись в errorlog
}


if(DEBUG) print "
\n";
// ОТКРЫТИЕ buffer.csv
// -------------------------------------------------------\
$fhBuf = fopen($path.$file_buffer, "w");
ftruncate($fhBuf, 0); // очищаем файл до 0 байтов.
$locked = flock($fhBuf, LOCK_EX | LOCK_NB);
if(!$locked) {
    echo 'Не удалось получить блокировку';
    exit(-1);
}

logWrite(date('j-m-Y H:i:s'));
logWrite('Чтение файла 1c_import.csv');

foreach($arr as $str)
{
	$fields=explode(';',$str);
	$num=count($fields);
	if($fields[1]=='Артикул') {logWrite("Строка заголовков удалена"); continue;}
	if($num!=$allow_col_num) {logWrite($str); continue;}
	$count++;
	fwrite($fhBuf, "$str");
}
$output = "Запись в буфер: ".$count." строк к импорту";
logWrite($output);

// ЗАКРЫТИЕ buffer.csv
fflush($fhBuf) or die($php_errormsg);
flock($fhBuf,LOCK_UN) or die($php_errormsg);
fclose($fhBuf) or die($php_errormsg);
unset($fhBuf);
/**/
// ---------------------------------------------------/

// Подключаемся к БД
try {
	$db = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass, array(
		PDO::ATTR_PERSISTENT => true,
		PDO::MYSQL_ATTR_LOCAL_INFILE => true
	));
} catch (PDOException $e) {
    logWrite('Подключение к БД не удалось: '.$e->getMessage());
	exit(13);
}

$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->exec("set names utf8");

// ------------ Импорт buffer.csv -> БД ------------------------
$db->exec("TRUNCATE TABLE `import_temp_raw`;");
$res=$db->exec("LOAD DATA LOCAL
INFILE '".$path."buffer.csv' INTO TABLE `import_temp_raw`
fields terminated by ';'
enclosed by ''
lines terminated by '\n';");
logWrite('Результат импорта в БД: '.$res.' строк внесено');
/**/

//------------- САНКТ-ПЕТЕРБУРГ -----------------------------------------------------------------------\
// Генерируем временную таблицу по Питеру
$sql="CREATE TEMPORARY TABLE IF NOT EXISTS temp_import_spb AS (
SELECT `id`,`article`,`name`,`vendor`,`weight`,
SUBSTRING_INDEX( `supply` , '=', -1 ) AS `quantity`,
SUBSTRING_INDEX( `price` , '=', -1 ) AS `price`,
SUBSTRING_INDEX( `old_price` , '=', -1 ) AS `old_price`
FROM `import_temp_raw`
ORDER BY `article` ASC
)";
$res=$db->exec($sql);
logWrite('Сборка временной таблицы по СПб: '.$res.' строк внесено');

// Составляем список ресурсов с изменениями
$sql="SELECT m.id
FROM `".$prefix."ms2_products` as m, temp_import_spb as t
WHERE m.article=t.article
AND (m.quantity<>t.quantity
OR m.weight<>t.weight
OR m.price<>t.price
OR m.old_price<>t.old_price)
ORDER BY `id` ASC";
$stmt=$db->query($sql);
$stmt->setFetchMode(PDO::FETCH_ASSOC);
$refreshIDs=array();
while($res = $stmt->fetch())
{
	$refreshIDs[$res['id']]='';
}
//print_r($refreshIDs);
logWrite("Изменения обнаружены в: ".count($refreshIDs)." товарах");

// TODO: Сохраняем сериализованный массив ресурсов с изменениями в файл refresh.spb.dat
// А может и не надо...

// Заливаем новые данные в рабочую таблицу ms_products
$sql="UPDATE `".$prefix."ms2_products` as m, temp_import_spb as t, `".$prefix."site_content` as c
SET m.quantity=t.quantity,
m.weight=t.weight,
m.price=t.price,
m.old_price=t.old_price
WHERE m.article=t.article
AND m.id=c.id
AND c.context_key='web'";
$res=$db->exec($sql);
logWrite('Запись новых данных: '.$res.' строк внесено');
/**/
//------------- САНКТ-ПЕТЕРБУРГ  ВЫПОЛНЕНО ---------------------------------------------------------------------/

// Избирательная чистка Кэша
//print_r($refreshIDs);
foreach($refreshIDs as $id => $val)
{
	//$id=79;
	$resource=$modx->getObject('modResource',$id);
	$cacheKey = $resource->getCacheKey();
	$modx->cacheManager->refresh(array(
		'resource' => array('key' => $cacheKey),
	));
}

// Финиш
logWrite('затраченное время: '.(microtime(true) - $modx->startTime));
logWrite('');
if(DEBUG) print "
";

в скрипте подключается файл с доступами к БД pdo.config.php вида:

$dbconfig[dbhost]	= 'localhost';
$dbconfig[dbuser]	= 'ваш_логин';
$dbconfig[dbpass]	= 'ваш_пароль';
$dbconfig[dbname]	= 'имя_базы';

Cтруктура временной таблицы:

Результат выходит следующий:
log: 28-03-2014 14:01:34
log: Чтение файла 1c_import.csv
log: Строка заголовков удалена
log: Запись в буфер: 755 строк к импорту
log: Результат импорта в БД: 755 строк внесено
log: Сборка временной таблицы по СПб: 755 строк внесено
log: Изменения обнаружены в: 1 товарах
log: Запись новых данных: 0 строк внесено
log: затраченное время: 0.68212199211121
log: