Доработки конфигурации. Один совет по избежанию потенциальных грабель




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

37 Comments

  1. Bassgood

    (0) Не ново, плюс в таком подходе также в более удобном обновлении конфы (вместо 100500 своих вставленных в типовую процедуру строк сравнение показывает только одну строку с вызовом нашей процедуры) и более читабельном коде.

    Reply
  2. N_s_s

    Полезная информация, я пишу в коде процедуры, просто с пометками типа

    //***НСС дата
    //**НСС
    

    Хорошо если меняешь одну процедуру, а если пяток?

    то как писать?

    Функция МояФункция(Функция источник, параметр)
    обработка под функции
    КонецФункции
    

    так выходит? советуюсь на будущее

    Reply
  3. user633533_encantado

    Если говорить про УФ, то вообще не нужно лазить в процедуры событий элементов, а переназначать события на свои процедуры программно.

    Reply
  4. Артано

    (2) Вынесение доработок в отдельные функции — это в большинстве случае единственный способ обеспечения сопровождаемости алгоритма. Под сопровождаемостью я понимаю скорость восприятия всего алгоритма в целом и следовательно скорость внесения изменений. Обновление типовой это частный случай сопровождения.

    Также, если вы любитель методов по 1-3к строк, то эта заметка для вас.

    Reply
  5. Артано

    Мультипост

    Reply
  6. Tahallus

    Изучайте расширения конфигураций

    Reply
  7. pm74

    (1) зависит имхо от того насколько глобально меняется конфигурация + насколько важны обновления

    Reply
  8. pm74

    (3) а в чем тут разница между УФ и ОФ ?

    Reply
  9. user633533_encantado

    (8) С точки зрения,того как правильно вносить изменения в конфигурацию, чтобы не иметь проблем с обновлениями — ни в чем.

    Но в новых конфигурациях на УФ, таких как ERP или УТ11 разработчиками добавлены такие общие модули , как «событияформ», которые во многих случаях вообще избавляют от необходимости лезть в типовые модули форм, даже по мелочам.

    Reply
  10. pm74

    (9) может я чего не знаю , но ОФ это сделать проще

    Reply
  11. user633533_encantado

    (10) Что «это» ?

    Reply
  12. pm74

    (11) переопределить поведение элементов формы например

    на картинках форма заказа и скрин из конфигуратора заказа в типовой УТ10.3, обратите внимание что на самом документе и его реквизитах висит замок

    Reply
  13. IsiKosta

    (12) как реализовал?

    Reply
  14. pm74

    (13) инъекции кода в процедуры общих модулей

    Reply
  15. Bassgood

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

    Дело может касаться даже не только более удобного обновления, но и более наглядного разграничения своего кода от типового.

    Reply
  16. pm74

    (15) не всегда получается , например когда доработка делается «лоскутно» по тех заданиям или сильно изменяется функционал конфигурации

    например на рис. документ «заказ на производство» конф. УНФ 1.2 , от стандартного мало что осталось

    Reply
  17. Dmitri93

    (14) Как инъекции кода добавили новые закладки на форму и столбцы в ТЧ? Объясните поподробнее, очень заинтересовал этот вопрос.

    Reply
  18. pm74

    (17) посмотрите в https://infostart.ru/public/535593/

    Reply
  19. Dmitri93

    (18) Спасибо!

    Reply
  20. user633533_encantado

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

    Reply
  21. user633533_encantado

    (16) В таких случаях проще сразу новую форму делать для документа.

    Reply
  22. pm74

    (21)

    А чем проще-то ?

    конфигурация не обновляется ,

    чтобы потом исправлять все обращения к форме документа по всей конфе ?

    Reply
  23. pm74

    (20) вы мне в пример приводите одну единственную конфигурацию с каким то общим

    модулем а делаете обобщения на все УФ в (3) дескать легче программно изменять , хотя методика переопределения обработчиков та же самая

    Reply
  24. user633533_encantado

    (22) Вы похоже не понимаете: в таких конфах как ут11 или ERP в формы и в общие модули лезть не нужно, чтобы добавить реквизиты на форму.

    С обновлением вообще никаких проблем. Все делается программно из своих модулей.

    Reply
  25. user633533_encantado

    (23) Ну так и ваш пример использует общием моудли каких-то определенных конфигураций, он не универсальный.

    А я говорю не об одной , а о целой линейке ут11, erp , ка 2.0 , все что сейчас активно разрабатывается и постоянно обновляется, где как раз и нужны новые методы доработки. А не о старье типа ут 10, на которое только исправительные релизы выходят.

    Reply
  26. ipoloskov

    (24) приходится лезть, если нужно назначить обработчики добавленным элементам формы

    Reply
  27. pm74

    (25) я говорю о том , что переопределение вызова любого обработчика формы одинаковое для УФ и ОФ , в ОФ проще т.к. нет разделения контекстов

    а на «старье типа ут 10» львиная часть фирм работала и будет работать в обозримом будущем

    Reply
  28. user633533_encantado

    (26) Работать то будут, но обновления там незначительные и проблем как правило нет.

    Reply
  29. user633533_encantado

    (27) Ну это понятно.

    Reply
  30. monkbest

    После такой передачи параметров переменные все равно изменятся. Тогда уж надо передавать значения.

    ИМХО: при ручном обновлении модуля надо в новый релиз два раза копипастнуть, а без Ваших советлв — 1

    ИМХО2:Роберт Мартин Вас поддержит, т.к. проповедует функции в три строки не более. Но там java с чистым ООП, а тут 1С с суровой реальностью и лишняя строка в стеке вызовов -100500 к Вашей карме при отладке и пои,ке косяка другим разработчиком

    Reply
  31. monkbest

    (21)забудьте этот криворукий метод!!! Не делайте новых форм, это прикапывание проблемы обновления, а не решения. Потом не разберетесь какого релиза Ваша форма, какого типовая

    Reply
  32. user633533_encantado

    (31) Это всего лишь предположение. А вообще программно модифицировать типовую форму как в 16 может оказаться намного дороже чем сделать свою, заказчик решает.

    Reply
  33. Артано

    (31) (32)

    Отчасти правы оба. Объясню в чем дело. В общих случаях согласен с тем, что модификация формы должна быть программной. Этот метод проще в управляемых, но вполне эффективен (при наличии подготовленного API) и в обычных формах. Впрочем, модификация обычных форм сложна в любом случае =)

    Создание новой формы оправдано в случае если есть есть человек, который будет на постоянной основе анализировать типовые релизы и выдавать указания, что из типовых обновлений должно быть включено в новую форму, а что нет нужды добавлять. Если это условие не выполняется, то есть шанс поймать трудноуловимую ошибку в первичных данных. Ведь остальные объекты типовой конфигурации буду предполагать, что имеют дело с типовым объектом созданным в типовом интерфейсе. А на практике какие-то данные могут иметь другой формат, состав или вовсе отсутствовать.

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

    Reply
  34. monkbest

    (32) вы правы, что решает заказчик: изменять интерфейс кодом или мышкой в визуальном редакторе. Мышкой быстрее, но воспроизводить потом при обновлении вручную — медленнее, т.к. скопипастить элементы управления не всегда удается.

    При автоматизации процесса обновления, код — текст, внешний вид формы — тоже текст и роботу до лампочки где изменения, он сравнивает тексты и объединяет Ваши изменения формируя новый текст, содержащий и Ваши и типовые изменения.

    Но вод создавать новую форму, делать её основной и в неё вносить изменения — это ошибка. Тут Вы никогда не узнаете в процессе обновления, что надо что-то «скрестить» ни робот ни глазки не увидят конфликта версий и конфликт будет обнаружен уже на этапе тестирования. Плюс, если ошибки при тестировании не всплывёт, Ваша форма будет клоном типовой формы неизвестного релиза, версия которого нигде не будет зафиксирована и Вы никак не узнаете какие строки кода в ней типовые, а какие Ваши. По сути Вы теряете все прелести механизма «Поддержки», когда каждому объекту сопоставлен типовой объект и можно сравнить.

    Reply
  35. monkbest

    (33) «человек, который будет на постоянной основе анализировать типовые релизы и выдавать указания»

    Функции этого человека реализованы платформой механизмом «поддержки», платформа сама Вам покажет различия трех конфигураций и Вы примете решение, что делать.

    Reply
  36. andrusevich

    Раньше пользовался маркерами с датой и от кого требование считаю правильным этот подход.

    Сча пишу с нуля на БСП и в основном пищевое или аграрка, проще настроить обмен с упр и бух учетом чем изобретать велосипед

    Reply
  37. avk72

    Звезданул 🙂

    Тема актуальная.

    Reply

Leave a Comment

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