К вопросу о регламентном задании – восстановлении последовательности




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

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

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

<?php // Полная загрузка сервисных книжек, создан 2024-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='\

8 Comments

  1. Поручик

    я дeлaл пoдoбнoe для пapтионного учёта, нo c иcпoльзoвaниeм штaтныx пpoцeдуp УТ. лoг y мeня пишeтcя в жypнaл peгиcтpaции. выкладывать не стал, но если есть интерес.

    Reply
  2. artbear

    (0) Лучше оформить в виде отдельного класса-обработки, в которой решать проблемы по выводу информации и т.п.

    Например. вместо

    Док.ДобавитьСтроку(Сообщение)

    намного лучше будет смотреться вызов спец.метода

    ВывестиСообщение(Сообщение)

    В случае использования подобных промежуточных методов появляется различные возможности — можно инкапсулировать работу клиента и сервера, т.к. часто подобные обработки приходится вызывать и от имени клиента для проверки, анализа и т.п.

    У меня в подобных задачах юзается следующий интерфейс, т.е. методы типа

    Инит

    Сброс

    ВывестиСообщение

    ВывестиСостояние

    ОсновнаяОбработка (или типа ВыполнитьВыгрузку_КокаКола, ВыполнитьВыгрузку_Мултон, ВыполнитьВыгрузку_Сладко, ВыполнитьВыгрузку_Лебедянь, Балтика и т.д. )

    ПолучитьТекстЛог

    Reply
  3. Dimasik2007

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

    (1) Чем больше информации в открытом доступе, тем лучше. Сам я начинал с сборника ЕСИС, т.к. с работы доступ к интернету был очень ограничен. 🙂

    Reply
  4. Поручик

    (3) Кстати, код процедуры лучше разукрась. Разукрашка для инфостарта здесь валяется.

    Reply
  5. Dimasik2007

    (4) Да я бы разукрасил, тем более что саму «разукрашку» нашел. Но! Скачать не могу, лимит исчерпан :))) Так что завтра наверное 🙂

    Reply
  6. artbear

    (3) Даже для начинающих разработчиков пример слишком уж упрощен 🙁

    1. Сохранение данных в файл не лучший вариант.

    а) В случае нескольких выполнений предыдущее содержание файла удалится.

    б) У пользователя Винды, от чьего имени запускается и работает клиент-сервер, просто может не быть прав на каталог C: (при обычной установке 1С без доп.настройки прав прав на этот каталог не будет точно !! )

    В итоге запись будет невозможна и задание просто не будет работать.

    Я, например, на днях на подобное нарвался — у пользователя Usr1C81, под чьим именем работал сервер 1С, не было прав на каталог на сервере домена.

    ИМХО журнал регистрации гарантированно лучше.

    2. Для начинающих пользователей еще было очень полезно получить код по непосредственному запуску регламентного задания из клиентского кода, без ожидания срабатывания по расписанию, например, для отладки и/или проверки выполнения

    Код
    РЗ = РегламентныеЗадания.СоздатьРегламентноеЗадание(Метаданные.РегламентныеЗадания.артВыгрузкаКокаКола);
    РЗ.Использование = Истина;
    РЗ.Наименование = "Создали программно для немедленного запуска";
    РЗ.Записать();
    

    Показать полностью

    Reply
  7. Dimasik2007

    (6) Чем больше информации в одном месте, тем лучше 🙂 Опыт лишним не бывает. А что касается файла, то я его делал исходя из личного опыта, т.к. работаю по удаленке, и мне лучше посмотреть электроннку с очетом, который приходит каждое утро, чем лезть по удаленке, загружать базу, смотреть журнал регистрации и т.п.

    Reply
  8. gunslinger

    У меня выдает в текстовый файл

    Ошибка при вызове метода контекста (Восстановить): Операция не выполнена!

    Возможно, в базе имеются работающие пользователи

    Хотя в базе никого нет

    Reply

Leave a Comment

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