1
0
Fork 0
mirror of https://github.com/Oreolek/ifhub.club.git synced 2024-07-01 14:05:07 +03:00

ORM-relation type 'Tree' support added.

This commit is contained in:
Alexander Zinchuk 2010-10-31 12:10:25 +00:00
parent 06c5580c75
commit eababf4af7
2 changed files with 244 additions and 4 deletions

View file

@ -25,6 +25,7 @@ abstract class EntityORM extends Entity {
const RELATION_TYPE_HAS_MANY='has_many';
const RELATION_TYPE_HAS_ONE='has_one';
const RELATION_TYPE_MANY_TO_MANY='many_to_many';
const RELATION_TYPE_TREE='tree';
protected $aRelations=array();
protected $aRelationsData=array();
@ -77,6 +78,70 @@ abstract class EntityORM extends Entity {
public function Reload() {
return $this->_Method(__FUNCTION__);
}
public function getChildren() {
if(in_array(self::RELATION_TYPE_TREE,$this->aRelations)) {
return $this->_Method(__FUNCTION__ .'Of');
}
return $this->__call(__FUNCTION__);
}
public function getDescendants() {
if(in_array(self::RELATION_TYPE_TREE,$this->aRelations)) {
return $this->_Method(__FUNCTION__ .'Of');
}
return $this->__call(__FUNCTION__);
}
public function getParent() {
if(in_array(self::RELATION_TYPE_TREE,$this->aRelations)) {
return $this->_Method(__FUNCTION__ .'Of');
}
return $this->__call(__FUNCTION__);
}
public function getAncestors() {
if(in_array(self::RELATION_TYPE_TREE,$this->aRelations)) {
return $this->_Method(__FUNCTION__ .'Of');
}
return $this->__call(__FUNCTION__);
}
public function setChildren($aChildren=array()) {
if(in_array(self::RELATION_TYPE_TREE,$this->aRelations)) {
$this->aRelationsData['children'] = $aChildren;
} else {
$aArgs = func_get_args();
return $this->__call(__FUNCTION__,$aArgs);
}
}
public function setDescendants($aDescendants=array()) {
if(in_array(self::RELATION_TYPE_TREE,$this->aRelations)) {
$this->aRelationsData['descendants'] = $aDescendants;
} else {
$aArgs = func_get_args();
return $this->__call(__FUNCTION__,$aArgs);
}
}
public function setParent($oParent=null) {
if(in_array(self::RELATION_TYPE_TREE,$this->aRelations)) {
$this->aRelationsData['parent'] = $oParent;
} else {
$aArgs = func_get_args();
return $this->__call(__FUNCTION__,$aArgs);
}
}
public function setAncestors($oParent=null) {
if(in_array(self::RELATION_TYPE_TREE,$this->aRelations)) {
$this->aRelationsData['ancestors'] = $oParent;
} else {
$aArgs = func_get_args();
return $this->__call(__FUNCTION__,$aArgs);
}
}
protected function _Method($sName) {
$sModuleName=Engine::GetModuleName($this);
@ -85,10 +150,7 @@ abstract class EntityORM extends Entity {
return Engine::GetInstance()->_CallModule("{$sPluginPrefix}{$sModuleName}_{$sName}{$sEntityName}",array($this));
}
public function _getRelations() {
return $this->aRelations;
}
public function _setData($aData) {
if(is_array($aData)) {
@ -102,6 +164,18 @@ abstract class EntityORM extends Entity {
}
}
public function _getRelations() {
return $this->aRelations;
}
public function _getRelationsData() {
return $this->aRelationsData;
}
public function _setRelationsData($aData) {
$this->aRelationsData=$aData;
}
public function __call($sName,$aArgs) {
$sType=substr($sName,0,strpos(func_underscore($sName),'_'));
if (!strpos($sName,'_') and in_array($sType,array('get','set','reload'))) {

View file

@ -81,13 +81,141 @@ abstract class ModuleORM extends Module {
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;
}
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();
$sParentId=$oEntity->getParentId();
while($sParentId > 0) {
$oEntity=$oEntity->getParent();
$aAncestors[]=$oEntity;
$sParentId=$oEntity->getParentId();
}
}
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()) {
$aDescendants=$aChildren;
$aTree=self::buildTree($aChildren);
foreach($aTree as $aItem) {
$aDescendants[] = $aItem['entity'];
}
}
}
if(is_array($aDescendants)) {
$oEntity->setDescendants($aDescendants);
return $aDescendants;
}
}
return false;
}
public function LoadTree($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(array(),$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;
}
public function GetByFilter($aFilter=array(),$sEntityFull=null) {
if (is_null($sEntityFull)) {
@ -225,6 +353,27 @@ abstract class ModuleORM extends Module {
if (preg_match("@^reload([\w]+)$@i",$sName,$aMatch)) {
return $this->_ReloadEntity($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);
}
$sNameUnderscore=func_underscore($sName);
$iEntityPosEnd=strlen($sNameUnderscore)-1;
@ -287,5 +436,22 @@ abstract class ModuleORM extends Module {
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;
}
}
?>