<?php

/**
 * This is the model class for table "authitem".
 *
 * The followings are the available columns in table 'authitem':
 * @property string $name
 * @property integer $type
 * @property string $description
 * @property string $bizrule
 * @property string $data
 */
class AuthItem extends ActiveRecord
{

  /**
   * Returns the static model of the specified AR class.
   *
   * @param string $className
   *          active record class name.
   * @return AuthItem the static model class
   */
  public static function model($className = __CLASS__)
  {
    return parent::model ( $className );
  }

  /**
   *
   * @return string the associated database table name
   */
  public function tableName()
  {
    return 'authitem';
  }

  /**
   *
   * @return array validation rules for model attributes.
   */
  public function rules()
  {
    // NOTE: you should only define rules for those attributes that
    // will receive user inputs.
    return array (
        array (
            'name, type',
            'required' 
        ),
        array (
            'type',
            'numerical',
            'integerOnly' => true 
        ),
        array (
            'name',
            'length',
            'max' => 64 
        ),
        array (
            'description, bizrule, data',
            'safe' 
        ),
        // The following rule is used by search().
        // Please remove those attributes that should not be searched.
        array (
            'name, type, description, bizrule, data',
            'safe',
            'on' => 'search' 
        ) 
    );
  }

  /**
   * create an item if doesn't exist
   *
   * @param string $name
   *          name of the item
   * @param integer $type
   *          type of the item
   * @return boolean
   */
  public static function createItem($name, $type = 0)
  {
    return AuthItem::ensureExists ( $name, $type );
  }

  private static $ensureExistsCache = array ();

  /**
   * create an item if doesn't exist
   *
   * @param string $name
   *          name of the item
   * @param integer $type
   *          type of the item
   * @return boolean
   */
  public static function ensureExists($operation, $type = 0)
  {
    if (! isset ( self::$ensureExistsCache [$operation] ))
    {
      $cnt = AuthItem::model ()->count ( 'name=:nm', array (
          'nm' => $operation 
      ) );
      if ($cnt <= 0)
      {
        $item = new AuthItem ();
        $item->name = $operation;
        $item->type = $type;
        $item->description = createBeautifulString ( $operation ) . " (autogenerated)";
        $item->data = 'N;';
        return $item->insert ();
      }
      else
        self::$ensureExistsCache [$operation] = 1;
    }
    return true;
  }

  /**
   * delete an item if exists
   *
   * @param string $name
   *          name of the item
   * @return boolean
   */
  public static function deleteItem($name)
  {
    $item = AuthItem::model ()->find ( 'name=:nm', array (
        ':nm' => $name 
    ) );
    if ($item != null)
      return $item->delete ();
    return true;
  }

  /**
   *
   * @param string $name          
   * @return AuthItem[]
   */
  public static function findLike($name)
  {
    return AuthItem::model ()->findAll ( 'name LIKE :nm', array (
        ':nm' => $name 
    ) );
  }

  /**
   *
   * @param string $name          
   * @return AuthItem
   */
  public static function findItem($name)
  {
    return AuthItem::model ()->find ( 'name=:nm', array (
        ':nm' => $name 
    ) );
  }

  /**
   *
   * @param string $name          
   * @return string
   */
  public static function countLike($name)
  {
    return AuthItem::model ()->count ( 'name LIKE :nm', array (
        ':nm' => $name 
    ) );
  }

  /**
   *
   * @return array relational rules.
   */
  public function relations()
  {
    // NOTE: you may need to adjust the relation name and the related
    // class name for the relations automatically generated below.
    return array (
        'childs' => array (
            self::MANY_MANY,
            'AuthItem',
            'authitemchild(parent, child)' 
        ),
    	'childLinks' => array (
    		self::HAS_MANY,
    		'AuthItemChild',
    		'parent'
    		)
    );
  }

  /**
   *
   * @return array customized attribute labels (name=>label)
   */
  public function myAttributeLabels()
  {
    return array (
        'name' => Yii::t ( 'app', 'Name' ),
        'type' => Yii::t ( 'app', 'Type' ),
        'description' => Yii::t ( 'app', 'Description' ),
        'bizrule' => Yii::t ( 'app', 'Bizrule' ),
        'data' => Yii::t ( 'app', 'Data' ) 
    );
  }

  /**
   *
   * @return string
   */
  public function getTypeName()
  {
    switch ($this->type)
    {
      case 0 :
        return 'Operation';
      case 1 :
        return 'Task';
      case 2 :
        return 'Role';
      default :
        return 'Unknown';
    }
  }

  /**
   * Retrieves a list of models based on the current search/filter conditions.
   *
   * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
   */
  public function search()
  {
    // Warning: Please modify the following code to remove attributes that
    // should not be searched.
    $criteria = new CDbCriteria ();
    
    $criteria->compare ( 'name', $this->name, true );
    $criteria->compare ( 'type', $this->type );
    $criteria->compare ( 'description', $this->description, true );
    $criteria->compare ( 'bizrule', $this->bizrule, true );
    $criteria->compare ( 'data', $this->data, true );
    
    return new CActiveDataProvider ( $this, array (
        'criteria' => $criteria 
    ) );
  }

  public static function getLabelByName($name)
  {
    $item = AuthItem::model ()->find ( 'name=:name', array (
        ':name' => $name 
    ) );
    if ($item === null)
      return null;
    return $item->description;
  }

  /**
   *
   * @param string $prefix          
   * @return boolean
   */
  public static function existsWithPrefix($prefix)
  {
    return AuthItem::model ()->count ( "name LIKE '$prefix%'" ) > 0;
  }

  /**
   *
   * @return AuthItem[]
   */
  public static function getAll($orderBy = null, $filter = null)
  {
    $model = AuthItem::model ();
    if ($filter !== null)
      if (is_array ( $filter ))
        $model->dbCriteria->addCondition ( 'type IN (' . implode ( ',', $filter ) . ')' );
      else
        $model->dbCriteria->addCondition ( 'type=' . $filter );
    if (! empty ( $orderBy ))
      $model->dbCriteria->order = $orderBy;
    return $model->findAll ();
  }

  /**
   *
   * @return string[]
   */
  public static function getAllNames($orderBy = null, $filter = null)
  {
    $names = array ();
    foreach ( self::getAll ( $orderBy, $filter ) as $item )
      $names [] = $item->name;
    return $names;
  }

  /**
   *
   * @return AuthItem[]
   */
  public static function getAllTree($parent)
  {
    $all = self::model ()->findAll ( 'name=:name', array (
        ':name' => $parent 
    ) );
    $names = new CQueue ();
    foreach ( $all as $aa )
    {
      $names->enqueue ( $aa->name );
      $seen [] = $aa->name;
    }
    
    $assignments = array ();
    $assNames = array ();
    $seen = array ();
    while ( $names->count () > 0 )
    {
      $itemName = $names->dequeue ();
      $item = AuthItem::findItem ( $itemName );
      if ($item != null && ! array_value_exists ( $assNames, $item->name ))
      {
        $assNames [] = $item->name;
        $assignments [] = $item;
      }
      
      $childs = AuthItemChild::model ()->findAll ( 'parent=:prnt', array (
          ':prnt' => $itemName 
      ) );
      foreach ( $childs as $chld )
        if (! array_value_exists ( $seen, $chld->child ))
        {
          $names->enqueue ( $chld->child );
          $seen [] = $chld->child;
        }
    }
    
    return $assignments;
  }
}