codepad
[
create a new paste
]
login
|
about
Language:
C
C++
D
Haskell
Lua
OCaml
PHP
Perl
Plain Text
Python
Ruby
Scheme
Tcl
<?php /** * @todo * 1. ввести $pathAttribute в метод getPath() * 2. проверять подключение NestedSetBehavior afterConstruct() (см. $this->asa()) * 3. включить автоматическое определение первичного ключа (вместо id) в метод getChildsPkArray() (см. $owner->getTableSchema()->primaryKey) */ class NestedSetPathBehavior extends CActiveRecordBehavior { /** * @var string наименование аттрибута модели содержащий псевдоним */ public $aliasAttribute='alias'; /** * @var string наименование аттрибута модели содержащий заголовок */ public $titleAttribute='title'; /** * @var string наименование поведения для NestedSetBehavior * @see CActiveRecord метод behaviors() * public function behaviors() * { * return array( * 'treeBehavior'=>array( * 'class'=>'application.behaviors.NestedSetBehavior', * ), * ); * } */ public $nestedSetBehaviorName='treeBehavior'; /** * Возвращает псевдоним текущей модели * * @return string */ public function getAlias() { return $this->getOwner()->{$this->aliasAttribute}; } /** * Возвращает заголовок текущей модели * * @return string */ public function getTitle() { return $this->getOwner()->{$this->titleAttribute}; } /** * Возвращает путь до текущей модели * * @param bool $assoc возвращать массив вида * array( * заголовок=>путь * ) * @param bool $withRoot запращивать корень дерева * @return array / string */ public function getPath($assoc=true, $withRoot=false) { $owner=$this->getOwner(); if($owner->isRoot() && $withRoot) return $assoc ? array($this->getTitle()=>$this->getAlias()) : $this->getAlias(); $criteria=$owner->getDbCriteria(); $criteria->select=$this->titleAttribute.', '.$this->aliasAttribute; if(!$withRoot) { $db=$owner->getDbConnection(); $criteria->addCondition($db->quoteColumnName($owner->getTableAlias()).'.'.$db->quoteColumnName($owner->{$this->nestedSetBehaviorName}->leftAttribute).'>1'); } $ancestors=$owner->ancestors()->findAll(); if($ancestors!=null) { $pathList=CHtml::listData($ancestors, $this->titleAttribute, $this->aliasAttribute); $pathList[$this->getTitle()]=$this->getAlias(); return $assoc ? array(end(array_keys($pathList))=>implode("/",array_values($pathList))) : implode("/",array_values($pathList)); } else return null; } /** * Возвращает модель соответствующую переданному пути * * @param string $path путь * @return CActiveRecord */ public function findByPath($path=null) { if($path==null) return null; $domens=explode('/', trim($path, '/')); $owner=$this->getOwner(); $db=$owner->getDbConnection(); $criteria=$owner->getDbCriteria(); $alias=$db->quoteColumnName($owner->getTableAlias()); if(count($domens)==1) { $criteria->addCondition($alias.'.'.$db->quoteColumnName($this->aliasAttribute).'='.CDbCriteria::PARAM_PREFIX.CDbCriteria::$paramCount); $criteria->params[CDbCriteria::PARAM_PREFIX.CDbCriteria::$paramCount++]=$domens[0]; } else { $tree=$owner->{$this->nestedSetBehaviorName}; $criteria->addCondition($alias.'.'.$db->quoteColumnName($this->aliasAttribute).'='.CDbCriteria::PARAM_PREFIX.CDbCriteria::$paramCount); $criteria->params[CDbCriteria::PARAM_PREFIX.CDbCriteria::$paramCount++]=end($domens); array_pop($domens); $domens=array_reverse($domens); $i=1; foreach($domens as $v) { $criteria->join .= ' LEFT JOIN '.$owner->tableName().' '.$db->quoteColumnName('t_'.$i) . ' ON ' . $db->quoteColumnName('t_'.$i).'.'.$db->quoteColumnName($tree->leftAttribute).'<'.$alias.'.'.$db->quoteColumnName($tree->leftAttribute).' AND '. $db->quoteColumnName('t_'.$i).'.'.$db->quoteColumnName($tree->rightAttribute).'>'.$alias.'.'.$db->quoteColumnName($tree->rightAttribute).' AND '. $db->quoteColumnName('t_'.$i).'.'.$db->quoteColumnName($tree->levelAttribute).'=('.$alias.'.'.$db->quoteColumnName($tree->levelAttribute).'-'.$i.') AND '. $db->quoteColumnName('t_'.$i).'.'.$db->quoteColumnName($this->aliasAttribute).'='.CDbCriteria::PARAM_PREFIX.CDbCriteria::$paramCount; $criteria->params[CDbCriteria::PARAM_PREFIX.CDbCriteria::$paramCount++]= $v; if($tree->hasManyRoots) $criteria->join .= ' AND '.$db->quoteColumnName('t_'.$i).'.'.$db->quoteColumnName($tree->rootAttribute). '='.$alias.'.'.$db->quoteColumnName($tree->rootAttribute); $criteria->addCondition($db->quoteColumnName('t_'.$i).'.'.$db->quoteColumnName($this->aliasAttribute).' IS NOT NULL'); $i++; } } return $owner->find(); } /** * Возвращает массив вида для всех предков текущей модели * array( * 'заголовок'=>'путь' * ) * * @param bool $withRoot запрашивать данные корня дерева * @param bool $withCurrent вставлять данные текущей модели * @return array */ public function getBreadcrumbs($withRoot=false, $withCurrent=false) { $owner=$this->getOwner(); if($owner->isRoot() && $withRoot) return array($this->getTitle()=>$this->getAlias()); $criteria=$owner->getDbCriteria(); $criteria->select=$this->titleAttribute.', '.$this->aliasAttribute; if(!$withRoot) { $db=$owner->getDbConnection(); $criteria->addCondition($db->quoteColumnName($owner->getTableAlias()).'.'.$db->quoteColumnName($owner->{$this->nestedSetBehaviorName}->leftAttribute).'>1'); } $ancestors=$owner->ancestors()->findAll(); if($ancestors==null && !$withCurrent) return null; else { if($ancestors!=null) $pathList=CHtml::listData($ancestors, $this->titleAttribute, $this->aliasAttribute); if($withCurrent) $pathList[$this->getTitle()]=$this->getAlias(); $titleList=array_keys($pathList); $aliasList=array_values($pathList); foreach($aliasList as $value) { $result[]=implode("/", $aliasList); array_pop($aliasList); } $result=array_reverse($result); return array_combine($titleList, $result); } } /** * Возвращает путь родителя текущей модели * * @param bool $withRoot запрашивать данные корня * @return string */ public function getParentPath($assoc=true, $withRoot=false) { $owner=$this->getOwner(); if($owner->isRoot()) return null; $criteria=$owner->getDbCriteria(); $criteria->select=$this->titleAttribute.', '.$this->aliasAttribute; if(!$withRoot) { $db=$owner->getDbConnection(); $criteria->addCondition($db->quoteColumnName($owner->getTableAlias()).'.'.$db->quoteColumnName($owner->{$this->nestedSetBehaviorName}->leftAttribute).'>1'); } $ancestors=$owner->ancestors()->findAll(); if($ancestors!=null) { $pathList=CHtml::listData($ancestors, $this->titleAttribute, $this->aliasAttribute); return $assoc ? array(end(array_keys($pathList))=>implode("/",array_values($pathList))) : implode("/",array_values($pathList)); } else return null; } /** * Возвращает массив ID потомков текущей модели * * @return array */ public function getChildsPkArray() { $owner=$this->getOwner(); $db=$owner->getDbConnection(); if($owner->isLeaf()) return null; $criteria=$owner->getDbCriteria(); $criteria->select=$db->quoteColumnName($owner->getTableAlias()).'.'.$db->quoteColumnName('id'); $childrens=$owner->descendants()->findAll(); return CHtml::listData($childrens, 'id', 'id'); } }
Private
[
?
]
Run code
Submit