02 September, 2018

Импорт/экспорт в SQLite

SQLite + Bitrix

Вступление

Довольно часто возникает необходимость с импортировании и экспортировании каких-либо данных в 1С-Битрикс. Для этого предусмотрен замечательный штатный механизм экспорта в csv и xml-файлы. Работают они хорошо, но имеют свои ограничения. К примеру xml-экспорт по умолчанию заточен под выгрузку и импорт в один и тот же инфоблок.

Выгрузка в csv-файл напротив заточена под обмен данными с различными системами. На выходе получается csv-файл. Формат куда проще этого вашего XML, но в случае с большими инфоблоками получаются совершненно огромные файлы с которыми трудно работать в интерфейсе условного “экселя”. Также при переносе нужно не забыть прихватить директорию upload/iblock т.к. пути к картинкам ведут туда и по-умолчанию придется тащить всю директорию даже если вы выгрузили только один маленький инфоблок с 3 картинками. Ну или вытаскивать картинки вручную/написанным обработчиком. Также как-то замороченно выглядят привязки к разделам/элементам других инфоблоков. Далеко не самая удобная выгрузка получается, да и лично мне проще работать с SQL-базами данных.

Можно конечно запилить еще одну MySQL БД и экспортировать данные туда, но ведь мы делали экспорт чтобы унести данные куда-то, а стало быть нам затем придется ее и дампить базу. Не так уж и удобно получается. Поэтому ищем другой выход…

SQLite нас спасет

Действительно, та же БД, но в удобном формате =) Ну а теперь я запилю небольшой тестовый проект с примером импорта и экспорта данных из инфоблоков в SQLite.

1. Проверяем доступность SQLite на сервере

Набираем


php -m

и ищем в выводе pdo_sqlite, если данного модуля нет, то устанавливаем его.

Ищем sqlite3


whereis sqlite3

Аналогично в случае недоступности доустанавливаем.

2. Устанавливаем зависимости через composer

Сайт у нас будет называться - test.com, в корне создаем директорию с названием test-export и там размещаем composer.json


{
    "name": "bxblog/testexport",
    "require": {
        "j4mie/idiorm": "^1.5"
    },
    "authors": [
        {
            "name": "Test Testoff",
            "email": "tester@test.com"
        }
    ]
}

И подтягиваем зависимости


composer update

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

3. Пишем свои функции для импорта и экспорта

Итак, после выполнения первых двух шагов в нашей директрии появляются 2 файла и одна директория:

Теперь создадим файл со схемой БД:

В нашу БД мы будем записывать старый id элемента (old_id), затем все необходимые нам поля закодированные в json (data), внешний код элемента (external_id) и при импорте будем отмечать уже обработанные строки (imported).

Теперь создаем там файл index.php

Создаем директорию images.

Создаем директорию includes и файлы:

И файл для импорта:

4. Все!

Вот собственно и все! Теперь при обращении к test.com/test-export/ у нас сгенерируется экспортированная БД (export.db).

Для импорта в другой инфоблок вам нужно лишь раскомментировать следующую строку в index.php

Вот скрин с итоговым кол-вом файлов в проекте:

А вот так мы можем просматривать наш экспорт через GUI:

P.S. А как же картинки?

Внимательные читатели догадаются что у нас никоим образом не использовалась директория images. А все потому что в конретно этом случае у меня не стояла задача выгрузки изображений. Но все же в качестве бонуса приложу часть кода для экспорта и импорта картинок из разделов.

Экспорт

Импорт

02 September, 2018

Страница без шаблона в 1С-Битрикс

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

Так как же запустить страницу без шаблона?

А очень просто:


<?php require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");
//И дальше ваш код здесь
?>
18 June, 2018

Проблемы с установкой node-sass [РЕШЕНО]

Итак, сегодня столкнулся с неожиданной проблемой во время установки зависимостей на сервере для одного из проектов. Привычно набрал npm i и увидел как после продолжительных мучений процесс установки крашнулся показав мне трейс из ошибок.

В трейсе присутствовали строчки:

g++: internal compiler error: killed (program cc1plus)

make: *** [Release/obj.target/libsass/src/libsass/src/ast.o] Error 4

Я не сразу догадался в чем дело и сперва пытался подоткнуть некоторые зависимости для сборки sass (libsass-dev, gcc, g++) и попробовал заюзать yarn. Последний показал себя не с лучшей стороны затянув процесс установки раза в два дольше чем npm и при этом показав менее понятный лог ошибок :thinking:

В итоге я догадался что процесс компиляции прерывается из-за нехватки памяти на сервере (1Gb RAM). Проблему решил включением swap'а.

Лучше после установки убрать swap.

dd if=/dev/zero of=/swapfile bs=4096 count=512k

mkswap /swapfile

swapon /swapfile

Создал себе временно своп на 2 гигабайта и все корректно и довольно быстро установилось.

09 October, 2017

Joomla 3.5 и Virtuemart - отправка письма покупателю сразу после покупки

По какой-то причине разработчики Virtuemart решили что письмо покупателю сразу после сделанного заказа отправлять не нужно. Письма шлются только после смены статуса заказа администратором магазина в админке. Да, это немного странное решение и как я понял не настраиваемое из коробки.

Так как решать вопрос надо было быстро то не обошлось без вмешательства в код Virtuemart:

administrator/components/com_virtuemart/models/orders.php

                // Send the email
                //$res = shopFunctionsF::renderMail('invoice', $order['details']['BT']->email, $vars, null,$vars['doVendor'],$this->useDefaultEmailOrderStatus);
                $sendMail = false;
                if(!$this->useDefaultEmailOrderStatus and isset($vars['newOrderData']['customer_notified']) and $vars['newOrderData']['customer_notified']==1){
                        $sendMail = true;
                } else {
                        $orderstatusForShopperEmail = VmConfig::get('email_os_s',array('U','C','S','R','X'));
                        if(!is_array($orderstatusForShopperEmail)) $orderstatusForShopperEmail = array($orderstatusForShopperEmail);

                        //TODO: Фикс для того чтобы письма отправлялись покупателю сразу после заказа
                        $orderstatusForShopperEmail[] = 'P';

                        if ( in_array((string) $vars['orderDetails']['details']['BT']->order_status,$orderstatusForShopperEmail) ){
                                $sendMail = true;
                                vmdebug('renderMail by default orderstati');
                        }
                }

Решение в виде одной строки сразу после коммента. Это мы добавляем статус "Pending" в список статусов при которых письма отправляются.

Вот и все)

15 May, 2017

Bitrix debug

1) Отключаем в .htaccess auto_prepend_file /bitrix/modules/security/tools/start.php

2) Включаем логи в Битрикс /bitrix/.settings.php

  'exception_handling' =>
  array (
    'value' =>
    array (
      'debug' => true,
      'handled_errors_types' => E_ALL & ~E_NOTICE & ~E_STRICT & ~E_USER_NOTICE & ~E_DEPRECATED,
      'exception_errors_types' => E_ALL & ~E_NOTICE & ~E_WARNING & ~E_STRICT & ~E_USER_WARNING & ~E_USER_NOTICE & ~E_COMPILE_WARNING,
      'ignore_silence' => true,
      'assertion_throws_exception' => false,
      'assertion_error_type' => 256,
      'log' => array (
        'settings' => array (
          'file' => 'bitrix/modules/error.log',
          'log_size' => 1000000,
        ),
    ),
    ),
    'readonly' => true,
  ),

3) Или в php.ini

display_errors display_startup_errors error_log

4) Отладка выгрузки 1С

init.php

AddEventHandler("main", "OnEndBufferContent", "ChangeMyContent");
function ChangeMyContent($content)
{
    if (strpos($_SERVER['REQUEST_URI'],'/bitrix/admin/1c_exchange.php')!==false) {
        $codabra = date("Y-m-d H:i:s")."\n";
        $codabra.= $content."\n";
        $codabra.= $_SERVER['REQUEST_URI']."\n";
        $codabra.= "------------------------------\n";
        file_put_contents($_SERVER["DOCUMENT_ROOT"].'/schmex.log', $codabra, FILE_APPEND);
    }
}
09 March, 2017

Полезности по MySQL

Пишу сюда некоторые запросы чтобы быстро скопипастить их в случае чего:

Получить 10 таблиц из всех БД на сервере с самым большим количеством записей

SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_ROWS FROM information_schema.TABLES ORDER BY TABLE_ROWS DESC LIMIT 10;

Получить 10 самых объемных таблиц из всех БД на сервере в мегабайтах

SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_ROWS, round(((DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024), 2) `Size in MB` FROM information_schema.TABLES ORDER BY (DATA_LENGTH + INDEX_LENGTH) DESC LIMIT 10;

Получить 10 таблиц из БД dbname с самым большим количеством записей

SELECT TABLE_NAME, TABLE_ROWS FROM information_schema.TABLES WHERE TABLE_SCHEMA='dbname' ORDER BY TABLE_ROWS DESC LIMIT 10;

Получить 10 самых объемных таблиц из БД dbname в мегабайтах

SELECT TABLE_NAME, TABLE_ROWS, round(((DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024), 2) `Size in MB` FROM information_schema.TABLES WHERE TABLE_SCHEMA='dbname' ORDER BY (DATA_LENGTH + INDEX_LENGTH) DESC LIMIT 10;
Home← Старые записи