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:
parent
06c5580c75
commit
eababf4af7
|
@ -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'))) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
?>
|
Loading…
Reference in a new issue