ORM для встроенных модулей
Пока еще модули Topic, Comment, User… не являются наследниками ORM классов, а зачастую хочется использовать преимущества ORM в плагинах, дополняющих данные модули. Скажем релейшены.
Конечно, можно отредактировать класс модуля жестко:
заменить
на
Только придется прописывать еще в методе Init():
+ сделать тоже самое для сущностей.
Согласитесь, каждый раз при развертывании проекта выполнять эти манипуляции совсем неинтересно. Да и в итоге можно забыть, где и что менять. При чем, при обновлении модуля придется все вставлять заново.
Поэтому возникла идея, чтобы сделать это в плагине.
Итак. К примеру, нам нужно сделать, чтобы в плагине можно было пользоваться ORM для Topic.
Для этого создаем два модуля с сущностями:
1) Модуль плагина переопределения классов Topic
2) Сущность переопределения для сущности Topic
3) Модуль обертки для ORM
4) Сущность обертки для ORM
В последний будем записывать все отношения.
В конфиг обязательно вставить таблицу для сущности, идентичную таблице топика:
Как всё работает.
Если будет запрошен какой-то незнакомый метод модуля Topic (например, Topic_GetTopicItemsbyTitleLike()), то магический метод __call перехватит его и попытается вызвать данный метод, но уже ORM модуля обертки.
Теперь в других ORM модулях вашего плагина можно смело указывать отношение с ModuleTopic_EntityTopic
Сама ORM сущность может быть вызвана так.
Сейчас разрабатываю плагин всевозможных дополнительных полей и характеристик к топику без единого запроса, где активно тестирую сей код.
Если будут изменения в коде при каких-либо ошибках, буду обновлять данный пост
Конечно, можно отредактировать класс модуля жестко:
заменить
extends Module
на
extends ModuleORM
Только придется прописывать еще в методе Init():
parent::Init();
+ сделать тоже самое для сущностей.
Согласитесь, каждый раз при развертывании проекта выполнять эти манипуляции совсем неинтересно. Да и в итоге можно забыть, где и что менять. При чем, при обновлении модуля придется все вставлять заново.
Поэтому возникла идея, чтобы сделать это в плагине.
Итак. К примеру, нам нужно сделать, чтобы в плагине можно было пользоваться ORM для Topic.
Для этого создаем два модуля с сущностями:
1) Модуль плагина переопределения классов Topic
<?php
/**
* Модуль топиков
*
*/
class PluginOrm_ModuleTopic extends PluginOrm_Inherit_ModuleTopic {
public function __call($sMethod,$aParams) {
try {
return parent::__call($sMethod,$aParams);
} catch (Exception $e) {
if (preg_match("/{$sMethod}/",$e->getMessage())) {
$sEntityShortName = preg_replace('/(.+_)*Module([^_]+)(_.+)*/','$2',__CLASS__);
$sMethod = str_replace($sEntityShortName,$sEntityShortName.'wrapper',$sMethod);
return call_user_func_array(array($this,"PluginOrm_Topicwrapper_$sMethod"), $aParams);
}
}
return;
}
}
?>
2) Сущность переопределения для сущности Topic
<?php
class PluginOrm_ModuleTopic_EntityTopic extends PluginOrm_Inherit_ModuleTopic_EntityTopic {
protected $oEntityORM = null;
public function getORM() {
if (!$this->oEntityORM) {
$this->oEntityORM = LS::GetEntity('PluginOrm_Topicwrapper_Topicwrapper');
$aData = array_intersect_key(
$this->_aData,
array_flip($this->oEntityORM->_getFields())
);
$this->oEntityORM->_setData($aData);
}
return $this->oEntityORM;
}
}
?>
3) Модуль обертки для ORM
<?php
/**
* Модуль топиков для совместимости ORM
*
*/
class PluginOrm_ModuleTopicwrapper extends ModuleORM {
}
?>
4) Сущность обертки для ORM
<?php
class PluginOrm_ModuleTopicwrapper_EntityTopicwrapper extends EntityORM {
protected $aRelations = array (
'property_values' => array (
self::RELATION_TYPE_MANY_TO_MANY,
'PluginOrm_ModuleProperty_EntityPropertyValue',
'property_value_id',
'db.table.property_value_topic',
'topic_id'
),
);
}
?>
В последний будем записывать все отношения.
В конфиг обязательно вставить таблицу для сущности, идентичную таблице топика:
Config::Set('db.table.topicwrapper', '___db.table.prefix___topic');
Как всё работает.
Если будет запрошен какой-то незнакомый метод модуля Topic (например, Topic_GetTopicItemsbyTitleLike()), то магический метод __call перехватит его и попытается вызвать данный метод, но уже ORM модуля обертки.
Теперь в других ORM модулях вашего плагина можно смело указывать отношение с ModuleTopic_EntityTopic
Сама ORM сущность может быть вызвана так.
$oTopicORM=$oTopic->getORM();
Сейчас разрабатываю плагин всевозможных дополнительных полей и характеристик к топику без единого запроса, где активно тестирую сей код.
Если будут изменения в коде при каких-либо ошибках, буду обновлять данный пост
7 комментариев
Сейчас доступны только односложные названия
Пробывал
выбивало:
В самом Engine везде strtolower() используются вместо func_underscore() для классов
Версия 5.1
Для самих названий плагина работает, а для названий модулей нет:
Есть, конечно, вопросы. Например, ActiveRecord пока неполноценен и работает через
При сохранении или удалении в ORM происходит проверка на связи.
Поэтому после встроенного метода сохранения необходимо еще вызывать ORM-ский.
Собственно, всё это делалось для того, чтобы можно было строить отношения с ORM сторонних модулей к модулям без ORM.