Поваренная книга Битриксиста

Работа c MySQL

Помимо получения данных средствами API инфоблоков (CIBlock, CIBlockSection, CIBlockElement, etc.) возможно работать с БД напрямую с помощью объекта, доступного через глобальную переменную $DB.

Использование в скриптах

Плюсы: быстрее API инфоблоков. Возможность писать более гибкие запросы, не доступные через API инфоблоков. Отлично подходит для несложных AJAX-запросов. Скорость ответа DB::Query() vs CIBlockElement::GetList() по данным Firebug: 70-90 / более 200 мс.

Минусы: необходимость разбираться в схеме БД; опасность повреждения данных; маловероятно, но стабильность работы способа при обновлении движка не гарантируется.

Одноразовые правки в БД

Типичные примеры из ТЗ, где использовался pure SQL:

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

Пример:

UPDATE b_iblock_element SET `IBLOCK_SECTION_ID` = 84 WHERE IBLOCK_ID = 6 AND IBLOCK_SECTION_ID IS NULL;

Как видно, запрос не сложный. Но следует перестраховаться, сделав резервную копию (CREATE TABLE ... LIKE ..., INSERT INTO ... SELECT * FROM ...).

Запуск движка из командной строки

Периодически выполняемые задачи в терминах Битрикс называют агентами (Настройка > Инструменты > Агенты). Агенты выполняют вспомогательную работу. Изначально механизм их запуска привязан к запуску движка при посещении сайта. Рекомендуется привязать их выполнение к крону (подробнее тут: http://dev.1c-bitrix.ru/learning/course/?COURSE_ID=43&LESSON_ID=2943).

Альтернативный запуск скрипта - своими силами, как подцепить движок написано тут: http://dev.1c-bitrix.ru/support/faq/8366/#112857

Рабочий пример:

cli.php
<?php
if(php_sapi_name() != "cli") die('Run it in the CLI mode');
 
$blockId = 19;
$projectRootDir = "/srv/devel/apps/naar/www";
 
/**
 * Initial bitrix core
 */
 
$_SERVER['DOCUMENT_ROOT'] = $projectRootDir;
$DOCUMENT_ROOT = $_SERVER["DOCUMENT_ROOT"];
define('NO_KEEP_STATISTIC', true);
define('NOT_CHECK_PERMISSIONS', true);
require($_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/main/include/prolog_before.php');
 
/**
 * Updater class
 */
class IblockUpdater {
  private $db;
  public function __construct() { global $DB; $this->db = $DB; }
 
  private $blockId;
  public function setBlockId ($blockId) { $this->blockId = $blockId; }
 
  public function run() {}
 
/**
 * Running
 */
 
$iblockUpdater = new IblockUpdater();
$iblockUpdater->setBlockId($blockId);
$iblockUpdater->run();

Повторное использование кода

У нас имеется внушительный объем скриптов других проектов, которые в той или иной степени возможно использовать повторно без серьезной переделки.

How to:

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

  CModule::AddAutoloadClasses('', array('JS' => '/lib/JS.php'));

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

Таким способом возможно копировать целые разделы сайта. Пригодится использование шаблона проектирования Адаптер. Например, определить собственный класс для работы с MySQL, завернув его на API Битрикса.

:!: Написание собственных компонентов Битрикса - самый разумный подход к повторному использованию кода.

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

- Учебный курс Битрикса

Это справедливо отчасти. Способов установки компонентов два:

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

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

Идеальным я считаю джумловский менеджер компонентов, который

  • руководствуется XML-схемой установки
  • эта схема определяет файлы (для копирования), SQL-инструкции для установки и скрипты, выполняемые до и после копирования файлов (исполняются при миграции, например), а также инструкции при удалении компонента (прибирается после себя), плюс связанные XML-схемы установок идущих в составе пакета компонентов.

Новые компоненты Битрикса

Фактически, на сегодняшний момент свой компонент нужно писать лишь тогда, когда нужен абсолютно новый функционал для сайта.

- Учебный курс Битрикса

Следующие компоненты фактически требуют такой переделки:

Поиск (bitrix:search.page)

  • доступны только два варианта сортировки - по релевантности и дате, причем только в одном направлении
  • невозможно сделать сепаратный поиск по заголовкам, текстам, тегам - только все вместе

Подписка (bitrix:subscribe.edit)

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

Модификация админки

Возможно задать шаблон редактирования и определить скрипт, выполняющийся при сохранении элемента.

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

app/php_interface/aliases.php
function Translit($text) {
  ...
}
 
if (strlen($_POST['CODE']) == 0) {
  $_POST['CODE'] = Translit($_POST['NAME']);
}

Добавление столбца в режиме показа всех элементов делается штатными средствами (звездочка справа).

Добавить произвольное вычисляемое поле (например, $row['idate'] =\> date('d.m.Y', $row['idate'])) возможно редактированием ядра модуля (других способов я не нашел).

Например, для добавление прямых fron-end-ссылок на материалы из списка комментариев следует отредактировать файл lib/bitrix/modules/forum/admin/forum_topics.php

Привязки элемента к нескольким разделам

Существует нативный способ привязки элемента к нескольким разделам. Он доступен на странице «разделы». Эту возможность используют редко. Получить все группы элемента инфоблока: http://dev.1c-bitrix.ru/api_help/iblock/classes/ciblockelement/getelementgroups.php

Чтение документации

Подборка how-to из документации:

Фильтр со сложной логикой http://dev.1c-bitrix.ru/api_help/iblock/classes/ciblockelement/getlist.php

Примечание по типу проверки фильтра:

  • Как выяснилось, !>< также работает
  • Поиск элемента без установленного свойства: $arrFilter['PROPERTY_DATE'] = false;
Печать/экспорт