В интернете есть много информации по тому, насколько хороша архитектура D7, но мало практической информации как, например, организовать код, какие новые возможности мы можем использовать на практике и для чего. В данной статье я опишу о том как создать модуль D7, какие основные моменты нужно учесть.
Для нетерпиливых исходный код модуля можно скачать здесь.
Всю теоретическую информацию о D7, вы можете найти в документации для разработчиков на сайте 1С:Битрикс. А на практике я опишу как использовать: namespace, ORM, автозагрузку классов.
Структура модуля
Для начала создадим основную структуру модуля, состоящую из следующих папок, файлов, структура модуля D7 аналогична обычному модулю:
- admin
- menu.php - меню в админке битрикс
- install
- db
- install.sql - запросы, которые выполняются при установке модуля
- uninstall.sql - запросы, которые выполняются при удалении модуля
- index.php - основной файл установки
- lang
- ru
- lib
- data.php - языковой файл
- lib
- test.php - основной класс модуля
- data.php - здесь будут настройки ORM
- include.php - файл, который используется для подключения файлов модуля
далее по порядку разберём файлы модуля.
Файл /admin/menu.php
Данный файл создаёт пункты меню в административном интерфейсе 1С:Битрикс.
В нём небходимо создать массив $aMenu, в котором указываются параметры меню:
- parent_menu - родительская группа меню
- url - ссылка на страницу модуля
так как модуль без отдельной страницы, то ссылку укажем на таблицу модуля
defined('B_PROLOG_INCLUDED') and (B_PROLOG_INCLUDED === true) or die(); use Bitrix\Main\Localization\Loc; Loc::loadMessages(__FILE__); $aMenu = array( array( 'parent_menu' => 'global_menu_content', 'sort' => 400, 'text' => "Тестовый модуль", 'title' => "", 'url' => 'perfmon_table.php?lang=ru&table_name=brainkit_test', 'items_id' => 'menu_references' ) ); return $aMenu;
Файл /install/db/install.sql
В данном файле напишем запрос на создание таблицы 'brainkit_test' помимо основных полей ID и TITLE, добавим поля SORT и CREATED, для сортировки и сохранения даты изменения записи в таблице соответственно:
CREATE TABLE `brainkit_test` ( `ID` INT(11) NOT NULL AUTO_INCREMENT, `TITLE` VARCHAR(65536) NOT NULL, `SORT` INT(11) DEFAULT 500, `CREATED` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY(ID) );
Файл /install/db/uninstall.sql
А здесь sql запрос на удаление созданной базы:
DROP TABLE IF EXISTS `brainkit_test`;
Файл /install/index.php
Данный файл является классом, который наследуется от класса Cmodule, выполняется при установке или удалении модуля через административный интерфейс.
В конструкторе класса указывается справочная информация о модуле: версия, дата обновления, имя и описание.
В методах класса должны обязатально присутствовать методы: DoInstall и DoUninstall, которые отрабатывают при установке и удалении модуля, а внутри них должны вызываться функции RegisterModule и UnRegisterModule для регистрации и удаления регистрации модуля в базе соответственно.
Внутри методов DoInstall/DoUninstall реализуем методы для: создания/удаления таблицы в базе, установки/удаления событий и дополнительных файлов модуля. Так как для нашего модуля не нужны события и дополнительные файлы, то эти методы просто оставим для будущего расширения возможностей модуля.
Исходный код файла:
<? IncludeModuleLangFile(__FILE__); use \Bitrix\Main\ModuleManager; Class Brainkit_D7 extends CModule { var $MODULE_ID = "brainkit.d7"; var $MODULE_VERSION; var $MODULE_VERSION_DATE; var $MODULE_NAME; var $MODULE_DESCRIPTION; var $errors; function __construct() { //$arModuleVersion = array(); $this->MODULE_VERSION = "1.0.0"; $this->MODULE_VERSION_DATE = "20.03.2016";https://dev.sokolov.ru/jewelry-shops/RU/Sankt-Peterburg/?country=RU&city=Sankt-Peterburg $this->MODULE_NAME = "Пример модуля D7"; $this->MODULE_DESCRIPTION = "Тестовый модуль для разработчиков, можно использовать как основу для разработки новых модулей для 1С:Битрикс"; } function DoInstall() { $this->InstallDB(); $this->InstallEvents(); $this->InstallFiles(); RegisterModule("brainkit.d7"); return true; } function DoUninstall() { $this->UnInstallDB(); $this->UnInstallEvents(); $this->UnInstallFiles(); UnRegisterModule("brainkit.d7"); return true; } function InstallDB() { global $DB; $this->errors = false; $this->errors = $DB->RunSQLBatch($_SERVER['DOCUMENT_ROOT'] . "/bitrix/modules/brainkit.d7/install/db/install.sql"); if (!$this->errors) { return true; } else return $this->errors; } function UnInstallDB() { global $DB; $this->errors = false; $this->errors = $DB->RunSQLBatch($_SERVER['DOCUMENT_ROOT'] . "/local/modules/Brainkit.D7/install/db/uninstall.sql"); if (!$this->errors) { return true; } else return $this->errors; } function InstallEvents() { return true; } function UnInstallEvents() { return true; } function InstallFiles() { return true; } function UnInstallFiles() { return true; } }
Файл /lang/ru/lib/data.php
Данный файл служит для реализации переводов для файла /lib/data.php, в нём простой массив $MESS, в котором хранитяся пары ключ=>значение перевода. А часть ru в пути к файлу является указанимем на язык перевода.
После того как мы создали файл, в любой части кода модуля, для получения перевода, мы можем вызвать функцию Loc::getMessage('KEY'), где KEY - ключ перевода:
<? $MESS["DATA_ENTITY_ID_FIELD"] = "ID"; $MESS["DATA_ENTITY_TITLE_FIELD"] = "Заголовок";
Файл /lib/test.php
В данном файле пристуствует namespace, который называется в соответвии будет храниться основная логика работы модуля, файл подключается в файле /include.php, для примера реализуем в данном файле получение одной записи из таблицы модуля с помощью ORM класса DataTable:
<?php namespace Brainkit\D7; use Brainkit\Data\DataTable; class Test{ public static function get($cond) { $result = DataTable::getList( array( 'select' => array('*') )); $row = $result->fetch(); print "<pre>"; print_r($row); print "</pre>"; return $row; } }
Файл /lib/data.php
Данный файл служит для организации доступа к таблице с помощью ORM, в нём создаётся класс DataTable, который наследуется от класса Entity\DataManager, который в свою очередь реализует парадигму ORM. Для того что бы подключить наш класс к ORM, мы должны указать имя таблицы и задать структуру, для этого есть 2 метода getTableName и getMap соответственно. Исходный код:
<?php namespace Brainkit\D7; use Bitrix\Main\Entity; use Bitrix\Main\Localization\Loc; /** * Class DataTable * * Fields: * <ul> * <li> ID int mandatory * <li> LINK string mandatory * <li> PATH string mandatory * <li> SORT int optional default 500 * <li> CREATED datetime mandatory default 'CURRENT_TIMESTAMP' * </ul> * * @package \Brainkit\Data **/ class DataTable extends Entity\DataManager { /** * Returns DB table name for entity. * * @return string */ public static function getTableName() { return 'brainkit_test'; } /** * Returns entity map definition. * * @return array */ public static function getMap() { return array( 'ID' => array( 'data_type' => 'integer', 'primary' => true, 'autocomplete' => true, 'title' => Loc::getMessage('DATA_ENTITY_ID_FIELD'), ), 'TITLE' => array( 'data_type' => 'text', 'required' => true, 'title' => Loc::getMessage('DATA_ENTITY_TITLE_FIELD'), ), 'SORT' => array( 'data_type' => 'integer', 'title' => Loc::getMessage('DATA_ENTITY_SORT_FIELD'), ), 'CREATED' => array( 'data_type' => 'datetime', 'title' => Loc::getMessage('DATA_ENTITY_CREATED_FIELD'), ), ); } }
файл /include.php
Файл необходим для подключения классов или дополнительных файлов модуля. Если соблюдать соответствие namespace и имени модуля, то поддерживается автозагрузка класса. Автозагрузка работает, по инфомации от 1С:Битрикс медленнее, чем поключение файла в include.php. Для примера загрузим класс test.php без автозагрузки:
<?php Bitrix\Main\Loader::registerAutoloadClasses( "brainkit.d7", array( "Brainkit\\D7\\Test" => "lib/test.php", ) );
Запуск модуля
Для того что бы протестировать и запустить наш модуль мы должны:
- установить модуль в административном интерфейсе
- добавить 1 запись в тестовую таблицу brainkit_test
- создать тестовую страницу, например, /test/index.php в корне сайта со следующим содержимым:
<? require($_SERVER['DOCUMENT_ROOT'].'/bitrix/header.php'); $APPLICATION->SetTitle("test"); ?><? if (CModule::IncludeModule("brainkit.d7")){ Brainkit\D7\Test::get(); } ?><? require($_SERVER['DOCUMENT_ROOT'].'/bitrix/footer.php'); ?>
если необходимо протестировать автозагрузку классов, то в файле include.php нужно закомментировать строку, которая подключает наш класс и запустить тестовую страницу снова
Вывод
Структура файлов модуля D7 не отличается от обычного модуля, отличается подход к разработке, код делается более структурированный, используется namespace, для отдельных таблиц мы не пишем отдельные запросы, а реализуем ORM, и при правильной организации кода, мы можем обойтись без файла include.php.