1
0
Fork 0
mirror of https://github.com/Oreolek/ifhub.club.git synced 2024-07-03 06:55:03 +03:00
ifhub.club/engine/classes/ModuleORM.class.php

488 lines
17 KiB
PHP
Raw Normal View History

2010-08-13 19:26:19 +03:00
<?php
/*-------------------------------------------------------
*
* LiveStreet Engine Social Networking
* Copyright © 2008 Mzhelskiy Maxim
*
*--------------------------------------------------------
*
* Official site: www.livestreet.ru
* Contact e-mail: rus.engine@gmail.com
*
* GNU General Public License, version 2:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
---------------------------------------------------------
*/
/**
* Абстракция модуля ORM
*
*/
abstract class ModuleORM extends Module {
protected $oMapperORM=null;
public function Init() {
$this->_LoadMapperORM();
}
protected function _LoadMapperORM() {
$this->oMapperORM=new MapperORM($this->oEngine->Database_GetConnect());
}
protected function _AddEntity($oEntity) {
$res=$this->oMapperORM->AddEntity($oEntity);
// сбрасываем кеш
if ($res===0 or $res) {
$sEntity=$this->Plugin_GetRootDelegater('entity',get_class($oEntity));
$this->Cache_Clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG,array($sEntity.'_save'));
}
2010-08-13 19:26:19 +03:00
if ($res===0) {
// у таблицы нет автоинремента
return $oEntity;
} elseif ($res) {
// есть автоинкремент, устанавливаем его
2010-08-29 10:03:53 +03:00
$oEntity->_setData(array($oEntity->_GetPrimaryKey() => $res));
2010-08-13 19:26:19 +03:00
return $oEntity;
}
return false;
}
protected function _UpdateEntity($oEntity) {
$res=$this->oMapperORM->UpdateEntity($oEntity);
if ($res===0 or $res) { // запись не изменилась, либо изменилась
// сбрасываем кеш
$sEntity=$this->Plugin_GetRootDelegater('entity',get_class($oEntity));
$this->Cache_Clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG,array($sEntity.'_save'));
2010-08-13 19:26:19 +03:00
return $oEntity;
}
2010-08-13 19:26:19 +03:00
return false;
}
2010-08-13 19:26:19 +03:00
protected function _SaveEntity($oEntity) {
if ($oEntity->_isNew()) {
return $this->_AddEntity($oEntity);
} else {
return $this->_UpdateEntity($oEntity);
}
2010-08-29 10:03:53 +03:00
}
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'));
return $oEntity;
}
return false;
}
2010-08-29 10:03:53 +03:00
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());
2010-08-29 10:03:53 +03:00
return $oEntity;
}
}
}
return false;
2010-08-13 19:26:19 +03:00
}
protected function _ShowColumnsFrom($oEntity) {
$res=$this->oMapperORM->ShowColumnsFrom($oEntity);
return $res;
}
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;
}
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;
}
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;
}
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;
}
2010-08-13 19:26:19 +03:00
2011-03-23 16:39:52 +02:00
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()) {
2011-03-23 16:39:52 +02:00
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;
}
2010-08-13 19:26:19 +03:00
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);
}
public function GetItemsByFilter($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;
}
$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);
}
2010-08-13 19:26:19 +03:00
/**
* Если необходимо подцепить связанные данные
*/
2011-01-28 12:10:55 +02:00
if (count($aEntities) and isset($aFilter['#with'])) {
2010-08-13 19:26:19 +03:00
if (!is_array($aFilter['#with'])) {
$aFilter['#with']=array($aFilter['#with']);
}
$oEntityEmpty=Engine::GetEntity($sEntityFull);
$aRelations=$oEntityEmpty->_getRelations();
2010-08-14 01:40:01 +03:00
$aEntityKeys=array();
2010-08-13 19:26:19 +03:00
foreach ($aFilter['#with'] as $sRelationName) {
2010-08-14 01:40:01 +03:00
$sRelType=$aRelations[$sRelationName][0];
$sRelEntity=$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))) {
2010-08-13 19:26:19 +03:00
throw new Exception("The entity <{$sEntityFull}> not have relation <{$sRelationName}>");
}
2010-08-14 01:40:01 +03:00
2010-08-13 19:26:19 +03:00
/**
* Формируем список ключей
*/
foreach ($aEntities as $oEntity) {
2010-08-14 01:40:01 +03:00
$aEntityKeys[$sRelKey][]=$oEntity->_getDataOne($sRelKey);
2010-08-13 19:26:19 +03:00
}
2010-08-14 01:40:01 +03:00
$aEntityKeys[$sRelKey]=array_unique($aEntityKeys[$sRelKey]);
2010-08-13 19:26:19 +03:00
/**
* Делаем общий запрос по всем ключам
*/
2010-08-14 01:40:01 +03:00
$oRelEntityEmpty=Engine::GetEntity($sRelEntity);
2010-08-13 19:26:19 +03:00
2010-08-14 01:40:01 +03:00
$sRelModuleName=Engine::GetModuleName($oRelEntityEmpty);
$sRelEntityName=Engine::GetEntityName($oRelEntityEmpty);
$sRelPluginPrefix=Engine::GetPluginPrefix($oRelEntityEmpty);
2010-09-21 18:01:05 +03:00
$sPrimaryKey="Id";
2011-02-15 15:25:19 +02:00
if (method_exists($oRelEntityEmpty,'_GetPrimaryKey') and $sPrimaryKey=$oRelEntityEmpty->_GetPrimaryKey()) {
2010-09-21 18:01:05 +03:00
$sPrimaryKey=ucfirst($sPrimaryKey);
}
$aRelData=Engine::GetInstance()->_CallModule("{$sRelPluginPrefix}{$sRelModuleName}_get{$sRelEntityName}ItemsByArray{$sPrimaryKey}",array($aEntityKeys[$sRelKey]));
2010-08-14 01:40:01 +03:00
/**
* Собираем набор
*/
foreach ($aEntities as $oEntity) {
if (isset($aRelData[$oEntity->_getDataOne($sRelKey)])) {
$oEntity->_setData(array($sRelationName => $aRelData[$oEntity->_getDataOne($sRelKey)]));
}
}
2010-08-13 19:26:19 +03:00
}
}
2010-09-21 18:01:05 +03:00
/**
* Если запрашиваем постраничный список, то возвращаем сам список и общее количество записей
*/
if (isset($aFilter['#page'])) {
return array('collection'=>$aEntities,'count'=>$this->GetCountItemsByFilter($aFilter,$sEntityFull));
}
2010-08-13 19:26:19 +03:00
return $aEntities;
}
2010-09-21 18:01:05 +03:00
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;
}
$iCount=$this->oMapperORM->GetCountItemsByFilter($aFilter,$sEntityFull);
2010-09-21 18:01:05 +03:00
return $iCount;
}
2010-08-29 10:03:53 +03:00
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;
}
return $this->oMapperORM->GetItemsByJoinTable($aJoinData,$sEntityFull);
}
public function __call($sName,$aArgs) {
2010-08-13 19:26:19 +03:00
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]);
}
2010-08-29 10:03:53 +03:00
if (preg_match("@^reload([\w]+)$@i",$sName,$aMatch)) {
return $this->_ReloadEntity($aArgs[0]);
2010-08-13 19:26:19 +03:00
}
if (preg_match("@^showcolumnsfrom([\w]+)$@i",$sName,$aMatch)) {
return $this->_ShowColumnsFrom($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($sEntityFull);
}
2010-08-13 19:26:19 +03:00
$sNameUnderscore=func_underscore($sName);
$iEntityPosEnd=0;
if(strpos($sNameUnderscore,'_items')>=3) {
2010-08-29 10:03:53 +03:00
$iEntityPosEnd=strpos($sNameUnderscore,'_items');
} else if(strpos($sNameUnderscore,'_by')>=3) {
2010-08-29 10:03:53 +03:00
$iEntityPosEnd=strpos($sNameUnderscore,'_by');
} else if(strpos($sNameUnderscore,'_all')>=3) {
2010-08-29 10:03:53 +03:00
$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;
}
2010-08-29 10:03:53 +03:00
/**
* getUserRoleJoinByUserIdAndRoleId() get_user-role-join_by_user_id_and_role_id
*/
$sNameUnderscore=substr_replace($sNameUnderscore,str_replace('_','',$sEntityName),4,$iEntityPosEnd-4);
2010-08-29 10:03:53 +03:00
$sEntityName=func_camelize($sEntityName);
2010-08-13 19:26:19 +03:00
/**
* 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 OR
* getUserItemsByIdIn() get_user_items_by_id_in
2010-08-13 19:26:19 +03:00
*/
if (preg_match("@^get_([a-z]+)_items_by_array_([_a-z]+)$@i",$sNameUnderscore,$aMatch) ||
preg_match("@^get_([a-z]+)_items_by_([_a-z]+)_in$@i",$sNameUnderscore,$aMatch)
) {
return $this->GetItemsByFilter(array("{$aMatch[2]} in"=>$aArgs[0]),$sEntityName);
2010-08-29 10:03:53 +03:00
}
/**
* 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));
2010-08-13 19:26:19 +03:00
}
/**
* 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
*
*/
if (preg_match("@^get_([a-z]+)((_items)|())_by_([_a-z]+)$@i",$sNameUnderscore,$aMatch)) {
2010-09-21 18:01:05 +03:00
$aSearchParams=explode('_and_',$aMatch[5]);
$aSplit=array_chunk($aArgs,count($aSearchParams));
$aFilter=array_combine($aSearchParams,$aSplit[0]);
if (isset($aSplit[1][0])) {
$aFilter=array_merge($aFilter,$aSplit[1][0]);
}
2010-08-13 19:26:19 +03:00
if ($aMatch[2]=='_items') {
2010-08-29 10:03:53 +03:00
return $this->GetItemsByFilter($aFilter,$sEntityName);
2010-08-13 19:26:19 +03:00
} else {
2010-08-29 10:03:53 +03:00
return $this->GetByFilter($aFilter,$sEntityName);
2010-08-13 19:26:19 +03:00
}
}
/**
* getUserAll() get_user_all OR getUserItemsAll() get_user_items_all
2010-08-13 19:26:19 +03:00
*/
if (preg_match("@^get_([a-z]+)_all$@i",$sNameUnderscore,$aMatch) ||
preg_match("@^get_([a-z]+)_items_all$@i",$sNameUnderscore,$aMatch)
) {
2010-08-13 19:26:19 +03:00
$aFilter=array();
if (isset($aArgs[0]) and is_array($aArgs[0])) {
$aFilter=$aArgs[0];
}
2010-08-29 10:03:53 +03:00
return $this->GetItemsByFilter($aFilter,$sEntityName);
2010-08-13 19:26:19 +03:00
}
return $this->oEngine->_CallModule($sName,$aArgs);
}
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;
}
2010-08-13 19:26:19 +03:00
}
?>