Gentics Portal.Node PHP API
 All Classes Namespaces Functions Variables Pages
PersonalisationAttribute.php
1 <?php
2 
3 /**
4  * Gentics Portal.Node PHP
5  * Author & Copyright (c) by Gentics Software GmbH
6  * sales@gentics.com
7  * http://www.gentics.com
8  * Licenses can be found in the LICENSE.txt file in the root-folder of this installation
9  * You must not use this software without a valid license agreement.
10  *
11  * This is the model class for table "{{personalization_attributes}}".
12  * It represents single personalisation attribute which can be assigned to user.
13  * In database stored hierarchical information about these attributes and they can be represented as tree.
14  *
15  * The followings are the available columns in table '{{personalization_attributes}}':
16  * @property integer $id
17  * @property integer $parent_id
18  * @property string $name
19  * @property string $title
20  * @property string $path
21  */
22 class PersonalisationAttribute extends CActiveRecord
23 {
24 
25  /**
26  * @var array $_flatLists "inclass" cache for personalisation flat rules
27  */
28  private static $_flatLists = array();
29 
30  /**
31  * Returns the static model of the specified AR class.
32  *
33  * @param string $className active record class name.
34  *
35  * @return PersonalisationAttribute the static model class
36  */
37  public static function model($className = __CLASS__)
38  {
39  return parent::model($className);
40  }
41 
42  /**
43  * returnes a table name
44  *
45  * @return string the associated database table name
46  */
47  public function tableName()
48  {
49  return '{{personalisation_attributes}}';
50  }
51 
52  /**
53  * returns validation rules
54  *
55  * @return array validation rules for model attributes.
56  */
57  public function rules()
58  {
59  // NOTE: you should only define rules for those attributes that
60  // will receive user inputs.
61  return array(
62  array('name, title', 'required'),
63  array('name, title', 'common.components.NotContainsTagsValidator'),
64  array('name', 'unique'),
65  array('parent_id', 'numerical', 'integerOnly' => true),
66  array('name, title', 'length', 'max' => 255),
67  array('path', 'safe'),
68  // The following rule is used by search().
69  // Please remove those attributes that should not be searched.
70  array('id, parent_id, name', 'safe', 'on' => 'search'),
71  );
72  }
73 
74  /**
75  * sets id of parent
76  *
77  * @param \PersonalisationAttribute $parent
78  *
79  * @return void
80  */
81  public function childOf(PersonalisationAttribute $parent)
82  {
83  $this->parent_id = $parent->id;
84  $this->path = empty($parent->path) ? '.' . $parent->id . '.' : $parent->path . $parent->id . '.';
85  }
86 
87  /**
88  * Find all children of current personalisation attribute
89  *
90  * @return array
91  */
92  public function getChildren()
93  {
94  return PersonalisationAttribute::model()->findAll("path LIKE '%.{$this->id}.%'");
95  }
96 
97  /**
98  * Get children ids
99  *
100  * @return array
101  */
102  public function getChildrenIds()
103  {
104  $data = Yii::app()->db->createCommand()
105  ->select('id')
106  ->from($this->tableName())
107  ->where("path LIKE '%.{$this->id}.%'")
108  ->queryAll(false);
109  $ids = array_map(
110  function($item)
111  {
112  return $item[0];
113  }, $data
114  );
115 
116  return $ids;
117  }
118 
119  /**
120  * returns relations rules
121  *
122  * @return array relational rules.
123  */
124  public function relations()
125  {
126  // NOTE: you may need to adjust the relation name and the related
127  // class name for the relations automatically generated below.
128  return array(
129  array(self::HAS_MANY, 'UserPersonalisationAttribute', 'personalisation_attribute_id')
130  );
131  }
132 
133  /**
134  * Returns customized attribute labels (name=>label)
135  *
136  * @return array
137  */
138  public function attributeLabels()
139  {
140  return array(
141  'id' => 'ID',
142  'parent_id' => 'Parent',
143  'name' => 'Name',
144  );
145  }
146 
147  /**
148  * Retrieves a list of models based on the current search/filter conditions.
149  *
150  * @return \CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
151  */
152  public function search()
153  {
154  // Warning: Please modify the following code to remove attributes that
155  // should not be searched.
156 
157  $criteria = new CDbCriteria;
158 
159  $criteria->compare('id', $this->id);
160  $criteria->compare('parent_id', $this->parent_id);
161  $criteria->compare('name', $this->name, true);
162 
163  return new CActiveDataProvider(
164  $this,
165  array(
166  'criteria' => $criteria,
167  )
168  );
169  }
170 
171  /**
172  * Delete personalisation attribute with children and UserPersonalisationAttribute records
173  *
174  * @return bool
175  */
176  public function delete()
177  {
178  $transaction = Yii::app()->db->beginTransaction();
179  try {
180  $removeIds = $this->getChildrenIds();
181  if (!empty($removeIds)) {
182  PersonalisationAttribute::model()->deleteAll('id IN (' . implode(',', $removeIds) . ')');
183  }
184  $removeIds[] = $this->id;
185  UserPersonalisationAttribute::model()->deleteAll('personalisation_attribute_id IN (' . implode(',', $removeIds) . ')');
186  $result = parent::delete();
187  $transaction->commit();
188  return $result;
189  } catch (Exception $e) {
190  $transaction->rollback();
191  return false;
192  }
193  }
194 
195  /**
196  * Get personalisation attributes for user in flat list form
197  *
198  * @param int $userId user id
199  * @param bool $cache defines if rrsult should be cached
200  *
201  * @return array
202  */
203  public static function flatListForUser($userId, $cache = true)
204  {
205  $flatList = array();
206  if (!empty($userId)) {
207  if (isset(self::$_flatLists[$userId])) {
208  $flatList = self::$_flatLists[$userId];
209  Yii::trace('Flatlist for userId='.$userId.' taken from inclass cache');
210  } else {
211  $userPersAttributes = UserPersonalisationAttribute::model()
212  ->cache($cache ? Yii::app()->getModule('personalisation')->cacheTime : 0)
213  ->with('personalisationAttribute')
214  ->findAllByAttributes(array('user_id' => $userId));
215  if ($userPersAttributes) {
216  foreach ($userPersAttributes as $attr) {
217  $flatList[] = $attr->personalisationAttribute->name;
218  }
219  }
220  Yii::trace('Flatlist for userId='.$userId.' was put to inclass cache');
221  self::$_flatLists[$userId] = $flatList;
222  }
223  }
224 
225  return $flatList;
226  }
227 
228  /**
229  * Get associative array which represents all existed personalisation attributes in tree structure
230  *
231  * @static
232  *
233  * @return array
234  */
235  public static function getTree()
236  {
237  $personalisationAttributes = PersonalisationAttribute::model()->findAll(
238  array(
239  'order'=>'path ASC,
240  title ASC'
241  )
242  );
243  $tree = array('id' => 0, 'item' => array());
244 
245  foreach ($personalisationAttributes as $attr) {
246  $node = array(
247  'id' => $attr->id,
248  'text' => $attr->title,
249  'userdata' => array(
250  array('name' => 'name', 'content' => $attr->name),
251  array('name' => 'title', 'content' => $attr->title)
252  ),
253  'item' => array()
254  );
255  if ($attr->parent_id === null) {
256  $tree['item'][] = $node;
257  } else {
258  $parent = &self::_findNode($tree, $attr->parent_id);
259  $parent['item'][] = $node;
260  }
261  }
262 
263  return $tree;
264  }
265 
266  /**
267  * Get personalisation attributes tree with user state
268  *
269  * @param integer $userId id uf user
270  *
271  * @return array
272  */
273  public static function getTreeWithUserState($userId)
274  {
275  $tree = self::getTree();
276  $userPAttributes = UserPersonalisationAttribute::model()->findAllByAttributes(array('user_id' => $userId));
277  foreach ($userPAttributes as $pAttr) {
278  $node = &self::_findNode($tree, $pAttr->personalisation_attribute_id);
279  $node['checked'] = 1;
280  }
281  return $tree;
282  }
283 
284  /**
285  * Helper method used for navigating by recursive tree
286  *
287  * @param array &$node link to array branch
288  * @param string $id key to find in array
289  *
290  * @return array|null
291  */
292  private static function &_findNode(&$node, $id)
293  {
294  if ($node['id'] == $id) {
295  return $node;
296  } else {
297  foreach ($node['item'] as &$item) {
298  $res = &self::_findNode($item, $id);
299  if ($res) {
300  return $res;
301  }
302  }
303  }
304  $empty = null;
305  return $empty;
306  }
307 }