Не смотря на то, что модуль с поддержкой ORM разработчики битрикса анонсировали ещё в конце прошлого года, и того, что этот модуль заявлен в списке доступных в практически всех редакциях, реально его пока что нет в комплекте, как нет по нему и документации. Оставим за кадром неэтичность включения отсутствующих фич в описание продукта в разделе покупки, вернемся к ORM. Раз его нет — почему бы не реализовать нечто подобное самостоятельно?
Для нетерпеливых — сразу дам ссылку на исходники модуля, на GitHub'е. Это как-бы прототип — потому что имеет некоторые проблемы, да и не все моменты решены красиво, но тем не менее, он уже работает. Так что всё-таки наш продукт. Хоть и прототип. На написание кода ушло менее 4х часов, со всеми вытекающими.
Полезности
- Реализован механизм создания объектов нужных классов через фабрику.
$item=new ORM(5); //создаем объект инфоблока с номером 5 $item=ORM::Factory(5); //аналогично $item=new ORM("news"); //создаем объект инфоблока с CODE=news $item=ORM::Factory("news"); //сначала будет попытка создать объект класса newsBitrixOrm или NewsBitrixOrm, если таковой не будет найдет - попытка создать объект инфоблока с CODE=news
- Есть поддержка сеттеров и геттеров, автоматически применяемых при работе с полями.
class NewsBitrixORM extends ORM{ protected $IBlockID=1; protected $auto_getters = array("NAME"=>"GetNameValue"); protected $auto_setters = array("NAME"=>"SetNameValue"); public function GetNameValue($value){ return str_replace(" (имя новости!)", "", $this->_data["NAME"]); } public function SetNameValue($value){ $this->_data["NAME"]=$value." (имя новости!)"; $this->_changed_fields["NAME"]="NAME"; return true; } }
- Реализованы все базовые действия (создание, удаление, изменение, поиск по различным фильтрам).
$ormNews = ORM::Factory(4); $list=$ormNews->Where("WIDTH","=","140")->FindAll(); foreach ($list as $_news){ $_news->NAME="Новость с номером {$_news->ID}"; $_news->WIDTH=24; echo "<pre>".print_r($_news->AsArray(true),true)."</pre>"; if ($_news->ID%2==0) $_news->Delete(); else { $_news->NAME.=" [обновлена!]"; $_news->Save(); } }
- Работа как со стандартными полями, так и с пользовательскими свойствами идет совершенно одинаково.
- Есть своя особенность при работе с полями типа «список». Например, у нас есть свойство
COLOR
. При работе с ним будет видно два поля —COLOR
, содержащее текстовое значение выбранного элемента списка, иCOLOR__ID
(два подчеркивания), содержащее ID выбранного варианта. Для изменения значения нужно назначить ему ID другого варианта списка (например$item->ID=5
), при этом автоматическиCOLOR__ID
получит это значение, аCOLOR
— изменит текстовое значение.
Недостатки
- некоторое уменьшение скорости. Работает с уже существующим API для работы с данными инфоблоков, а не напрямую с базой. С другой стороны, эти части можно и переписать, после чего весь код, завязанный на данную ORM продолжит работать
- работает исключительно с элементами (не с папками)
- отсутствуют нормальные механизмы для сложных запросов со вложениями запросами, с OR-запросами.
- отсутствует возможность наполнять свойства-массивы (множественные свойства) запросом вида $obj->item[]=«значение»; Вместо него пока приходится использовать AddToArrayValue(«item»,«значение»). Как обойти этот момент, пока что не придумал.
- отсутствует решения для создания зависимостей между инфоблоками (один к одному, один ко многим и т.п.)
Автор: Newbilius