Усовершенствованная проверка заполнения реквизитов




Принцип обмена данными из 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='\

14 Comments

  1. YVolohov

    (1) Не видел. Но это разные вещи. В одном случае единичная функция, в другом целая подсистема с возможностью тонкой настройки и кучей фич. Думаю и тот и другой продукт может быть полезен.

    Reply
  2. Ish_2
    Если (ТипЗначенияЯчейкиТЧ = Тип(«Число»)) и (ЗначениеЯчейкиТЧ = 0) Тогда

    ЯчейкаПустая = Истина;

    ИначеЕсли (ТипЗначенияЯчейкиТЧ = Тип(«Строка»)) и (ПустаяСтрока(ЗначениеЯчейкиТЧ)) Тогда

    ЯчейкаПустая = Истина;

    ИначеЕсли (ТипЗначенияЯчейкиТЧ = Тип(«Дата»)) и (ЗначениеЯчейкиТЧ = ‘00010101000000’) Тогда

    ЯчейкаПустая = Истина;

    ИначеЕсли (ТипЗначенияЯчейкиТЧ = Тип(«Булево»)) Тогда

    ЯчейкаПустая = Ложь;

    ИначеЕсли (ТипЗначенияЯчейкиТЧ = Тип(«Неопределено»)) Тогда

    ЯчейкаПустая = Истина;

    Не понял. Для чего тогда встроенная функция «ЗначениеЗаполнено(ЗначениеЯчейкиТЧ)» ?

    Для «хранилища»,наверное, проверку можно оставить.

    И почему

    ИначеЕсли (ТипЗначенияЯчейкиТЧ = Тип(«Булево»)) Тогда

    ЯчейкаПустая = Ложь;

    Логичнее результат функции «ЗначениеЗаполнено()» для булевого параметра : если параметр = «ложь» ,то ячейка считается незаполненной .

    Через «Попытку» определять заполненность ссылочного значения — это совсем плохо.

    Reply
  3. YVolohov

    (3) Не знал про эту функцию. Спасибо за подсказку. В ближайшее время допилю.

    А вот булевское значение я тоже думал сначала проверять на «параметр = ложь». Но потом решил этого не делать. Если некий реквизит должен постоянно иметь значение «Истина», то он просто не имеет смысла.

    Reply
  4. Ish_2

    (4) Функция ЗначениеЗаполнено() может вызывать ошибку для каких-то типов данных. Сейчас не вспомню.

    Reply
  5. YVolohov

    (5) Попробую погуглить. А хранилище значения наверное лучше вообще не проверять. Думаю это может повлиять на производительность (если программа извлекает значение из хранилища, чтобы проверить его заполненность).

    Reply
  6. Spartan

    (5),(6) Для мутабельных…

    Reply
  7. YVolohov

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

    Reply
  8. YVolohov

    Обновил публикацию. Теперь для проверки заполнения значения использую встроенную функцию ЗначениеЗаполнено(). Тестирование показало, что эта функция игнорирует значения с типами «Булево» и «ХранилищеЗначения» всегда возвращая в результате их проверки «Истина», что в общем достаточно логично.

    Reply
  9. Поручик

    >>> Тестирование показало

    Поржало. А в СП заглянуть: Для значений типа Булево всегда возвращается Истина.

    Reply
  10. YVolohov

    (10) Это в моем характере, не особо вникать в документацию и изобретать велосипеды. Иногда вредно а иногда здорово помагает 😀

    Reply
  11. Ish_2

    (9) Ага,в (3) ошибка. В функции «ЗначениеЗаполнено()» для параметра булевого типа выдается только «Истина».

    Reply
  12. YVolohov

    (12) Нет, ошибки там не будет. Переменная «ЯчейкаПустая» будет всегда принимать значение «Ложь», т.е. всегда будет считаться не пустой, независимо от значения. Сейчас (после обновления) я ипользовал для этого оператор НЕ:

    ЯчейкаПустая = НЕ(ЗначениеЗаполнено(ЗначениеЯчейкиТЧ));

    Reply
  13. igea

    пСсылка (ссылка) — ссылка на элемент справочника или плана, документ.

    Этот параметр лучше передавать не ссылкой, а через ЭтотОбъект, т.к. при передаче ссылкой, если документ уже был заведен -заполненный зрительно реквизит будет передаваться пустым из процедуры ПередЗаписью. У меня была такая проблема. А так автору респект и большой ПЛЮС.

    Reply
  14. shoy

    (1) Публикация не найдена!

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

    Конечно, код чуть править придётся.

    Reply

Leave a Comment

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