ModuleORM

Package engine.orm
Inheritance abstract class ModuleORM » Module » LsObject
Since 1.0
Source Code /engine/classes/ModuleORM.class.php
Абстракция модуля ORM Предоставляет базовые методы для работы с EntityORM, например,
$aUsers=$this->User_GetUserItemsByAgeAndSex(18,'male');

Protected Properties

Hide inherited properties

PropertyTypeDescriptionDefined By
bIsInit bool Указывает на то, была ли проведенна инициализация модуля Module
oEngine Engine Объект ядра Module
oMapperORM MapperORM Объект маппера ORM ModuleORM

Public Methods

Hide inherited methods

MethodDescriptionDefined By
GetByFilter() Получить сущность по фильтру ModuleORM
GetCountItemsByFilter() Получить количество сущностей по фильтру ModuleORM
GetCountItemsByJoinTable() Получить число сущностей по связанной таблице ModuleORM
GetItemsByArray() Возвращает список сущностей по фильтру ModuleORM
GetItemsByFilter() Получить список сущностей по фильтру ModuleORM
GetItemsByJoinTable() Получить сущности по связанной таблице ModuleORM
Init() Инициализация ModuleORM
LoadTree() Для сущностей со связью RELATION_TYPE_TREE возвращает список сущностей в виде дерева ModuleORM
SetInit() Помечает модуль как инициализированный Module
Shutdown() Метод срабатывает при завершении работы ядра Module
__call() Ставим хук на вызов неизвестного метода и считаем что хотели вызвать метод какого либо модуля. ModuleORM
__construct() При создании модуля передаем объект ядра Module
buildTree() Построение дерева ModuleORM
isInit() Возвращает значение флага инициализации модуля Module

Protected Methods

Hide inherited methods

MethodDescriptionDefined By
_AddEntity() Добавление сущности в БД ModuleORM
_DeleteEntity() Удаление сущности из БД ModuleORM
_GetAncestorsOfEntity() Для сущности со связью RELATION_TYPE_TREE возвращает список всех предков ModuleORM
_GetChildrenOfEntity() Для сущности со связью RELATION_TYPE_TREE возвращает список прямых потомков ModuleORM
_GetDescendantsOfEntity() Для сущности со связью RELATION_TYPE_TREE возвращает список всех потомков ModuleORM
_GetParentOfEntity() Для сущности со связью RELATION_TYPE_TREE возвращает предка ModuleORM
_LoadMapperORM() Загрузка маппера ORM ModuleORM
_ReloadEntity() Обновляет данные сущности из БД ModuleORM
_SaveEntity() Сохранение сущности в БД ModuleORM
_ShowColumnsFrom() Список полей сущности ModuleORM
_ShowPrimaryIndexFrom() Primary индекс сущности ModuleORM
_UpdateEntity() Обновление сущности в БД ModuleORM
__clone() Блокируем копирование/клонирование объекта Module
_deleteManyToManySet() Удаление связи many_to_many в бд ModuleORM
_setIndexesFromField() Returns assotiative array, indexed by PRIMARY KEY or another field. ModuleORM
_updateManyToManySet() Обновление связи many_to_many в бд ModuleORM

Property Details

oMapperORM property
protected MapperORM $oMapperORM;

Объект маппера ORM

Method Details

GetByFilter() method
public EntityORM|null GetByFilter(array $aFilter=array ( ), string $sEntityFull=NULL)
$aFilter array Фильтр
$sEntityFull string Название класса сущности
{return} EntityORM|null
Source Code: /engine/classes/ModuleORM.class.php#343 (show)
public function GetByFilter($aFilter=array(),$sEntityFull=null) {
    if (
is_null($sEntityFull)) {
        
$sEntityFull=Engine::GetPluginPrefix($this).'Module'.Engine::GetModuleName($this).'_Entity'.Engine::GetModuleName(get_class($this));
    } elseif (!
substr_count($sEntityFull,'_')) {
        
$sEntityFull=Engine::GetPluginPrefix($this).'Module'.Engine::GetModuleName($this).'_Entity'.$sEntityFull;
    }
    return 
$this->oMapperORM->GetByFilter($aFilter,$sEntityFull);
}

Получить сущность по фильтру

GetCountItemsByFilter() method
public int GetCountItemsByFilter(array $aFilter=array ( ), string $sEntityFull=NULL)
$aFilter array Фильтр
$sEntityFull string Название класса сущности
{return} int
Source Code: /engine/classes/ModuleORM.class.php#473 (show)
public function GetCountItemsByFilter($aFilter=array(),$sEntityFull=null) {
    if (
is_null($sEntityFull)) {
        
$sEntityFull=Engine::GetPluginPrefix($this).'Module'.Engine::GetModuleName($this).'_Entity'.Engine::GetModuleName(get_class($this));
    } elseif (!
substr_count($sEntityFull,'_')) {
        
$sEntityFull=Engine::GetPluginPrefix($this).'Module'.Engine::GetModuleName($this).'_Entity'.$sEntityFull;
    }
    
// Если параметр #cache указан и пуст, значит игнорируем кэширование для запроса
    
if (array_key_exists('#cache'$aFilter) && !$aFilter['#cache']) {
        
$iCount=$this->oMapperORM->GetCountItemsByFilter($aFilter,$sEntityFull);
    } else {
        
$sEntityFullRoot=$this->Plugin_GetRootDelegater('entity',$sEntityFull);
        
$sCacheKey=$sEntityFullRoot.'_count_items_by_filter_'.serialize($aFilter);
        
$aCacheTags=array($sEntityFullRoot.'_save',$sEntityFullRoot.'_delete');
        
$iCacheTime=60*60*24// скорее лучше хранить в свойстве сущности, для возможности выборочного переопределения
        // переопределяем из параметров
        
if (isset($aFilter['#cache'][0])) $sCacheKey=$aFilter['#cache'][0];
        if (isset(
$aFilter['#cache'][1])) $aCacheTags=$aFilter['#cache'][1];
        if (isset(
$aFilter['#cache'][2])) $iCacheTime=$aFilter['#cache'][2];

        if (
false === ($iCount $this->Cache_Get($sCacheKey))) {
            
$iCount=$this->oMapperORM->GetCountItemsByFilter($aFilter,$sEntityFull);
            
$this->Cache_Set($iCount,$sCacheKey$aCacheTags$iCacheTime);
        }
    }
    return 
$iCount;
}

Получить количество сущностей по фильтру

GetCountItemsByJoinTable() method
public int GetCountItemsByJoinTable(array $aJoinData=array ( ), string $sEntityFull=NULL)
$aJoinData array Фильтр
$sEntityFull string Название класса сущности
{return} int
Source Code: /engine/classes/ModuleORM.class.php#568 (show)
public function GetCountItemsByJoinTable($aJoinData=array(),$sEntityFull=null) {
    if (
is_null($sEntityFull)) {
        
$sEntityFull=Engine::GetPluginPrefix($this).'Module'.Engine::GetModuleName($this).'_Entity'.Engine::GetModuleName(get_class($this));
    } elseif (!
substr_count($sEntityFull,'_')) {
        
$sEntityFull=Engine::GetPluginPrefix($this).'Module'.Engine::GetModuleName($this).'_Entity'.$sEntityFull;
    }
    
// Если параметр #cache указан и пуст, значит игнорируем кэширование для запроса
    
if (array_key_exists'#cache'$aJoinData) && !$aJoinData['#cache']) {
        
$iCount $this->oMapperORM->GetCountItemsByJoinTable($aJoinData,$sEntityFull);
    } else {
        
$sEntityFullRoot=$this->Plugin_GetRootDelegater('entity',$sEntityFull);
        
$sCacheKey=$sEntityFullRoot.'_count_items_by_join_table_'.serialize($aJoinData);
        
$aCacheTags=array();
        
$iCacheTime=60*60*24// скорее лучше хранить в свойстве сущности, для возможности выборочного переопределения
        // переопределяем из параметров
        
if (isset($aJoinData['#cache'][0])) $sCacheKey=$aJoinData['#cache'][0];
        if (isset(
$aJoinData['#cache'][1])) $aCacheTags=$aJoinData['#cache'][1];
        if (isset(
$aJoinData['#cache'][2])) $iCacheTime=$aJoinData['#cache'][2];

        
$aCacheTags[] = 'm2m_'.$aJoinData['#relation_key'].$aJoinData['#by_key'].$aJoinData['#by_value'];
        if (
false === ($iCount $this->Cache_Get($sCacheKey))) {
            
$iCount $this->oMapperORM->GetCountItemsByJoinTable($aJoinData,$sEntityFull);
            
$this->Cache_Set($iCount,$sCacheKey$aCacheTags$iCacheTime);
        }
    }
    return 
$iCount;
}

Получить число сущностей по связанной таблице

GetItemsByArray() method
public array GetItemsByArray(array $aFilter, string|null $sEntityFull=NULL)
$aFilter array Фильтр
$sEntityFull string|null Название класса сущности
{return} array
Source Code: /engine/classes/ModuleORM.class.php#507 (show)
public function GetItemsByArray($aFilter,$sEntityFull=null) {
    foreach (
$aFilter as $k=>$v) {
        
$aFilter["{$k} IN"]=$v;
        unset(
$aFilter[$k]);
    }
    
$aFilter[] = '#index-from-primary';
    return 
$this->GetItemsByFilter($aFilter,$sEntityFull);
}

Возвращает список сущностей по фильтру В качестве ключей возвращаемого массива используется primary key сущности

GetItemsByFilter() method
public array GetItemsByFilter(array $aFilter=array ( ), string|null $sEntityFull=NULL)
$aFilter array Фильтр
$sEntityFull string|null Название класса сущности
{return} array
Source Code: /engine/classes/ModuleORM.class.php#358 (show)
public function GetItemsByFilter($aFilter=array(),$sEntityFull=null) {
    if (
is_null($aFilter)) {
        
$aFilter = array();
    }

    if (
is_null($sEntityFull)) {
        
$sEntityFull=Engine::GetPluginPrefix($this).'Module'.Engine::GetModuleName($this).'_Entity'.Engine::GetModuleName(get_class($this));
    } elseif (!
substr_count($sEntityFull,'_')) {
        
$sEntityFull=Engine::GetPluginPrefix($this).'Module'.Engine::GetModuleName($this).'_Entity'.$sEntityFull;
    }

    
// Если параметр #cache указан и пуст, значит игнорируем кэширование для запроса
    
if (array_key_exists('#cache'$aFilter) && !$aFilter['#cache']) {
        
$aEntities=$this->oMapperORM->GetItemsByFilter($aFilter,$sEntityFull);
    } else {
        
$sEntityFullRoot=$this->Plugin_GetRootDelegater('entity',$sEntityFull);
        
$sCacheKey=$sEntityFullRoot.'_items_by_filter_'.serialize($aFilter);
        
$aCacheTags=array($sEntityFullRoot.'_save',$sEntityFullRoot.'_delete');
        
$iCacheTime=60*60*24// скорее лучше хранить в свойстве сущности, для возможности выборочного переопределения
        // переопределяем из параметров
        
if (isset($aFilter['#cache'][0])) $sCacheKey=$aFilter['#cache'][0];
        if (isset(
$aFilter['#cache'][1])) $aCacheTags=$aFilter['#cache'][1];
        if (isset(
$aFilter['#cache'][2])) $iCacheTime=$aFilter['#cache'][2];

        if (
false === ($aEntities $this->Cache_Get($sCacheKey))) {
            
$aEntities=$this->oMapperORM->GetItemsByFilter($aFilter,$sEntityFull);
            
$this->Cache_Set($aEntities,$sCacheKey$aCacheTags$iCacheTime);
        }
    }
    
/**
     * Если необходимо подцепить связанные данные
     */
    
if (count($aEntities) and isset($aFilter['#with'])) {
        if (!
is_array($aFilter['#with'])) {
            
$aFilter['#with']=array($aFilter['#with']);
        }
        
$oEntityEmpty=Engine::GetEntity($sEntityFull);
        
$aRelations=$oEntityEmpty->_getRelations();
        
$aEntityKeys=array();
        foreach (
$aFilter['#with'] as $sRelationName) {
            
$sRelType=$aRelations[$sRelationName][0];
            
$sRelEntity=$this->Plugin_GetRootDelegater('entity',$aRelations[$sRelationName][1]); // получаем корневую сущность, без учета наследников
            
$sRelKey=$aRelations[$sRelationName][2];

            if (!
array_key_exists($sRelationName,$aRelations) or !in_array($sRelType,array(EntityORM::RELATION_TYPE_BELONGS_TO,EntityORM::RELATION_TYPE_HAS_ONE))) {
                throw new 
Exception("The entity <{$sEntityFull}> not have relation <{$sRelationName}>");
            }

            
/**
             * Формируем список ключей
             */
            
foreach ($aEntities as $oEntity) {
                
$aEntityKeys[$sRelKey][]=$oEntity->_getDataOne($sRelKey);
            }
            
$aEntityKeys[$sRelKey]=array_unique($aEntityKeys[$sRelKey]);

            
/**
             * Делаем общий запрос по всем ключам
             */
            
$oRelEntityEmpty=Engine::GetEntity($sRelEntity);
            
$sRelModuleName=Engine::GetModuleName($sRelEntity);
            
$sRelEntityName=Engine::GetEntityName($sRelEntity);
            
$sRelPluginPrefix=Engine::GetPluginPrefix($sRelEntity);
            
$sRelPrimaryKey method_exists($oRelEntityEmpty,'_getPrimaryKey') ? func_camelize($oRelEntityEmpty->_getPrimaryKey()) : 'Id';
            
$aRelData=Engine::GetInstance()->_CallModule("{$sRelPluginPrefix}{$sRelModuleName}_get{$sRelEntityName}ItemsByArray{$sRelPrimaryKey}", array($aEntityKeys[$sRelKey]));

            
/**
             * Собираем набор
             */
            
foreach ($aEntities as $oEntity) {
                if (isset(
$aRelData[$oEntity->_getDataOne($sRelKey)])) {
                    
$oEntity->_setData(array($sRelationName => $aRelData[$oEntity->_getDataOne($sRelKey)]));
                }
            }
        }

    }
    
/**
     * Returns assotiative array, indexed by PRIMARY KEY or another field.
     */
    
if (in_array('#index-from-primary'$aFilter) || !empty($aFilter['#index-from'])) {
        
$aEntities $this->_setIndexesFromField($aEntities$aFilter);
    }
    
/**
     * Если запрашиваем постраничный список, то возвращаем сам список и общее количество записей
     */
    
if (isset($aFilter['#page'])) {
        return array(
'collection'=>$aEntities,'count'=>$this->GetCountItemsByFilter($aFilter,$sEntityFull));
    }
    return 
$aEntities;
}

Получить список сущностей по фильтру

GetItemsByJoinTable() method
public array GetItemsByJoinTable(array $aJoinData=array ( ), string $sEntityFull=NULL)
$aJoinData array Фильтр
$sEntityFull string Название класса сущности
{return} array
Source Code: /engine/classes/ModuleORM.class.php#522 (show)
public function GetItemsByJoinTable($aJoinData=array(),$sEntityFull=null) {
    if (
is_null($sEntityFull)) {
        
$sEntityFull=Engine::GetPluginPrefix($this).'Module'.Engine::GetModuleName($this).'_Entity'.Engine::GetModuleName(get_class($this));
    } elseif (!
substr_count($sEntityFull,'_')) {
        
$sEntityFull=Engine::GetPluginPrefix($this).'Module'.Engine::GetModuleName($this).'_Entity'.$sEntityFull;
    }

    
// Если параметр #cache указан и пуст, значит игнорируем кэширование для запроса
    
if (array_key_exists('#cache'$aJoinData) && !$aJoinData['#cache']) {
        
$aEntities $this->oMapperORM->GetItemsByJoinTable($aJoinData,$sEntityFull);
    } else {
        
$sEntityFullRoot=$this->Plugin_GetRootDelegater('entity',$sEntityFull);
        
$sCacheKey=$sEntityFullRoot.'_items_by_join_table_'.serialize($aJoinData);
        
$aCacheTags=array($sEntityFullRoot.'_save',$sEntityFullRoot.'_delete');
        
$iCacheTime=60*60*24// скорее лучше хранить в свойстве сущности, для возможности выборочного переопределения
        // переопределяем из параметров
        
if (isset($aJoinData['#cache'][0])) $sCacheKey=$aJoinData['#cache'][0];
        if (isset(
$aJoinData['#cache'][1])) $aCacheTags=$aJoinData['#cache'][1];
        if (isset(
$aJoinData['#cache'][2])) $iCacheTime=$aJoinData['#cache'][2];

        
// Добавление тега для обработки MANY_TO_MANY
        
$aCacheTags[] = 'm2m_'.$aJoinData['#relation_key'].$aJoinData['#by_key'].$aJoinData['#by_value'];
        if (
false === ($aEntities $this->Cache_Get($sCacheKey))) {
            
$aEntities $this->oMapperORM->GetItemsByJoinTable($aJoinData,$sEntityFull);
            
$this->Cache_Set($aEntities,$sCacheKey$aCacheTags$iCacheTime);
        }
    }

    if (
in_array('#index-from-primary'$aJoinData) || !empty($aJoinData['#index-from'])) {
        
$aEntities $this->_setIndexesFromField($aEntities$aJoinData);
    }
    
/**
     * Если запрашиваем постраничный список, то возвращаем сам список и общее количество записей
     */
    
if (isset($aFilter['#page'])) {
        return array(
'collection'=>$aEntities,'count'=>$this->GetCountItemsByJoinTable($aJoinData,$sEntityFull));
    }
    return 
$aEntities;
}

Получить сущности по связанной таблице

Init() method
public void Init()
Source Code: /engine/classes/ModuleORM.class.php#41 (show)
public function Init() {
    
$this->_LoadMapperORM();
}

Инициализация В наследнике этот метод нельзя перекрывать, необходимо вызывать через parent::Init();

LoadTree() method
public array|bool LoadTree(array $aFilter=array ( ), string $sEntityFull=NULL)
$aFilter array Фильтр
$sEntityFull string Название класса сущности
{return} array|bool
Source Code: /engine/classes/ModuleORM.class.php#301 (show)
public function LoadTree($aFilter=array(),$sEntityFull=null) {
    if (
is_null($sEntityFull)) {
        
$sEntityFull=Engine::GetPluginPrefix($this).'Module'.Engine::GetModuleName($this).'_Entity'.Engine::GetModuleName(get_class($this));
    } elseif (!
substr_count($sEntityFull,'_')) {
        
$sEntityFull=Engine::GetPluginPrefix($this).'Module'.Engine::GetModuleName($this).'_Entity'.$sEntityFull;
    }
    if(
$oEntityDefault=Engine::GetEntity($sEntityFull)) {
        if(
in_array(EntityORM::RELATION_TYPE_TREE,$oEntityDefault->_getRelations())) {
            if(
$sPrimaryKey=$oEntityDefault->_getPrimaryKey()) {
                if(
$aItems=$this->GetItemsByFilter($aFilter,$sEntityFull)) {
                    
$aItemsById = array();
                    
$aItemsByParentId = array();
                    foreach(
$aItems as $oEntity) {
                        
$oEntity->setChildren(array());
                        
$aItemsById[$oEntity->_getDataOne($sPrimaryKey)] = $oEntity;
                        if(empty(
$aItemsByParentId[$oEntity->getParentId()])) {
                            
$aItemsByParentId[$oEntity->getParentId()] = array();
                        }
                        
$aItemsByParentId[$oEntity->getParentId()][] = $oEntity;
                    }
                    foreach(
$aItemsByParentId as $iParentId=>$aItems) {
                        if(
$iParentId 0) {
                            
$aItemsById[$iParentId]->setChildren($aItems);
                            foreach(
$aItems as $oEntity) {
                                
$oEntity->setParent($aItemsById[$iParentId]);
                            }
                        }
                    }
                    return 
$aItemsByParentId[0];
                }
            }
        }
    }
    return 
false;
}

Для сущностей со связью RELATION_TYPE_TREE возвращает список сущностей в виде дерева

_AddEntity() method
protected EntityORM|bool _AddEntity(EntityORM $oEntity)
$oEntity EntityORM Объект сущности
{return} EntityORM|bool
Source Code: /engine/classes/ModuleORM.class.php#62 (show)
protected function _AddEntity($oEntity) {
    
$res=$this->oMapperORM->AddEntity($oEntity);
    
// сбрасываем кеш
    
if ($res===or $res) {
        
$sEntity=$this->Plugin_GetRootDelegater('entity',get_class($oEntity));
        
$this->Cache_Clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG,array($sEntity.'_save'));
    }
    if (
$res===0) {
        
// у таблицы нет автоинремента
        
return $oEntity;
    } elseif (
$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 && $oEntity->$sRelName->isUpdated()) {
                
// Сброс кэша по связям
                
$this->Cache_Clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG,array('m2m_'.$aRelation[2].$aRelation[4].$oEntity->_getPrimaryKeyValue()));
                
$this->_updateManyToManySet($aRelation$oEntity->$sRelName->getCollection(), $oEntity->_getDataOne($oEntity->_getPrimaryKey()));
                
$oEntity->resetRelationsData($sRelName);
            }
        }
        return 
$oEntity;
    }
    return 
false;
}

Добавление сущности в БД Вызывается не напрямую, а через сущность, например

 $oUser->setName('Claus');
	$oUser->Add();

_DeleteEntity() method
protected EntityORM|bool _DeleteEntity(EntityORM $oEntity)
$oEntity EntityORM Объект сущности
{return} EntityORM|bool
Source Code: /engine/classes/ModuleORM.class.php#135 (show)
protected function _DeleteEntity($oEntity) {
    
$res=$this->oMapperORM->DeleteEntity($oEntity);
    if (
$res) {
        
// сбрасываем кеш
        
$sEntity=$this->Plugin_GetRootDelegater('entity',get_class($oEntity));
        
$this->Cache_Clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG,array($sEntity.'_delete'));

        
// Обновление связей many_to_many
        
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 
false;
}

Удаление сущности из БД

_GetAncestorsOfEntity() method
protected array _GetAncestorsOfEntity(EntityORM $oEntity)
$oEntity EntityORM Объект сущности
{return} array
Source Code: /engine/classes/ModuleORM.class.php#247 (show)
protected function _GetAncestorsOfEntity($oEntity) {
    if(
in_array(EntityORM::RELATION_TYPE_TREE,$oEntity->_getRelations())) {
        
$aRelationsData=$oEntity->_getRelationsData();
        if(
array_key_exists('ancestors',$aRelationsData)) {
            
$aAncestors=$aRelationsData['ancestors'];
        } else {
            
$aAncestors=array();
            
$oEntityParent=$oEntity->getParent();
            while(
is_object($oEntityParent)) {
                
$aAncestors[]=$oEntityParent;
                
$oEntityParent=$oEntityParent->getParent();
            }
        }
        if(
is_array($aAncestors)) {
            
$oEntity->setAncestors($aAncestors);
            return 
$aAncestors;
        }
    }
    return 
false;
}

Для сущности со связью RELATION_TYPE_TREE возвращает список всех предков

_GetChildrenOfEntity() method
protected array _GetChildrenOfEntity(EntityORM $oEntity)
$oEntity EntityORM Объект сущности
{return} array
Source Code: /engine/classes/ModuleORM.class.php#195 (show)
protected function _GetChildrenOfEntity($oEntity) {
    if(
in_array(EntityORM::RELATION_TYPE_TREE,$oEntity->_getRelations())) {
        
$aRelationsData=$oEntity->_getRelationsData();
        if(
array_key_exists('children',$aRelationsData)) {
            
$aChildren=$aRelationsData['children'];
        } else {
            
$aChildren=array();
            if(
$sPrimaryKey=$oEntity->_getPrimaryKey()) {
                if(
$sPrimaryKeyValue=$oEntity->_getDataOne($sPrimaryKey)) {
                    
$aChildren=$this->GetItemsByFilter(array('parent_id'=>$sPrimaryKeyValue),Engine::GetEntityName($oEntity));
                }
            }
        }
        if(
is_array($aChildren)) {
            
$oEntity->setChildren($aChildren);
            return 
$aChildren;
        }
    }
    return 
false;
}

Для сущности со связью RELATION_TYPE_TREE возвращает список прямых потомков

_GetDescendantsOfEntity() method
protected array _GetDescendantsOfEntity(EntityORM $oEntity)
$oEntity EntityORM Объект сущности
{return} array
Source Code: /engine/classes/ModuleORM.class.php#273 (show)
protected function _GetDescendantsOfEntity($oEntity) {
    if(
in_array(EntityORM::RELATION_TYPE_TREE,$oEntity->_getRelations())) {
        
$aRelationsData=$oEntity->_getRelationsData();
        if(
array_key_exists('descendants',$aRelationsData)) {
            
$aDescendants=$aRelationsData['descendants'];
        } else {
            
$aDescendants=array();
            if(
$aChildren=$oEntity->getChildren()) {
                
$aTree=self::buildTree($aChildren);
                foreach(
$aTree as $aItem) {
                    
$aDescendants[] = $aItem['entity'];
                }
            }
        }
        if(
is_array($aDescendants)) {
            
$oEntity->setDescendants($aDescendants);
            return 
$aDescendants;
        }
    }
    return 
false;
}

Для сущности со связью RELATION_TYPE_TREE возвращает список всех потомков

_GetParentOfEntity() method
protected EntityORM|bool _GetParentOfEntity(EntityORM $oEntity)
$oEntity EntityORM Объект сущности
{return} EntityORM|bool
Source Code: /engine/classes/ModuleORM.class.php#221 (show)
protected function _GetParentOfEntity($oEntity) {
    if(
in_array(EntityORM::RELATION_TYPE_TREE,$oEntity->_getRelations())) {
        
$aRelationsData=$oEntity->_getRelationsData();
        if(
array_key_exists('parent',$aRelationsData)) {
            
$oParent=$aRelationsData['parent'];
        } else {
            
$oParent='%%NULL_PARENT%%';
            if(
$sPrimaryKey=$oEntity->_getPrimaryKey()) {
                if(
$sParentId=$oEntity->getParentId()) {
                    
$oParent=$this->GetByFilter(array($sPrimaryKey=>$sParentId),Engine::GetEntityName($oEntity));
                }
            }
        }
        if(!
is_null($oParent)) {
            
$oEntity->setParent($oParent);
            return 
$oParent;
        }
    }
    return 
false;
}

Для сущности со связью RELATION_TYPE_TREE возвращает предка

_LoadMapperORM() method
protected void _LoadMapperORM()
Source Code: /engine/classes/ModuleORM.class.php#48 (show)
protected function _LoadMapperORM() {
    
$this->oMapperORM=new MapperORM($this->oEngine->Database_GetConnect());
}

Загрузка маппера ORM

_ReloadEntity() method
protected EntityORM|bool _ReloadEntity(EntityORM $oEntity)
$oEntity EntityORM Объект сущности
{return} EntityORM|bool
Source Code: /engine/classes/ModuleORM.class.php#159 (show)
protected function _ReloadEntity($oEntity) {
    if(
$sPrimaryKey=$oEntity->_getPrimaryKey()) {
        if(
$sPrimaryKeyValue=$oEntity->_getDataOne($sPrimaryKey)) {
            if(
$oEntityNew=$this->GetByFilter(array($sPrimaryKey=>$sPrimaryKeyValue),Engine::GetEntityName($oEntity))) {
                
$oEntity->_setData($oEntityNew->_getData());
                
$oEntity->_setRelationsData(array());
                return 
$oEntity;
            }
        }
    }
    return 
false;
}

Обновляет данные сущности из БД

_SaveEntity() method
protected EntityORM|bool _SaveEntity(EntityORM $oEntity)
$oEntity EntityORM Объект сущности
{return} EntityORM|bool
Source Code: /engine/classes/ModuleORM.class.php#122 (show)
protected function _SaveEntity($oEntity) {
    if (
$oEntity->_isNew()) {
        return 
$this->_AddEntity($oEntity);
    } else {
        return 
$this->_UpdateEntity($oEntity);
    }
}

Сохранение сущности в БД

_ShowColumnsFrom() method
protected array _ShowColumnsFrom(EntityORM $oEntity)
$oEntity EntityORM Объект сущности
{return} array
Source Code: /engine/classes/ModuleORM.class.php#177 (show)
protected function _ShowColumnsFrom($oEntity) {
    return 
$this->oMapperORM->ShowColumnsFrom($oEntity);
}

Список полей сущности

_ShowPrimaryIndexFrom() method
protected array _ShowPrimaryIndexFrom(EntityORM $oEntity)
$oEntity EntityORM Объект сущности
{return} array
Source Code: /engine/classes/ModuleORM.class.php#186 (show)
protected function _ShowPrimaryIndexFrom($oEntity) {
    return 
$this->oMapperORM->ShowPrimaryIndexFrom($oEntity);
}

Primary индекс сущности

_UpdateEntity() method
protected EntityORM|bool _UpdateEntity(EntityORM $oEntity)
$oEntity EntityORM Объект сущности
{return} EntityORM|bool
Source Code: /engine/classes/ModuleORM.class.php#95 (show)
protected function _UpdateEntity($oEntity) {
    
$res=$this->oMapperORM->UpdateEntity($oEntity);
    if (
$res===or $res) { // запись не изменилась, либо изменилась
        // Обновление связей many_to_many
        
$aRelationsData $oEntity->_getRelationsData();
        foreach (
$oEntity->_getRelations() as $sRelName => $aRelation) {
            if (
$aRelation[0] == EntityORM::RELATION_TYPE_MANY_TO_MANY && $oEntity->$sRelName->isUpdated()) {
                
// Сброс кэша по связям

                
$this->Cache_Clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG,array('m2m_'.$aRelation[2].$aRelation[4].$oEntity->_getPrimaryKeyValue()));
                
$this->_updateManyToManySet($aRelation$oEntity->$sRelName->getCollection(), $oEntity->_getDataOne($oEntity->_getPrimaryKey()));
                
$oEntity->resetRelationsData($sRelName);
            }
        }
        
// сбрасываем кеш
        
$sEntity=$this->Plugin_GetRootDelegater('entity',get_class($oEntity));
        
$this->Cache_Clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG,array($sEntity.'_save'));
        return 
$oEntity;
    }
    return 
false;
}

Обновление сущности в БД

__call() method
public mixed __call(string $sName, array $aArgs)
$sName string Имя метода
$aArgs array Аргументы
{return} mixed
Source Code: /engine/classes/ModuleORM.class.php#613 (show)
public function __call($sName,$aArgs) {
    if (
preg_match("@^add([\w]+)$@i",$sName,$aMatch)) {
        return 
$this->_AddEntity($aArgs[0]);
    }

    if (
preg_match("@^update([\w]+)$@i",$sName,$aMatch)) {
        return 
$this->_UpdateEntity($aArgs[0]);
    }

    if (
preg_match("@^save([\w]+)$@i",$sName,$aMatch)) {
        return 
$this->_SaveEntity($aArgs[0]);
    }

    if (
preg_match("@^delete([\w]+)$@i",$sName,$aMatch)) {
        return 
$this->_DeleteEntity($aArgs[0]);
    }

    if (
preg_match("@^reload([\w]+)$@i",$sName,$aMatch)) {
        return 
$this->_ReloadEntity($aArgs[0]);
    }

    if (
preg_match("@^showcolumnsfrom([\w]+)$@i",$sName,$aMatch)) {
        return 
$this->_ShowColumnsFrom($aArgs[0]);
    }

    if (
preg_match("@^showprimaryindexfrom([\w]+)$@i",$sName,$aMatch)) {
        return 
$this->_ShowPrimaryIndexFrom($aArgs[0]);
    }

    if (
preg_match("@^getchildrenof([\w]+)$@i",$sName,$aMatch)) {
        return 
$this->_GetChildrenOfEntity($aArgs[0]);
    }

    if (
preg_match("@^getparentof([\w]+)$@i",$sName,$aMatch)) {
        return 
$this->_GetParentOfEntity($aArgs[0]);
    }

    if (
preg_match("@^getdescendantsof([\w]+)$@i",$sName,$aMatch)) {
        return 
$this->_GetDescendantsOfEntity($aArgs[0]);
    }

    if (
preg_match("@^getancestorsof([\w]+)$@i",$sName,$aMatch)) {
        return 
$this->_GetAncestorsOfEntity($aArgs[0]);
    }

    if (
preg_match("@^loadtreeof([\w]+)$@i",$sName,$aMatch)) {
        
$sEntityFull array_key_exists(1,$aMatch) ? $aMatch[1] : null;
        return 
$this->LoadTree($aArgs[0], $sEntityFull);
    }

    
$sNameUnderscore=func_underscore($sName);
    
$iEntityPosEnd=0;
    if(
strpos($sNameUnderscore,'_items')>=3) {
        
$iEntityPosEnd=strpos($sNameUnderscore,'_items');
    } else if(
strpos($sNameUnderscore,'_by')>=3) {
        
$iEntityPosEnd=strpos($sNameUnderscore,'_by');
    } else if(
strpos($sNameUnderscore,'_all')>=3) {
        
$iEntityPosEnd=strpos($sNameUnderscore,'_all');
    }
    if(
$iEntityPosEnd && $iEntityPosEnd 4) {
        
$sEntityName=substr($sNameUnderscore,4,$iEntityPosEnd-4);
    } else {
        
$sEntityName=func_underscore(Engine::GetModuleName($this)).'_';
        
$sNameUnderscore=substr_replace($sNameUnderscore,$sEntityName,4,0);
        
$iEntityPosEnd=strlen($sEntityName)-1+4;
    }

    
$sNameUnderscore=substr_replace($sNameUnderscore,str_replace('_','',$sEntityName),4,$iEntityPosEnd-4);

    
$sEntityName=func_camelize($sEntityName);

    
/**
     * getUserItemsByFilter() get_user_items_by_filter
     */
    
if (preg_match("@^get_([a-z]+)((_items)|())_by_filter$@i",$sNameUnderscore,$aMatch)) {
        if (
$aMatch[2]=='_items') {
            return 
$this->GetItemsByFilter($aArgs[0],$sEntityName);
        } else {
            return 
$this->GetByFilter($aArgs[0],$sEntityName);
        }
    }

    
/**
     * getUserItemsByArrayId() get_user_items_by_array_id
     */
    
if (preg_match("@^get_([a-z]+)_items_by_array_([_a-z]+)$@i",$sNameUnderscore,$aMatch)) {
        return 
$this->GetItemsByArray(array($aMatch[2]=>$aArgs[0]),$sEntityName);
    }

    
/**
     * getUserItemsByJoinTable() get_user_items_by_join_table
     */
    
if (preg_match("@^get_([a-z]+)_items_by_join_table$@i",$sNameUnderscore,$aMatch)) {
        return 
$this->GetItemsByJoinTable($aArgs[0],func_camelize($sEntityName));
    }

    
/**
     * getUserByLogin()                    get_user_by_login
     * getUserByLoginAndMail()            get_user_by_login_and_mail
     * getUserItemsByName()                get_user_items_by_name
     * getUserItemsByNameAndActive()    get_user_items_by_name_and_active
     * getUserItemsByDateRegisterGte()    get_user_items_by_date_register_gte        (>=)
     * getUserItemsByProfileNameLike()    get_user_items_by_profile_name_like
     * getUserItemsByCityIdIn()            get_user_items_by_city_id_in
     */
    
if (preg_match("@^get_([a-z]+)((_items)|())_by_([_a-z]+)$@i",$sNameUnderscore,$aMatch)) {
        
$aAliases = array( '_gte' => ' >=''_lte' => ' <=''_gt' => ' >''_lt' => ' <''_like' => ' LIKE''_in' => ' IN' );
        
$sSearchParams str_replace(array_keys($aAliases),array_values($aAliases),$aMatch[5]);
        
$aSearchParams=explode('_and_',$sSearchParams);
        
$aSplit=array_chunk($aArgs,count($aSearchParams));
        
$aFilter=array_combine($aSearchParams,$aSplit[0]);
        if (isset(
$aSplit[1][0])) {
            
$aFilter=array_merge($aFilter,$aSplit[1][0]);
        }
        if (
$aMatch[2]=='_items') {
            return 
$this->GetItemsByFilter($aFilter,$sEntityName);
        } else {
            return 
$this->GetByFilter($aFilter,$sEntityName);
        }
    }

    
/**
     * getUserAll()            get_user_all         OR
     * getUserItemsAll()    get_user_items_all
     */
    
if (preg_match("@^get_([a-z]+)_all$@i",$sNameUnderscore,$aMatch) ||
        
preg_match("@^get_([a-z]+)_items_all$@i",$sNameUnderscore,$aMatch)
    ) {
        
$aFilter=array();
        if (isset(
$aArgs[0]) and is_array($aArgs[0])) {
            
$aFilter=$aArgs[0];
        }
        return 
$this->GetItemsByFilter($aFilter,$sEntityName);
    }

    return 
$this->oEngine->_CallModule($sName,$aArgs);
}

Ставим хук на вызов неизвестного метода и считаем что хотели вызвать метод какого либо модуля. Также обрабатывает различные ORM методы сущности, например

$oUser->Save();
$oUser->Delete();
И методы модуля ORM, например
$this->User_getUserItemsByName('Claus');
$this->User_getUserItemsAll();

_deleteManyToManySet() method
protected void _deleteManyToManySet(string $sDbTableAlias, string $sEntityKey, int $iEntityId)
$sDbTableAlias string Алиас имени таблицы связи
$sEntityKey string Название поля в таблице связи с id сущности, для которой удаляются связи.
$iEntityId int Id сущнсоти, для который удаляются связи
Source Code: /engine/classes/ModuleORM.class.php#820 (show)
protected function _deleteManyToManySet($sDbTableAlias$sEntityKey$iEntityId) {
    
$this->oMapperORM->deleteManyToManySet($sDbTableAlias$sEntityKey$iEntityId);
}

Удаление связи many_to_many в бд

_setIndexesFromField() method
protected array _setIndexesFromField(array $aEntities, array $aFilter)
$aEntities array Список сущностей
$aFilter array Фильтр
{return} array
Source Code: /engine/classes/ModuleORM.class.php#456 (show)
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;
}

Returns assotiative array, indexed by PRIMARY KEY or another field.

_updateManyToManySet() method
protected void _updateManyToManySet(array $aRelation, array $aRelationData, int $iEntityId)
$aRelation array Соответствующий связи элемент массива из $oEntityORM->aRelations
$aRelationData array Соответствующий связи элемент массива из $oEntityORM->aRelationsData
$iEntityId int Id сущности, для которой обновляются связи
Source Code: /engine/classes/ModuleORM.class.php#782 (show)
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 в бд

buildTree() method
public static array buildTree(array $aItems, array $aList=array ( ), int $iLevel=0)
$aItems array Список сущностей
$aList array
$iLevel int Текущий уровень вложенности
{return} array
Source Code: /engine/classes/ModuleORM.class.php#758 (show)
static function buildTree($aItems,$aList=array(),$iLevel=0) {
    foreach(
$aItems as $oEntity) {
        
$aChildren=$oEntity->getChildren();
        
$bHasChildren = !empty($aChildren);
        
$sEntityId $oEntity->_getDataOne($oEntity->_getPrimaryKey());
        
$aList[$sEntityId] = array(
            
'entity'         => $oEntity,
            
'parent_id'         => $oEntity->getParentId(),
            
'children_count' => $bHasChildren count($aChildren) : 0,
            
'level'             => $iLevel,
        );
        if(
$bHasChildren) {
            
$aList=self::buildTree($aChildren,$aList,$iLevel+1);
        }
    }
    return 
$aList;
}

Построение дерева