Объекты ORM, утилита генерации
С 18 версии в ORM Битрикс появились объекты.
О работе с объектами подробно можно узнать из курса
А также из видео партнерских конференций:
https://youtu.be/QmAf1xxkX0Q
https://youtu.be/mnX8oeE_lO0
Класс объекта создается в процессе выполнения кода, а практически все методы основываются на «магических» методах (__call, __get).
В результате чего IDE (например, phpStorm) будет считать обращение к таким методам ошибкой, а также не будет выводить подсказки. Для решения проблемы был выпущен bitrix cli с поддержкой команды orm:annotate. Инструмент предназначен для работы через командную строку, требует наличия библиотеки symfony/console (устанавливается через composer).
Процесс установки описан в курсе:
https://dev.1c-bitrix.ru/learning/course/index.php?COURSE_ID=43&LESSON_ID=4637
В этом же курсе приведены примеры использования:
https://dev.1c-bitrix.ru/learning/course/index.php?COURSE_ID=43&LESSON_ID=11733
В результате вызова команды orm:annotate мы получаем файл /bitrix/modules/orm_annotations.php который содержит описание всех генерируемых классов ORM в формате phpdoc, IDE видит этот файл (если он находится в рамках проекта) и начинает выводить все необходимые подсказки.
Правила генерации
Аннотация генерируется только для классов, которые заканчиваются на Table и являются наследниками класса \Bitrix\Main\ORM\Data\DataManager (либо его алиаса для старых версий Bitrix\Main\Entity\DataManager).
Поиск классов, соответствующих указанным правилам, осуществляется в нескольких местах:
php bitrix.php orm:annotate -m tasks forum
/bitrix/modules/tasks/lib/Если директория не существует, то она исключается из списка. Далее для каждой директории:
/bitrix/modules/tasks/dev/lib/
/local/modules/forum/lib/
/local/modules/forum/dev/lib/
php bitrix.php orm:annotate -m tasksБудет вызвано только событие, которое зарегистрировал модуль tasks.
Ограничение
В соответствии с описанным выше, аннотация классов не будет сгенерирована в случае, если классы системы не принадлежат модулям и подключаются, например, по psr-4 через composer или через \Bitrix\Main\ Loader::registerAutoLoadClasses(null, …)
Событие onVirtualClassBuildList
Далее приведен упрощенный пример, как можно использовать событие.
Добавляем класс:
namespace Pixelplus\OrmAnnotations; use Bitrix\Main\EventManager; class Handlers { public static function onVirtualClassBuildList() { //Основной код } public static function registerHandler() { EventManager::getInstance()->registerEventHandler( 'main', 'onVirtualClassBuildList', 'main', self::class, 'onVirtualClassBuildList' ); } }
Разово вызываем метод
\Pixelplus\OrmAnnotations\Handlers::registerHandler().Для отдельного модуля это можно сделать при установке, в качестве toModuleId указывая свой модуль.
Внутри метода \Pixelplus\OrmAnnotations\Handlers::onVirtualClassBuildList
Для классов без модуля, зарегистрированных через Bitrix\Main\Loader::registerAutoLoadClasses, вызываем class_exists, таким образом они попадают в get_declared_classes(). Альтернативный вариант – где-то сохранить список классов, добавляемых в загрузчик.
$rp = new \ReflectionProperty('Bitrix\Main\Loader', 'arAutoLoadClasses'); $rp->setAccessible(true); $classes = $rp->getValue(); $rp->setAccessible(false); foreach ($classes as $class => $classData) { if (!$classData['module']) { class_exists($class); } }
Для классов, загруженных через composer по psr-4
(например такого)
if (class_exists('\Composer\Autoload\ClassMapGenerator')) { $composerJsonFile = $_SERVER['DOCUMENT_ROOT'].'/local/composer.json'; $map = []; if (file_exists($composerJsonFile)) { $jsonContent = json_decode(file_get_contents($composerJsonFile), true); if (array_key_exists('psr-4', $jsonContent['autoload'])) { foreach (['psr-4', 'psr-0'] as $psrType) { foreach ($jsonContent['autoload'][$psrType] as $path) { if (substr($path, 0, 1) != '/') { $path = dirname($composerJsonFile).'/'.$path; } $map = array_merge($map, array_keys(\Composer\Autoload\ClassMapGenerator::createMap( $path ))); } } } } foreach ($map as $class) { class_exists($class); } }где $composerJsonFile - полный путь к файлу composer.json
Таким образом все наши дополнительные классы попадут в файл аннотаций
Комментариев пока что нет
Входим в число лучших компаний России в сферах интернет-рекламы и разработки сайтов по результатам самых авторитетных рейтингов
Нужна помощь с сайтом? Заполните форму, и наши менеджеры проконсультируют вас уже сегодня!
Уникальный тариф «Оборот», где доход агентства больше не зависит от визитов и позиций вашего сайта, а привязан исключительно к росту оборота вашей компании.
Тариф, который хотели сделать многие, но реализовали только мы.