Технология обновления типовых конфигураций с изменениями




Принцип обмена данными из 1С с сайтом (на MySQL) и выдачи (публикации) этих данных по запросу.
PHP-Скрипт автоматической загрузки данных из файла данных в формате CSV в базу данных сайта работающего на WordPress.

В продолжение моей темы: 1С:Альфа-Авто Автосалон Автосервис: обмен с сайтом.
С помощью данного скрипта можно загружать в автоматическом режиме, по расписанию, данные сервисных книжек (ремонтов авто) из 1С:Альфа-Авто Автосалон Автосервис.
Также можно загружать данные в ручном режиме: для этого делается скрытая страница, где размещается специальная кнопка.
Комментарии размещенные внутри скрипта разъяснят логику и порядок действия.
Комментарии с "/////    echo" использовались для отладки.
Дополнительно создана таблица для журналирования результатов загрузки данных.
Скрипт включает в себя защиту от SQL инъекций (думаю безопасность соблюдена в полной мере).
В кратце:
1. Пишется скрипт, который запускает этот.
2. Создается регламентное задание в WordPress, по которому запускается скрипт из п.1. 
3. Этот скрипт осуществляет проверку на существование файла обмена в папке.
4. Если данные не новые, загрузка не производится.
5. Если данные новые, очищается таблица сервисных книжек.
6. Загружаются новые данные.

Собственно сам скрипт:

<?php // Полная загрузка сервисных книжек, создан 2026-01-05 12:44:55

global $wpdb2;
global $failure;
global $file_hist;

/////  echo '<H2><b>Старт загрузки</b></H2><br>';

$failure=FALSE;
//подключаемся к базе
$wpdb2 = include_once 'connection.php'; ; // подключаемся к MySQL
// если не удалось подключиться, и нужно оборвать PHP с сообщением об этой ошибке
if (!empty($wpdb2->error))
{
/////   echo '<H2><b>Ошибка подключения к БД, завершение.</b></H2><br>';
$failure=TRUE;
wp_die( $wpdb2->error );
}

$m_size_file=0;
$m_mtime_file=0;
$m_comment='';
/////проверка существования файлов выгрузки из 1С
////файл выгрузки сервисных книжек
$file_hist = ABSPATH.'/_1c_alfa_exchange/AA_hist.csv';
if (!file_exists($file_hist))
{
/////   echo '<H2><b>Файл обмена с сервисными книжками не существует.</b></H2><br>';
$m_comment='Файл обмена с сервисными книжками не существует';
$failure=TRUE;
}

/////инициируем таблицу лога
/////если не существует файла то возврат и ничего не делаем
if ($failure){
///включает защиту от SQL инъекций и данные можно передавать как есть, например: $_GET['foo']
/////   echo '<H2><b>Попытка вставить запись в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>$m_comment));
wp_die();
/////    echo '<H2><b>Возврат в начало.</b></H2><br>';
return $failure;
}
/////проверка лога загрузки, что бы не загружать тоже самое
$masiv_data_file=stat($file_hist);   ////передаем в массив свойство файла
$m_size_file=$masiv_data_file[7];    ////получаем размер файла
$m_mtime_file=$masiv_data_file[9];   ////получаем дату модификации файла
////создаем запрос на получение последней удачной загрузки
////выбираем по штампу времени создания (редактирования) файла загрузки AA_hist.csv, $m_mtime_file

/////   echo '<H2><b>Размер файла: '.$m_size_file.'</b></H2><br>';
/////   echo '<H2><b>Штамп времени файла: '.$m_mtime_file.'</b></H2><br>';
/////   echo '<H2><b>Формирование запроса на выборку из лога</b></H2><br>';
////препарируем запрос
$text_zaprosa=$wpdb2->prepare("SELECT * FROM `vin_logs` WHERE `last_mtime_upload` = %s", $m_mtime_file);
$results=$wpdb2->get_results($text_zaprosa);

if ($results)
{   foreach ( $results as $r)
{
////если штамп времени и размер файла совпадают, возврат
if (($r->last_mtime_upload==$m_mtime_file) && ($r->last_size_upload==$m_size_file))
{////echo '<H2><b>Возврат в начало, т.к. найдена запись в логе.</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>'Загрузка отменена, новых данных нет, т.к. найдена запись в логе.'));
wp_die();
return $failure;
}
}
}
////если данные новые, пишем в лог запись о начале загрузки
/////echo '<H2><b>Попытка вставить запись о начале загрузки в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>0, 'last_size_upload'=>$m_size_file, 'comment'=>'Начало загрузки'));

////очищаем таблицу
$clear_tbl_zap=$wpdb2->prepare("TRUNCATE TABLE %s", 'vin_history');
$clear_tbl_zap_repl=str_replace("'","`",$clear_tbl_zap);
$results=$wpdb2->query($clear_tbl_zap_repl);
/////   echo '<H2><b>Очистка таблицы сервисных книжек</b></H2><br>';
if (empty($results))
{
/////   echo '<H2><b>Ошибка очистки таблицы книжек, завершение.</b></H2><br>';
//// если очистка не удалась, возврат
$failure=TRUE;
wp_die();
return $failure;
}

////загружаем данные
$table='vin_history';         // Имя таблицы для импорта
//$file_hist Имя CSV файла, откуда берется информация     // (путь от корня web-сервера)
$delim=';';          // Разделитель полей в CSV файле
$enclosed='"';      // Кавычки для содержимого полей
$escaped='\

14 Comments

  1. pumbaE

    0. Сделать копию.

    Reply
  2. w-divin

    Хорошо описано. Плюс. Мне кажется стоило бы добавить, что в процессе обновления стоит пересмотреть все изменения в модулях и по возможности максимально вынести их в сторонние обработчики (подписки на события, общие модули обработки объектов), чтобы облегчить себе и другим дальнейшую поддержку…

    Reply
  3. maldinitaly

    Спасибо, все хорошо написано. Никогда не хватало времени все это описать по пунктам.Автору плюс.

    Reply
  4. Sykoku

    У меня несколько иной подход.

    1. Существует база «Пустышка». Это копия рабочей базы со всеми необходимыми изменениями, но без данных.

    2. Создается «Копия» текущей базы.

    3. Обновляется «Пустышка». Обновление происходит по возможности с объединением с приоритетом загружаемой, т.к. существуют документы, модули, обработки, разделы меню и т.д., для которых уже установлены Права и Роли. Раздавать их заново долго и неправильно.

    4. Происходит экспорт конфигурации «Пустышки» в файл.

    5. Сравнивается конфигурация «Копии» с «Пустышкой». Здесь основная работа: поиск отличий и внесение этих отличий в «Пустышку». Для удобства работы каждое изменение кода помечено маркерами начала и конца. В первую очередь поиск идет по маркерам.

    6. По окончании всех работ еще раз экспорт конфигурации «Пустышки».

    7. Объединение рабочей конфигурации с «Пустышкой».

    Все телодвижения занимают часа 2 для УТП 1.2.

    В последний раз был глюк при обновлении до релиза 20.08 — 1С наконец-то включила поддержку драйверов от Арт-Софт (3 года упорно доказывали, что это не их глюк, а виноват поставщик драйверов, касса или инсталятор) и при запуске отвалилась касса. Проблема решилась еще за полчаса.

    Reply
  5. andr_andrey

    (4) Sykoku,

    «7. Объединение рабочей конфигурации с «Пустышкой». »

    А как потом обновляете конфигурацию поставщика?

    Reply
  6. EvilDoc

    (5) а зачем? просто хранить типовую актуального релиза. я сравниваю свою конфу с такой же типовой, сравниваю 2 типовых и сравниваю текущую с типовой на которую нужно обновить. Все в разных базах. Благо 2 моника

    Reply
  7. andr_andrey

    (6) EvilDoc,

    просто так легко «потерять» конфигурацию поставщика. Пустышку надо бэкапить (хранить как зеницу ока), помнить и передавать любому новому 1Снику, а если конфигурация поставщика в рабочей базе есть, то ежедневно бэкапится all-in-one.

    Рекомендую задавать себе вопрос «Если меня не станет завтра, как будет «жить» решение». Если возможны нюансы, надо сделать более просто и лаконично.

    Reply
  8. EvilDoc

    (7) Да, типовую конфу текущей версии приходится хранить. Ну а если она потеряется или новый сотрудник ее не найдет — всегда можно скачать релиз и обновить до текущей версии. Да долго, ну а чего делать. Но пока-что продлем не было — и мне передали все и я храню все. И соответственно передам

    Reply
  9. PLAstic

    Пункт 3 убрать из текста вообще. При фильтре из п.2 мы итак видим объекты, изменëнные по отношению к конфигурации поставщика, но не все (как если бы сравнивать конфигурацию поставщика и основную через пункт меню «Сравнение конфигураций»), а только те, что меняются в новой конфигурации поставщика. Именно этот фильтр позволяет провести оценку «что менялось мной и что изменено авторами».

    Reply
  10. alanto23

    Статья неплохая. Только не полная. Не освещен, на мой взгляд очень важный, последний шаг — когда делаем «Объединение объекта с приоритетом основной» в код модулей добавляются фрагменты изменений. По умолчанию они закомменчены и выделены символами {{MRG[ < — > ] или {{MRG[ < — ] или {{MRG[ — > ]. Стрелка указывает какая конфигурация была изменена. Основная, поставщика или обе. Такие символы ставятся в начале и конце измененного блока.

    И вот последний шаг: Открываем конфу в конфигураторе, делаем глобальный поиск по символам: {{MRG[ и анализируя изменения, принимаем решение — поменять блок кода или оставить все как есть.

    Если выбираем пункт «Объединение объекта с приоритетом поставщика» — смысл тот же, только комментариями становятся измененные блоки кода основной конфигурации. А изменения от поставщика вставляются в рабочем состоянии.

    И нужно не забывать удалять этот отработанный мусор. Иначе, если пару тройку раз обновиться с «Объединением» — потом в модулях сам чёрт ногу поломает! 🙂

    Reply
  11. Trinitron

    спасибо большое за статью, как начинающему, было очень полезно прочитать, возьму на заметку данную статью

    Reply
  12. 4ur

    все правильно, только как бороться с внедренцами, которые не придерживаются никаких требований при внесении изменений в конфигурацию. К сожалению таких достаточно много, и хотят они таким образом максимально привязать клиента к себе. У нас просто внедряют УПП, внедренцев выбирал фин. дир., никто с ИТ не советовался, вот теперь приходиться за ними, как мусорщики, с совком и веником, все подчищать…

    Reply
  13. 4ur

    На сайте http://www.gilev.ru/author/admin/ есть рекомендация — отключать режим совместимости с 8.2.13 для повышения производительности базы на SQL, никто не может подсказать, как при таком отключении будет проходить обновление конфигурации?

    Reply
  14. zqzq

    (10) alanto23, более удобно попроцедурно настраивать режим объединения модулей (справа от модулей через лупу), часто нетиповые и типовые изменения в разных процедурах и достаточно расставить режимы объединения, тогда и постобработка не нужна.

    Очередная статья, которая на эту неочевидную для новичков фишку не обратила внимания. Кстати, в 8.3 обещают kdiff прикрутить и сразу редактировать объединение.

    Также была статья, затерявшаяся на просторах инфостарта. Там почерпнул полезную контрольную проверку — выгрузить в текст полное описание изменений Поставщик-Основная до обновления и после. Далее эти 2 файла сравнить (через kdiff, штатный не очень). Сразу все косяки обновления обнаружатся + кое-что полезное.

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *