показать полностью
Пользователь 124877  -> Примеры частных решений
13 Август, 2014 14:46
инструменты диагностики нового ядра
И снова здравствуйте.
По ходу работы, часто приходится производить отладку и прочие замеры, и руками писать всякие записи в файлы не очень-то оптимально. Бывает, вижу что кто-то подключает свои файлы, и использует функции оттуда, для упрощения отладки. Но в продукте есть отдельные инструменты, которые могут упростить данную операцию.

Вывод данных
Итак, есть у нас вызов АПИ, и хочется увидеть, с какими параметры в данном месте производится вызов. Лично я предпочитаю запись в файл, чтобы никак не влиять на работу сайта (разные проверки ip и прочее лениво писать).
Код для записи в файл получится компактным:
Bitrix\Main\Diag\Debug::writeToFile(array('ID' => $id, 'fields'=>$fields ),"","prices.txt");
тут у нас первым параметром идет сами данные, которые мы хотим увидеть, вторым идет название переменной, а третьим - имя файла (можно указывать путь, к примеру /bitrix/log.txt)

я лично сразу пишу много данных и сразу в массиве указываю подходящие ключи, поэтому второй параметр не использую
на выходе получим примерно такое:

Array
    (
        [ID] => 26028
        [fields] => Array
            (
                [PRODUCT_ID] => 54586
                [CATALOG_GROUP_ID] => 1
                [^PRICE] => 1840
                [CURRENCY] => RUB
                [QUANTITY_FROM] => 
                [QUANTITY_TO] => 
                [PRICE] => 1840
                [RECALC] => 
            )
    ) 

если же могут быть булевы переменные, то можно и так указать:
Bitrix\Main\Diag\Debug::dumpToFile(array('ID' => $id, 'fields'=>$fields ),"","prices.txt"); 
вывод соответственно будет через var_dump

Учет времени
Если же надоучесть время выполнения того или иного участка кода, то и для этого есть подходящие функции.
В начале исследуемого участка кода, добавляем:
Bitrix\Main\Diag\Debug::startTimeLabel('test'); 
в конец:
Bitrix\Main\Diag\Debug::endTimeLabel('test'); 
И для вывода используем:
Bitrix\Main\Diag\Debug::getTimeLabels(); 

метод возвращаем массив со всеми включенными учетами времени
Helper
Также есть вспомогательный класс Helper (Bitrix\Main\Diag\Helper), в котором всего пару функций:
Bitrix\Main\Diag\Helper::getCurrentMicrotime(); 
и
Bitrix\Main\Diag\Helper::getBackTrace($limit = 0, $options = null); 
думаю, из названия и так понятно, для чего они нам могут пригодиться.
Дрёмин Станислав
Еще в копилку - SQL tracker http://dev.1c-bitrix.ru/community/web...log/10205/
4 Ещё
Васильков Евгений
Дрёмин Станислав,  отлично, а то не было времени поразбираться в нем.
0 Ещё
Сильчук Светлана
Bitrix\Main\Diag\Debug::writeToFile() не работает там где не определена переменная $_SERVER["DOCUMENT_ROOT"]
1 Ещё
показать полностью
Пользователь 124877  -> Примеры частных решений
2 Сентябрь, 2014 17:40
Подписка мобильного приложения на push-уведомления
Приветствую. Последнее время, участились вопросы по функционалу получения push-уведомлений в мобильной приложении, поэтому я решил написать данную статью.
Схема работы такова, что чтобы приложение начало получать push-уведомления, оно должно подписаться на них.
За саму подписку у нас будет отвечать отдельный скрипт:
        <?
    define('NO_KEEP_STATISTIC', true);
    define('NO_AGENT_STATISTIC', true);
    define('NOT_CHECK_PERMISSIONS', true);
    require($_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/main/include/prolog_admin_before.php');

    if(!check_bitrix_sessid()) return;

    $token = $_REQUEST["device_token"];
    $arFields = Array(
        "USER_ID" => $USER->GetID(),
        "DEVICE_NAME" => $_REQUEST["device_name"],
        "DEVICE_TYPE" =>  $_REQUEST["device_type"],
        "DEVICE_ID" => $_REQUEST["uuid"],
        "DEVICE_TOKEN" => $token,
        "APP_ID" => "BitrixMobile"
    );
    if(!$_REQUEST["device_token"])
        break;
    if(!CModule::IncludeModule("pull"))
    {
        $arResult["ERROR"] = GetMessage("MOBILEAPP_PULL_NOT_INSTALLED");
        break;
    }
    $uuid = $_REQUEST["uuid"];
    $data = array(
        "register_token" => "fail",
        "token" => $token,
        "user_id" => $USER->GetID() 
    );
    $dbres = CPullPush::GetList(Array(), Array("=DEVICE_ID" => $uuid));
    $arToken = $dbres->Fetch();
    if($arToken["ID"])
    {
        $res = CPullPush::Update($arToken["ID"], $arFields);
        if($res)
            $data["register_token"] = "updated";
    }
    else
    {
        $res = CPullPush::Add($arFields);
        if($res)
            $data["register_token"] = "created";
    }
    $arResult["DATA"] = $data;
    if(isset($arResult["ERROR"]))
        $arResult["RESULT"] = "ERROR";
    else
        $arResult["RESULT"] = "OK";
    $arResult = $APPLICATION->ConvertCharsetArray($arResult, SITE_CHARSET, 'utf-8');
    die(json_encode($arResult));
    ?> 

Данный скрипт никак не зависит от устройства, которое вы используете. Собственно похожий скрипт используется и в административном приложении для магазина.Одно но!
"APP_ID" => "BitrixMobile"
это код приложения для разработки. При компиляции вашего приложения, код будет иным.
Пусть путь у него будет: /eshop_app/pull.php

А вот определяющим будет js скрипт, который и будет отправлять запрос подписки приложения.

    BX.ready(function(){
        DEV.getToken();
    });
    DEV = {
        getToken : function ()
        {
            var _this = this,
                dt = "APPLE";

            if (platform != "ios")
                dt = "GOOGLE";

            var params = {
                callback: function (token)
                {
                    var postData = {
                        action: "save_device_token",
                        device_name: device.name,
                        uuid: device.uuid,
                        device_token: token,
                        device_type: dt,
                        sessid: BX.bitrix_sessid()
                    };

                    BX.ajax({
                        timeout:   30,
                        method:   'POST',
                        dataType: 'json',
                        url:       '/eshop_app/pull.php',
                        data:      postData,
                    });
                }
            };

            return app.exec("getToken", params);
        }
    };
 
Данный код вы можете вызывать при любых условиях, по которым нам необходима подписка на push-уведомления.
Собственно, это и все.
Долганин Антон
Не очень очевидный факт - юзер должен быть авторизован, чтобы подписка прошла.
2 Ещё
Попов Кирилл
А глобальную рассылку можно делать, всем - и неавторизованным и авторизованным?
0 Ещё
Попов Кирилл
Подскажите, а где задается иконка для уведомлений http://c2n.me/3KWmLMB
0 Ещё
показать полностью
Пользователь 124877  -> Примеры частных решений
12 Ноябрь, 2013 13:54
Редактирование настроек ядра 14 версии
Всем привет!

Все ожидали выхода нового ядра, и вот оно и вышло.
Как я думаю, многим уже известно, что часть настроек уже берется из файла /bitrix/.settings.php
Этот файл структурно сильно отличается от прежнего dbconn.php и править его руками довольно неудобно. Благо, его и не надо править руками, в большинстве случаев, так как есть API главного модуля, которое позволяет читать настройки, и записывать их.
За это отвечает класс Configuration (Bitrix\Main\Config\Configuration).

По самой структуре, файл настроек содержит параметр readonly для определенных секций, это означает, что данные настройки не будут изменены через API.

Я написал скрипт, который пока дает редактировать такие параметры как:

DEBUG - вывод ошибок на экран (прежний параметр $DBDebug)
handled_errors_types - типы ошибок, которые будут записытьваться в лог
exception_errors_types - типы ошибок, которые будут обрабатываться через исключение, т.е. при их возникновении работа будет остановлена и на экран будет выведена только ошибка. (ВНИМАНИЕ! Вывод максимально возможных ошибок может привести и к неработоспособности самого скрипта(смотря какая ошибка), в таком случае, изменить настройки обратно можно будет только через прямое изменение файла настроек fixed(0.2) )
LOG - параметры лога (с ошибками)
Cache settings - параметры хранения кеша (файлы/memcache и т.п.)

Скрипт будет работать только с 14 версией ядра, на более старых выдаст ошибку да и бессмысленно его там запускать.
Позднее включу изменение остальных параметров, которые беруются из файла настроек.

P.S. файл в CP1251 - fixed

UPD 0.2:
- из минимального типа обработки ошибок убран E_DEPRECATED;
- подключается минимум ядра, поэтому exception_errors_types не валит работу скрипта;

UPD 0.3:
- добавлена возможность просмотра лога ошибок
- мелкие фиксы
bx_tweaker.php (10.35 КБ)
Панишев Александр
А так задумано что скрипт дает пустой экран?
я сначала подумал что он позволяет задать параметры в удобочитаемом виде, но запустив увидел только пустой экран.
1 Ещё
Васильков Евгений
На какой версии php и версии ядра?
1 Ещё
Панишев Александр
пустой экран как оказывается появляется если скрипт бросить не в корневую папку сайта. А так все ок,работает как положено, не понятно почему не сделали так в админке...
3 Ещё
показать полностью
Пользователь 124877  -> Примеры частных решений
4 Сентябрь, 2014 19:54
Тестирование отправки push-уведомлений.
В прошлый раз мы подписали наше приложение на push-уведомления (link)
Теперь надо проверить работу.

Для отправки необходимо использовать метод модуля Push&Pull
Примерный код таков:

$arMessages[] = array(
         "USER_ID" => $value['user_id'],
         "TITLE" => 'Push test script',
         "APP_ID"=> $value['app_id'],
         "MESSAGE" => $request['message'],
      );
$pushMe = new CPushManager();
$result = $pushMe->SendMessage($arMessages);
 
конечно вручную каждый раз все это указывать муторно, поэтому я написал скрипт, для тестирования данного функционала, т.е. отправки push-уведомлений на мобильные устройства.

Выглядит это таким образом:
shot_937.png

Скрипт достаточно поместить в папку сайта (желательно в /bitrix) ну и открыть в браузере.
Работает только из под администратора.
push_test.php (14.02 КБ)
показать полностью
Пользователь 124877  -> Примеры частных решений
9 Июль, 2014 18:14
Написание модуля на D7+ORM
Всем привет, давно хотел написать данную простенькую статейку, но все не находил времени.
Итак, всем известно (или почти всем), что уже в продукте есть и новое ядро, ORM и все это постепенно улучшается. Так вот, сегодня я вам расскажу какая примерно последовательность создания модулей на новом ядре с использованием ORM. Отчасти затрону использование amCharts, который идет в поставке как КП, так и БУС, и вы можете использовать его в полном объеме.

Структура файлов
Так как модуль для локального использования, то будем использовать папку local в корне сайта, которая стала доступна с 14 версии ядра.
Мой модуль называется my.ticketstat, так и называется папка модуля, размещенная в /local/modules/. В ней у нас примерно стандартный набор, это папки: admin, install, lang, lib. Отдельно заострим внимание на lib - теперь никаких папок classes и прочего. Тут у нас будет хранится основная логика модуля, и это нам позволит использовать namespace с автоподгрузкой при вызове.

Логика работы модуля
Логика будет достаточно простая:
1. Принять данные.
- данные будут приходить из внешнего источника, поэтому будет использоваться публичный скрипт.
2. Отдать обработанные данные.
- данные отдаются в виде json, с последующей обработкой и построением графика в amCharts.

База данных
База у нас будет очень простая, всего с двумя полями (integer и datetime).
Для её описания в ORM воспользуется пока скрытыми возможностями модуля производительности, а именно, работы с таблицами.
Добавляем GET параметр orm=y и у каждой таблицы в контекстном меню добавляется пункт ORM.
На выходе получаем почти готовые данные для описания таблицы. После некоторых изменений, у нас остается:

    namespace My\Ticketstat;

    use Bitrix\Main\Entity;
    use Bitrix\Main\Localization\Loc;
    Loc::loadMessages(__FILE__);

    /**
     * Class StatTable
     * 
     * Fields:
     * <ul>
     * <li> COUNT int mandatory
     * <li> TIME datetime optional
     * </ul>
     *
     * @package Bitrix\Data
     **/

    class StatTable extends Entity\DataManager
    {
        public static function getFilePath()
        {
            return __FILE__;
        }

        public static function getTableName()
        {
            return 'bx_custom_stat';
        }

        public static function getMap()
        {
            return array(
                'COUNT' => array(
                    'data_type' => 'integer',
                    'primary' => true,
                    'required' => true,
                    'title' => Loc::getMessage('STAT_ENTITY_COUNT_FIELD'),
                ),
                'TIME' => array(
                    'data_type' => 'datetime',
                    'title' => Loc::getMessage('STAT_ENTITY_TIME_FIELD'),
                ),
            );
        }
    }

можно считать, что пол дела сделано
Работа с данными
Для начала нам надо получить данные, и записать их в нашу базу данных.
За это у нас будет отвечать файл tools/stat_add.php.
Необходимые значения будут передаваться через GET, поэтому будем использовать объект запроса:

    $context = \Bitrix\Main\Application::getInstance()->getContext();
    $request = $context->getRequest();
    $request->get('text');

Для записи в базу, нам не надо придумывать велосипеды, методы ORM у нас уже есть на вооружении, достаточно ими воспользоваться:

    \My\Ticketstat\StatTable::add(array(
        'COUNT' => $count,
        'TIME' => new \Bitrix\Main\Type\DateTime(null,0)
    ));
 

Как видно, все гениальное - просто!
Теперь на очереди получение данных, за это у нас отвечает файл tools/get_stat.php.
Данные могут отдаваться за определенный день:

    $filter = array('><TIME' => array(
                    new \Bitrix\Main\Type\DateTime(
                               date($request->get('date').' 00:00:00'),
                            'Y-m-d H:i:s'
                        ),
                    new \Bitrix\Main\Type\DateTime(
                            date($request->get('date').' 23:59:59'),
                            'Y-m-d H:i:s'
                        )
                ),);

так и от определенного времени:

    $filter = array('>=TIME' => new \Bitrix\Main\Type\DateTime(
                    date('Y-m-d '.$request->get('time')),
                    'Y-m-d H:i:s'
                ),);

И фильтр идет в наш GetList, который мы также сами не писали:

    $arStat = \My\Ticketstat\StatTable::getList(array(
            'select' => array("COUNT","TIME"),
            'order' => array("TIME"=>'asc'),
            'filter' => $filter,
        ));
    while ($stat = $arStat->fetch(new \My\Ticketstat\TestConverter))
    {
        $result[] = $stat;
    }

Тут мы используем наш конвертер данных, чтобы они у нас получались сразу в нужном формате.
Сам конвертер у нас определен в файле lib/testconverter.php:

    namespace My\Ticketstat;

    class TestConverter extends \Bitrix\Main\Text\Converter
    {
        public function encode($text, $textType = "")
        {
            if ($text instanceof \Bitrix\Main\Type\DateTime)
                return $text->format('Y-m-d H:i:s');

            return \Bitrix\Main\Text\String::htmlEncode($text);
        }

        public function decode($text, $textType = "")
        {
            if (is_object($text))
                return $text;

            return \Bitrix\Main\Text\String::htmlDecode($text);
        }
    }

как видно, ничего сложного.
В начале я упоминал про amCharts. Вот его то мы и будем использовать для вывода наших данных.
Честно говоря, мне сильно наскучили графики, которые выводятся как единая картинка. А тут у нас готовая библиотека для построения красивых и динамичных графиков и прочего.
Всего-то нам надо подключить:
/bitrix/js/main/amcharts/3.3/amcharts.js
/bitrix/js/main/amcharts/3.3/serial.js


P.S. версия может отличаться
Поигравшись с желаемым видом графика, настройками и темой, мы можем получить приятный результат подобного вида:
shot_896.png
Долганин Антон
Плюс вот здесь в двух комментах я осветил два довольно неприметных камня при написании обработчиков:
http://dev.1c-bitrix.ru/community/blo....php#58070
0 Ещё
Васильков Евгений
Долганин Антон написал:
случае файл с классом StatTable должен называться stat.php.
Об этом и в учебных курсах написано:
http://dev.1c-bitrix.ru/learning/cour....5748.5749
0 Ещё
Загальский Андрей
Долганин Антон,  я тоже плюнул вообще на Entity\Event $event. (onAfterDelete(array $event)) Сколько не пытался так ничего нормально не работало - одна ругань. Данные модифицировать не пришлось вроди так тоже работать должно
0 Ещё
показать полностью
Пользователь 124877  -> Примеры частных решений
3 Февраль, 2014 19:07
собственный обработчик ошибок
Всем привет.
Продолжаем познавать нововведения нового ядра продукта.


На этот раз - это подключение собственного обработчика ошибок для всего продукта.

За обработку ошибок отвечает блок exception_handling в файле настроек /bitrix/.settings.php
В данном блоке есть параметр log, в котором можно добавить опции:

'class_name' => 'MyTest',
'extension' => '',
'required_file' => 'modules/mylog.module/lib/log.php',
в данном случае, уже указаны мои тестовые значения.
По названию, я думаю, понятно, что за что отвечает.

Двигаем далее. Мы указали подключение файла modules/mylog.module/lib/log.php, его и создадим.
<?php
class MyTest
   extends \Bitrix\Main\Diag\ExceptionHandlerLog
{
   private $URL;

   public function initialize(array $options)
   {
      $this->URL = $options["send_url"];
   }

   public function write(\Exception $exception, $logType)
   {
      $title = \Bitrix\Main\Diag\ExceptionHandlerFormatter::severityToString($exception->getSeverity());
      $text = $exception->getMessage();
      $text .= "\n".$exception->getFile()."[".$exception->getLine()."]";
      $this->SendError($title,$text);
   }

   protected function SendError($title,$text)
   {
      $data = array('name' => $title, 'text' => $text);
      $sock = new CHTTP();
      $sock->Post($this->URL,$data);
   }
}
 
Как видно, класс тот, что указан в конфигурационном файле. Данный класс должен быть унаследован от \Bitrix\Main\Diag\ExceptionHandlerLog
Обязательных 2 функции initialize и write.
Собственно первая вызывается для инициализации, а вторая для обработки ошибки.

В функции инициализации у меня просто заполняется переменная, значение для которой передается из .settings.php
В функции записи производится подготовка текста ошибок для отправки.

Затем вызывается SendError, которая отправляет данные мне на компьютер, на специальный скрипт. Как итог, на экране я вижу возникающие ошибки.
shot_711.png
Kriachek Mikhail
Для полноты картины расскажите читателям откуда берется\устанавливается
$options["send_url"];
1 Ещё
Васильков Евгений
Kryachek Mikhail,  все из того же .settings.php

'log' => 
      array (
        'settings' => 
        array (
          'send_url' => 'http://localhost/notify.php'
        ),
        'class_name' => 'MyTest',
        'extension' => '',
        'required_file' => 'modules/mylog.module/lib/log.php',
      ),
 
0 Ещё

Группы на сайте создаются не только сотрудниками «1С-Битрикс», но и партнерами компании. Поэтому мнения участников групп могут не совпадать с позицией компании «1С-Битрикс».