mirror of
https://github.com/Oreolek/ifhub.club.git
synced 2024-07-01 14:05:07 +03:00
Доработка MANY_TO_MANY связей
This commit is contained in:
parent
a29dc1735e
commit
4e2dde7dc5
|
@ -32,6 +32,8 @@ require_once("ModuleORM.class.php");
|
||||||
require_once("EntityORM.class.php");
|
require_once("EntityORM.class.php");
|
||||||
require_once("MapperORM.class.php");
|
require_once("MapperORM.class.php");
|
||||||
|
|
||||||
|
require_once("ManyToManyRelation.class.php");
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Основной класс движка, который позволяет напрямую обращаться к любому модулю
|
* Основной класс движка, который позволяет напрямую обращаться к любому модулю
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
*/
|
*/
|
||||||
abstract class Entity extends Object {
|
abstract class Entity extends Object {
|
||||||
protected $_aData=array();
|
protected $_aData=array();
|
||||||
|
protected $sPrimaryKey = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Если передать в конструктор ассоциативный массив свойств и их значений, то они автоматом загрузятся в сущность
|
* Если передать в конструктор ассоциативный массив свойств и их значений, то они автоматом загрузятся в сущность
|
||||||
|
@ -88,5 +89,26 @@ abstract class Entity extends Object {
|
||||||
return Engine::getInstance()->_CallModule($sName,$aArgs);
|
return Engine::getInstance()->_CallModule($sName,$aArgs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Получение первичного ключа сущности (ключ, а не значение!)
|
||||||
|
*/
|
||||||
|
public function _getPrimaryKey()
|
||||||
|
{
|
||||||
|
if (!$this->sPrimaryKey) {
|
||||||
|
if (isset($this->_aData['id'])) {
|
||||||
|
$this->sPrimaryKey = 'id';
|
||||||
|
} else {
|
||||||
|
// Получение primary_key из схемы бд (пока отсутствует)
|
||||||
|
$this->sPrimaryKey = 'id';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->sPrimaryKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function _getPrimaryKeyValue() {
|
||||||
|
return $this->_getDataOne($this->_getPrimaryKey());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
?>
|
?>
|
|
@ -33,6 +33,9 @@ abstract class EntityORM extends Entity {
|
||||||
|
|
||||||
protected $aRelations=array();
|
protected $aRelations=array();
|
||||||
protected $aRelationsData=array();
|
protected $aRelationsData=array();
|
||||||
|
|
||||||
|
// Объекты связей many_to_many
|
||||||
|
protected $_aManyToManyRelations = array();
|
||||||
|
|
||||||
protected $sPrimaryKey='id';
|
protected $sPrimaryKey='id';
|
||||||
protected $bIsNew=true;
|
protected $bIsNew=true;
|
||||||
|
@ -55,6 +58,10 @@ abstract class EntityORM extends Entity {
|
||||||
}
|
}
|
||||||
return $this->sPrimaryKey;
|
return $this->sPrimaryKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function _getPrimaryKeyValue() {
|
||||||
|
return $this->_getDataOne($this->_getPrimaryKey());
|
||||||
|
}
|
||||||
|
|
||||||
public function _isNew() {
|
public function _isNew() {
|
||||||
return $this->bIsNew;
|
return $this->bIsNew;
|
||||||
|
@ -283,7 +290,7 @@ abstract class EntityORM extends Entity {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __call($sName,$aArgs) {
|
public function __call($sName,$aArgs) {
|
||||||
$sType=substr($sName,0,strpos(func_underscore($sName),'_'));
|
$sType=substr($sName,0,strpos(func_underscore($sName),'_'));
|
||||||
if (!strpos($sName,'_') and in_array($sType,array('get','set','reload'))) {
|
if (!strpos($sName,'_') and in_array($sType,array('get','set','reload'))) {
|
||||||
$sKey=func_underscore(str_replace($sType,'',$sName));
|
$sKey=func_underscore(str_replace($sType,'',$sName));
|
||||||
if ($sType=='get') {
|
if ($sType=='get') {
|
||||||
|
@ -326,7 +333,6 @@ abstract class EntityORM extends Entity {
|
||||||
}
|
}
|
||||||
|
|
||||||
$iPrimaryKeyValue=$this->_getDataOne($this->_getPrimaryKey());
|
$iPrimaryKeyValue=$this->_getDataOne($this->_getPrimaryKey());
|
||||||
|
|
||||||
$sCmd='';
|
$sCmd='';
|
||||||
$aCmdArgs=array();
|
$aCmdArgs=array();
|
||||||
switch ($sRelationType) {
|
switch ($sRelationType) {
|
||||||
|
@ -345,10 +351,11 @@ abstract class EntityORM extends Entity {
|
||||||
case self::RELATION_TYPE_MANY_TO_MANY :
|
case self::RELATION_TYPE_MANY_TO_MANY :
|
||||||
$sCmd="{$sRelPluginPrefix}Module{$sRelModuleName}_get{$sRelEntityName}ItemsByJoinTable";
|
$sCmd="{$sRelPluginPrefix}Module{$sRelModuleName}_get{$sRelEntityName}ItemsByJoinTable";
|
||||||
$aCmdArgs[0]=array(
|
$aCmdArgs[0]=array(
|
||||||
'#join_table' => $sRelationJoinTable,
|
'#join_table' => Config::Get($sRelationJoinTable),
|
||||||
'#relation_key' => $sRelationKey,
|
'#relation_key' => $sRelationKey,
|
||||||
'#by_key' => $sRelationJoinTableKey,
|
'#by_key' => $sRelationJoinTableKey,
|
||||||
'#by_value' => $iPrimaryKeyValue,
|
'#by_value' => $iPrimaryKeyValue,
|
||||||
|
'#index-from-primary' => true // Для MANY_TO_MANY необходимо индексами в $aRelationsData иметь первичные ключи сущностей
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -360,6 +367,10 @@ abstract class EntityORM extends Entity {
|
||||||
$res=Engine::GetInstance()->_CallModule($sCmd,$aCmdArgs);
|
$res=Engine::GetInstance()->_CallModule($sCmd,$aCmdArgs);
|
||||||
|
|
||||||
$this->aRelationsData[$sKey]=$res;
|
$this->aRelationsData[$sKey]=$res;
|
||||||
|
// Создаём объекты-обёртки для связей MANY_TO_MANY
|
||||||
|
if ($sRelationType == self::RELATION_TYPE_MANY_TO_MANY) {
|
||||||
|
$this->_aManyToManyRelations[$sKey] = new LS_ManyToManyRelation($this->aRelationsData[$sKey]);
|
||||||
|
}
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -380,5 +391,25 @@ abstract class EntityORM extends Entity {
|
||||||
return Engine::getInstance()->_CallModule($sName,$aArgs);
|
return Engine::getInstance()->_CallModule($sName,$aArgs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function __get($sName)
|
||||||
|
{
|
||||||
|
// Обработка обращений к обёрткам связей MANY_TO_MANY
|
||||||
|
// Если связь загружена, возвращаем объект связи
|
||||||
|
var_dump(($this->aRelations[strtolower($sName)]));
|
||||||
|
if (isset($this->_aManyToManyRelations[strtolower($sName)])) {
|
||||||
|
return $this->_aManyToManyRelations[strtolower($sName)];
|
||||||
|
// Есл не загружена, но связь с таким именем существет, пробуем загрузить и вернуть объект связи
|
||||||
|
} elseif (isset($this->aRelations[strtolower($sName)]) && $this->aRelations[strtolower($sName)][0] == self::RELATION_TYPE_MANY_TO_MANY) {
|
||||||
|
$sMethod = 'get' . ucfirst($sName);
|
||||||
|
$this->__call($sMethod, array());
|
||||||
|
if (isset($this->_aManyToManyRelations[strtolower($sName)])) {
|
||||||
|
return $this->_aManyToManyRelations[strtolower($sName)];
|
||||||
|
}
|
||||||
|
// В противном случае возвращаем то, что просили у объекта
|
||||||
|
} else {
|
||||||
|
return $this->$sName;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
?>
|
?>
|
46
engine/classes/ManyToManyRelation.class.php
Normal file
46
engine/classes/ManyToManyRelation.class.php
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Класс. представляющий собой обёертку для связей MANY_TO_MANY.
|
||||||
|
* Позволяет оперровать коллекцией загруженных по связи эдементов через имя связи
|
||||||
|
* Например, $oTopic->Tags->add($oTag) или $oTopic->Tags->delete($oTag->getId()) при
|
||||||
|
* наличии настроенной MANY_TO_MANY связи 'tags'
|
||||||
|
*/
|
||||||
|
class LS_ManyToManyRelation
|
||||||
|
{
|
||||||
|
// Ссылка на $oEntityORM->aRelationsData[<relation_name>],
|
||||||
|
// где relation_name - имя сязи, которую представляет объект
|
||||||
|
protected $_aCollection = array();
|
||||||
|
|
||||||
|
public function __construct(&$aCollection)
|
||||||
|
{
|
||||||
|
$this->_aCollection = &$aCollection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Добавление объекта в коллекцию
|
||||||
|
* @param <type> $oEntity
|
||||||
|
*/
|
||||||
|
public function add($oEntity)
|
||||||
|
{
|
||||||
|
$this->_aCollection[$oEntity->_getPrimaryKeyValue()] = $oEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Удаление объекта из коллекции по его id или массиву id
|
||||||
|
* @param <type> $iId
|
||||||
|
*/
|
||||||
|
public function delete($iId)
|
||||||
|
{
|
||||||
|
if (is_array($iId)) {
|
||||||
|
foreach ($iId as $id) {
|
||||||
|
if (isset($this->_aCollection[$id])) {
|
||||||
|
unset($this->_aCollection[$id]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} elseif (isset($this->_aCollection[$iId])) {
|
||||||
|
unset($this->_aCollection[$iId]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
|
@ -261,5 +261,68 @@ class MapperORM extends Mapper {
|
||||||
return Config::Get('db.table.prefix').$sTable;
|
return Config::Get('db.table.prefix').$sTable;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Загрузка данных из таблицы связи many_to_many
|
||||||
|
* @param <type> $sDbTableAlias Алиас имени таблицы связи
|
||||||
|
* @param <type> $sEntityKey Название поля в таблице связи с id сущности, для которой зегружаются объекты.
|
||||||
|
* @param <type> $iEntityId Id сущнсоти, для который загружаются объекты
|
||||||
|
* @param <type> $sRelationKey Название поля в таблице связи с id сущности, объекты которой загружаются по связи.
|
||||||
|
* @return <type> список id из столбца $sRelationKey, у которых столбец $sEntityKey = $iEntityId
|
||||||
|
*/
|
||||||
|
public function getManyToManySet($sDbTableAlias, $sEntityKey, $iEntityId, $sRelationKey)
|
||||||
|
{
|
||||||
|
if (!Config::Get($sDbTableAlias)) return array();
|
||||||
|
$sql = 'SELECT ?# FROM '.Config::Get($sDbTableAlias).' WHERE ?# = ?d';
|
||||||
|
return $this->oDb->selectCol($sql, $sRelationKey, $sEntityKey, $iEntityId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Обновление связи many_to_many
|
||||||
|
* @param <type> $sDbTableAlias Алиас имени таблицы связи
|
||||||
|
* @param <type> $sEntityKey Название поля в таблице связи с id сущности, для которой обновляются связи.
|
||||||
|
* @param <type> $iEntityId Id сущнсоти, для который обновляются связи
|
||||||
|
* @param <type> $sRelationKey Название поля в таблице связи с id сущности, с объектами которой назначаются связи.
|
||||||
|
* @param <type> $aInsertSet Массив id для $sRelationKey, которые нужно добавить
|
||||||
|
* @param <type> $aDeleteSet Массив id для $sRelationKey, которые нужно удалить
|
||||||
|
* @return <type>
|
||||||
|
*/
|
||||||
|
public function updateManyToManySet($sDbTableAlias, $sEntityKey, $iEntityId, $sRelationKey, $aInsertSet, $aDeleteSet)
|
||||||
|
{
|
||||||
|
if (!Config::Get($sDbTableAlias)) return false;
|
||||||
|
if (count($aDeleteSet)) {
|
||||||
|
$sql = 'DELETE FROM '.Config::Get($sDbTableAlias).' WHERE ?# = ?d AND ?# IN (?a)';
|
||||||
|
$this->oDb->query($sql, $sEntityKey, $iEntityId, $sRelationKey, $aDeleteSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($aInsertSet)) {
|
||||||
|
$sql = 'INSERT INTO '.Config::Get($sDbTableAlias).' (?#,?#) VALUES ';
|
||||||
|
$aParams = array();
|
||||||
|
foreach ($aInsertSet as $iId) {
|
||||||
|
$sql .= '(?d, ?d), ';
|
||||||
|
$aParams[] = $iEntityId;
|
||||||
|
$aParams[] = $iId;
|
||||||
|
}
|
||||||
|
$sql = substr($sql, 0, -2); // удаление последних ", "
|
||||||
|
call_user_func_array(array($this->oDb, 'query'), array_merge(array($sql,$sEntityKey, $sRelationKey), $aParams));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Удаление связей many_to_many для объекта. Используется при удалении сущности,
|
||||||
|
* чтобы не удалять большие коллекции связанных объектов через updateManyToManySet(),
|
||||||
|
* где используется IN.
|
||||||
|
*
|
||||||
|
* @param <type> $sDbTableAlias Алиас имени таблицы связи
|
||||||
|
* @param <type> $sEntityKey Название поля в таблице связи с id сущности, для которой удаляются связи.
|
||||||
|
* @param <type> $iEntityId Id сущнсоти, для который удаляются связи
|
||||||
|
* @return <type>
|
||||||
|
*/
|
||||||
|
public function deleteManyToManySet($sDbTableAlias, $sEntityKey, $iEntityId)
|
||||||
|
{
|
||||||
|
if (!Config::Get($sDbTableAlias)) return false;
|
||||||
|
$sql = 'DELETE FROM '.Config::Get($sDbTableAlias).' WHERE ?# = ?d';
|
||||||
|
$this->oDb->query($sql, $sEntityKey, $iEntityId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
?>
|
?>
|
|
@ -45,6 +45,13 @@ abstract class ModuleORM extends Module {
|
||||||
} elseif ($res) {
|
} elseif ($res) {
|
||||||
// есть автоинкремент, устанавливаем его
|
// есть автоинкремент, устанавливаем его
|
||||||
$oEntity->_setData(array($oEntity->_getPrimaryKey() => $res));
|
$oEntity->_setData(array($oEntity->_getPrimaryKey() => $res));
|
||||||
|
// Обновление связей many_to_many
|
||||||
|
$aRelationsData = $oEntity->_getRelationsData();
|
||||||
|
foreach ($oEntity->_getRelations() as $sRelName => $aRelation) {
|
||||||
|
if ($aRelation[0] == EntityORM::RELATION_TYPE_MANY_TO_MANY) {
|
||||||
|
$this->_updateManyToManySet($aRelation, $aRelationsData[$sRelName], $oEntity->_getDataOne($oEntity->_getPrimaryKey()));
|
||||||
|
}
|
||||||
|
}
|
||||||
return $oEntity;
|
return $oEntity;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -52,7 +59,15 @@ abstract class ModuleORM extends Module {
|
||||||
|
|
||||||
protected function _UpdateEntity($oEntity) {
|
protected function _UpdateEntity($oEntity) {
|
||||||
$res=$this->oMapperORM->UpdateEntity($oEntity);
|
$res=$this->oMapperORM->UpdateEntity($oEntity);
|
||||||
|
|
||||||
if ($res===0 or $res) { // запись не изменилась, либо изменилась
|
if ($res===0 or $res) { // запись не изменилась, либо изменилась
|
||||||
|
// Обновление связей many_to_many
|
||||||
|
$aRelationsData = $oEntity->_getRelationsData();
|
||||||
|
foreach ($oEntity->_getRelations() as $sRelName => $aRelation) {
|
||||||
|
if ($aRelation[0] == EntityORM::RELATION_TYPE_MANY_TO_MANY) {
|
||||||
|
$this->_updateManyToManySet($aRelation, $aRelationsData[$sRelName], $oEntity->_getDataOne($oEntity->_getPrimaryKey()));
|
||||||
|
}
|
||||||
|
}
|
||||||
// сбрасываем кеш
|
// сбрасываем кеш
|
||||||
$sEntity=$this->Plugin_GetRootDelegater('entity',get_class($oEntity));
|
$sEntity=$this->Plugin_GetRootDelegater('entity',get_class($oEntity));
|
||||||
$this->Cache_Clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG,array($sEntity.'_save'));
|
$this->Cache_Clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG,array($sEntity.'_save'));
|
||||||
|
@ -75,6 +90,15 @@ abstract class ModuleORM extends Module {
|
||||||
// сбрасываем кеш
|
// сбрасываем кеш
|
||||||
$sEntity=$this->Plugin_GetRootDelegater('entity',get_class($oEntity));
|
$sEntity=$this->Plugin_GetRootDelegater('entity',get_class($oEntity));
|
||||||
$this->Cache_Clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG,array($sEntity.'_delete'));
|
$this->Cache_Clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG,array($sEntity.'_delete'));
|
||||||
|
|
||||||
|
// Обновление связей many_to_many
|
||||||
|
$aRelationsData = $oEntity->getRelationsData();
|
||||||
|
foreach ($oEntity->_getRelations() as $sRelName => $aRelation) {
|
||||||
|
if ($aRelation[0] == EntityORM::RELATION_TYPE_MANY_TO_MANY) {
|
||||||
|
$this->_deleteManyToManySet($aRelation[3], $aRelation[4], $oEntity->_getPrimaryKeyValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return $oEntity;
|
return $oEntity;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -316,18 +340,29 @@ abstract class ModuleORM extends Module {
|
||||||
* Returns assotiative array, indexed by PRIMARY KEY or another field.
|
* Returns assotiative array, indexed by PRIMARY KEY or another field.
|
||||||
*/
|
*/
|
||||||
if (in_array('#index-from-primary', $aFilter) || !empty($aFilter['#index-from'])) {
|
if (in_array('#index-from-primary', $aFilter) || !empty($aFilter['#index-from'])) {
|
||||||
$aIndexedEntities=array();
|
$aEntities = $this->_setIndexesFromField($aEntities, $aFilter);
|
||||||
foreach ($aEntities as $oEntity) {
|
|
||||||
$sKey = in_array('#index-from-primary', $aFilter) || ( !empty($aFilter['#index-from']) && $aFilter['#index-from'] == '#primary' ) ?
|
|
||||||
$oEntity->_getPrimaryKey() :
|
|
||||||
$oEntity->_getField($aFilter['#index-from']);
|
|
||||||
$aIndexedEntities[$oEntity->_getDataOne($sKey)]=$oEntity;
|
|
||||||
}
|
|
||||||
$aEntities = $aIndexedEntities;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $aEntities;
|
return $aEntities;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns assotiative array, indexed by PRIMARY KEY or another field.
|
||||||
|
* @param <type> $oEntity
|
||||||
|
* @param <type> $aFilter
|
||||||
|
* @return <type>
|
||||||
|
*/
|
||||||
|
protected function _setIndexesFromField($aEntities, $aFilter)
|
||||||
|
{
|
||||||
|
$aIndexedEntities=array();
|
||||||
|
foreach ($aEntities as $oEntity) {
|
||||||
|
$sKey = in_array('#index-from-primary', $aFilter) || ( !empty($aFilter['#index-from']) && $aFilter['#index-from'] == '#primary' ) ?
|
||||||
|
$oEntity->_getPrimaryKey() :
|
||||||
|
$oEntity->_getField($aFilter['#index-from']);
|
||||||
|
$aIndexedEntities[$oEntity->_getDataOne($sKey)]=$oEntity;
|
||||||
|
}
|
||||||
|
return $aIndexedEntities;
|
||||||
|
}
|
||||||
|
|
||||||
public function GetCountItemsByFilter($aFilter=array(),$sEntityFull=null) {
|
public function GetCountItemsByFilter($aFilter=array(),$sEntityFull=null) {
|
||||||
if (is_null($sEntityFull)) {
|
if (is_null($sEntityFull)) {
|
||||||
|
@ -359,7 +394,13 @@ abstract class ModuleORM extends Module {
|
||||||
} elseif (!substr_count($sEntityFull,'_')) {
|
} elseif (!substr_count($sEntityFull,'_')) {
|
||||||
$sEntityFull=Engine::GetPluginPrefix($this).'Module'.Engine::GetModuleName($this).'_Entity'.$sEntityFull;
|
$sEntityFull=Engine::GetPluginPrefix($this).'Module'.Engine::GetModuleName($this).'_Entity'.$sEntityFull;
|
||||||
}
|
}
|
||||||
return $this->oMapperORM->GetItemsByJoinTable($aJoinData,$sEntityFull);
|
$aEntities = $this->oMapperORM->GetItemsByJoinTable($aJoinData,$sEntityFull);
|
||||||
|
|
||||||
|
if (in_array('#index-from-primary', $aJoinData) || !empty($aJoinData['#index-from'])) {
|
||||||
|
$aEntities = $this->_setIndexesFromField($aEntities, $aJoinData);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $aEntities;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __call($sName,$aArgs) {
|
public function __call($sName,$aArgs) {
|
||||||
|
@ -513,5 +554,56 @@ abstract class ModuleORM extends Module {
|
||||||
}
|
}
|
||||||
return $aList;
|
return $aList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Обновление связи many_to_many в бд
|
||||||
|
* @param <type> $aRelation Соответствующий связи элемент массива из $oEntityORM->aRelations
|
||||||
|
* @param <type> $aRelationData Соответствующий связи элемент массива из $oEntityORM->aRelationsData
|
||||||
|
* @param <type> $iEntityId Id сущности, для которой обновляются связи
|
||||||
|
* @return <type>
|
||||||
|
*/
|
||||||
|
protected function _updateManyToManySet($aRelation, $aRelationData, $iEntityId)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Описание параметров связи many_to_many
|
||||||
|
* Для примера возьмём такую связь в сущности $oTopic
|
||||||
|
* 'tags' => array(self::RELATION_TYPE_MANY_TO_MANY,'ModuleTopic_EntityTag', 'tag_id', 'db.table.topic_tag_rel', 'topic_id'),
|
||||||
|
* И используется таблица связи
|
||||||
|
* table prefix_topic_tag_rel
|
||||||
|
* topic_id | ефп_id
|
||||||
|
* Тогда тут
|
||||||
|
* [0] -> self::RELATION_TYPE_MANY_TO_MANY - тип связи
|
||||||
|
* [1] -> 'ModuleTopic_EntityTag' - имя сущности объектов связи
|
||||||
|
* [2] -> 'tag_id' - названия столбца в таблице связи, в котором содержатся id объектов связи, в нашем случае тегов.
|
||||||
|
* [3] -> 'db.table.topic_tag_rel' - алиас (идентификатор из конфига) таблицы связи.
|
||||||
|
* Обратите внмание на то, что ORM для определения таблиц сущностей использует модуль и название сущности, то есть
|
||||||
|
* если мы захотим таблицу связи назвать prefix_topic_tag, что, в общем-то, логично, то будет конфликт имён, потому что
|
||||||
|
* ModuleTopic_EntityTag также преобразуется в prefix_topic_tag.
|
||||||
|
* Поэтому необходимо следить за корректным именованием таблиц (точнее алиасов в конфиге, сами таблицы в бд могут
|
||||||
|
* называться как угодно). В данном примере используется суффикс '_rel'.
|
||||||
|
* [4] -> 'topic_id' - название столбца в таблице связи, в котором содержатся id сущности, для которой объявляется связь,
|
||||||
|
* в нашем случае топиков
|
||||||
|
*/
|
||||||
|
$aSavedSet = $this->oMapperORM->getManyToManySet($aRelation[3], $aRelation[4], $iEntityId, $aRelation[2]);
|
||||||
|
$aCurrentSet = array();
|
||||||
|
foreach ($aRelationData as $oEntity) {
|
||||||
|
$aCurrentSet[] = $oEntity->_getDataOne($oEntity->_getPrimaryKey());
|
||||||
|
}
|
||||||
|
if ($aSavedSet == $aCurrentSet) return;
|
||||||
|
$aInsertSet = array_diff($aCurrentSet, $aSavedSet);
|
||||||
|
$aDeleteSet = array_diff($aSavedSet, $aCurrentSet);
|
||||||
|
$this->oMapperORM->updateManyToManySet($aRelation[3], $aRelation[4], $iEntityId, $aRelation[2], $aInsertSet, $aDeleteSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Удаление связи many_to_many в бд
|
||||||
|
* @param <type> $sDbTableAlias Алиас имени таблицы связи
|
||||||
|
* @param <type> $sEntityKey Название поля в таблице связи с id сущности, для которой удаляются связи.
|
||||||
|
* @param <type> $iEntityId Id сущнсоти, для который удаляются связи
|
||||||
|
*/
|
||||||
|
protected function _deleteManyToManySet($sDbTableAlias, $sEntityKey, $iEntityId)
|
||||||
|
{
|
||||||
|
$this->oMapperORM->deleteManyToManySet($sDbTableAlias, $sEntityKey, $iEntityId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
?>
|
?>
|
Loading…
Reference in a new issue