Командное окно




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

22 Comments

  1. coder1cv8

    Напрасно боишься 😉 никто пинать ногами и не собирается… Я свой плюсик поставил )

    Reply
  2. tormozit

    Я боюсь и не плюсую.

    Reply
  3. coder1cv8

    (2) А почему свою консоль не сделаешь со встроенной контекстной подсказкой? Или я чего-то пропустил?…

    Reply
  4. uncle_o

    Очень хочу контекстную подсказку — времени нет:((( Я и консоль то на коленке сваял, самый минимум, чтобы свою работу немного ускорить.

    Reply
  5. tormozit

    (3) В моей подсистеме есть справочник Алгоритмы. Обычно я открываю форму нового элемента этого справочника и имею ту же самую «консоль кода» только более продвинутую. Ведь обычно результат своего мучения в «консоли кода» в конце нужно сохранять, а у меня просто нужно записать элемент справочника и готово!

    Reply
  6. uncle_o

    Ну, я и не претендую, как можно-с… Если бы знал, что существует такой шедевр … все равно бы написал так же.

    Фишка в том, что Командное Окно — это возможность выполнять команды по одной: выполнил — посмотрел, что получилось — выполнил следующую. Не теряя при этом предыдущих выполненных команд, к которым можно всегда вернуться, просто поднявшись вверх по протоколу. И сохраняя, естественно, вычисленные значения. И больше ничего! Просто, как три копейки. Такой механизм есть во всех интерпретаторах. Странно, что в 1С — интерпретирующей по сути системе — нет такого штатного способа работы. Даже для чисто компилятивных языков, как С и Паскаль, давно уже есть возможность выполнять исходный код, не выходя из среды разработки.

    Что касается Справочника алгоритмов, то это вещь, нет слов, полезная. Только, что сохранять из командного окна? Текст типа:

    %зп = новый запрос(«ВЫБРАТЬ … &пп…»)

    зп=установитьпараметр(«пп», …)

    %тз = зп.выполнить().выгрузить()

    смотр(тз)

    или

    %фф=Документы.МойДок.ПолучитьФорму()

    фф.Открыть()

    !фф.Открыта()

    !фф.ЭлементыФормы.Поле.Реквизит

    Его проще написать, чем искать в справочнике.

    Опять же, справочник полезных алгоритмов, привязанный к конфигурации, — это что же, сколько у меня конфигураций — столько справочников? А если я чего изменил, мне что, по всем остальным экземплярам справочника изменения дублировать? Или я чего-то недопонял?

    С полным уважением ко всем присутствующим, Дядюшка О.

    Reply
  7. coder1cv8

    (5) Хотелось бы именно «консоль», в виде внешней обработки… )

    Reply
  8. German

    (6) смотрите EI там прекрасная «консоль кода» как вы ее называете…

    Reply
  9. tormozit

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

    По поводу внешней обработки я также согласен (в моем случае переход к подсистеме был неизбежен).

    Reply
  10. uncle_o

    (8) EI — это круто! Оценил. Только (простите за занудство), хотелось бы, чтобы значения переменных, полученных при выполнении строк по одной, сохранялись бы… Это можно?

    Reply
  11. German

    (10) я даже не представляю как это можно реализовать?

    Reply
  12. Totoro

    (11) Я тоже такое бы хотел :), но возникают проблемы с циклами/условиями/попытками. Либо после каждой строки нужно вызывать модальную форму со значениями переменных (код значительно разбухнет) 🙂

    Reply
  13. German

    (12) хотя по идее такое есть .. только переменные нужно определить вначале …

    А потом

    Параметры.Эл=25*40-11;

    А потом использовать эту переменную в последующих строках….

    Сообщить(Параметры.Эл);

    в Ei реализовано в «Конструкторе запросов» на закладке «Встроенный язык»

    Reply
  14. Totoro

    (13) Надо будет дома посмотреть (на пока работе файловая)…

    Но я имел ввиду следующее. Допустим вызываем код через:

    Выполнить(ПодготовитьКод(«А = 1; Б= 2;«)). Тогда код преобразуется в следующий:

    А=1;

    ОбработатьТекущуюСтрокуИПоказатьМодульнуюФормуСПеременными();

    Б= 2;

    ОбработатьТекущуюСтрокуИПоказатьМодульнуюФормуСПеременными();

    где на модальной форме будут показаны только доступные сейчас переменные

    Reply
  15. German

    (14) этот функционал работает и в файловой версии … Модальное окно там есть … где перечислены элементы входящие в структуру параметров

    Reply
  16. Totoro

    (15) Действительно работает (прошу прощения за свою ленивость 🙂 ), но выполняется сразу весь указанный (или выделенный) код (если я правильно понял). Но опять же проблема в циклах и т.п. Сейчас попробую набросать простейший пример построчного выполнения без анализа кода.

    Reply
  17. uncle_o

    (11) Я это сделал так: либо Вы определяете переменную через Перем П1, П2, …, либо при первом присваивании указываете ее имя с % — %П1=10. Перед выполнением текст анализируется и структуре-реквизите формы Локалы заводится поле по каждую определенную таким образом переменную. Затем, к выполняемому тексту впереди добавляется текст П1=Локалы.П1, а в конце Локалы.П1 = П1 для определенных переменных, используемых в исполняемом фрагменте (см.текст обработки).

    Reply
  18. Totoro

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

    Для указанного примера кода параметры будут доступны постепенно:

    А = Новый Структура(«Поле1, Поле1»);

    Б = 2;

    А.Поле1 = Б;

    http://zalil.ru/upload/24840608

    Reply
  19. Totoro

    Подправил автообновление параметров по шагам и выход из выполнения при нажатии «Закрыть»

    http://slil.ru/24840694

    Reply
  20. tormozit

    Нечто подобное и я пытаюсь придумать, но пока никак не могу преодолеть все преграды.

    Нужно написать практически полноценный парсер текста, который кроме разбивки на командные блоки промаркирует конструкции ЕСЛИ ТОГДА, ПОКА ЦИКЛ, ДЛЯ КАЖДОГО ИЗ ЦИКЛ, ДЛЯ ПО ЦИКЛ, ПОПЫТКА ИСКЛЮЧЕНИЕ. Каждую из этих конструкций придется специфическим образом обрабатывать. Обращение к каждой локальной переменной, которые нужно будет еще отличить от свойств глобального контекста, нужно будет префиксовать типа Переменные.<ИмяПеременной>. Ну есть и еще ряд проблем…

    Reply
  21. uncle_o

    А командные блоки зачем разбирать, если не секрет?

    Reply
  22. German

    (20) И отличить » ПОПЫТКА -«+»123» от настоящего оператора ПОПЫТКА

    Reply

Leave a Comment

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