[ create a new paste ] login | about

Link: http://codepad.org/XBhyQfxb    [ raw code | output | fork ]

PHP, pasted on Oct 22:
<?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');
    }         
}


Output:
1
2

Fatal error: Class 'CActiveRecordBehavior' not found on line 8


Create a new paste based on this one


Comments: