Gentics Portal.Node PHP API
 All Classes Namespaces Functions Variables Pages
PersonalizedContent.php
1 <?php
2 /**
3  * Gentics Portal.Node PHP
4  * Author & Copyright (c) by Gentics Software GmbH
5  * sales@gentics.com
6  * http://www.gentics.com
7  * Licenses can be found in the LICENSE.txt file in the root-folder of this installation
8  * You must not use this software without a valid license agreement.
9  *
10  * Class for working with Gentics Content Connector
11  */
12 class PersonalizedContent extends CComponent
13 {
14 
15  /**
16  * @var array $folderIds contains folder IDs of content to show
17  */
18  public $folderIds;
19 
20  /**
21  * @var string $gccRequestParams contains parameters that should be requested fron GCC
22  */
23  public $gccRequestParams;
24 
25  /**
26  * @var string $lang contains current languagecode
27  */
28  public $lang;
29 
30  /**
31  * @var string $tag contains content required tag
32  */
33  public $tag;
34 
35  /**
36  * array that contains categories tree
37  * @var $data
38  */
39 
40  public $data = array();
41 
42  /**
43  * @var string $sorting contains sorting expression
44  */
45  public $sorting;
46 
47  /**
48  * @var bool $usePersonalisation defines if personalisation should be performed
49  */
50  public $usePersonalisation = true;
51 
52  /**
53  * Construction that will load nodes tree for given $folderIds
54  *
55  * @param array $folderIds contains folder IDs of content to show
56  * @param bool $usePersonalisation determines if personalization should be performed
57  * @param string $tag content tag
58  *
59  * @return \personalizedContent
60  */
61  public function __construct($folderIds = array(), $usePersonalisation = true, $tag = '', $gccRequestParams = null, $sorting = null)
62  {
63 
64  //Yii::app()->cache->flush();
65 
66  if (!empty($folderIds)) {
67 
68  $this->lang = substr(Yii::app()->language, 0, 2);
69  $this->gccRequestParams = isset($gccRequestParams)? $gccRequestParams : Yii::app()->getModule('personalizedContent')->gccRequestParams;
70  $this->sorting = isset($sorting)? $sorting : Yii::app()->getModule('personalizedContent')->sorting;
71  $this->usePersonalisation = $usePersonalisation;
72  $this->tag = $tag;
73 
74  $this->folderIds = $folderIds;
75  sort($this->folderIds);
76 
77  $this->_loadData();
78  $this->_cleanUp(Yii::app()->user->id);
79 
80  } else {
81  return false;
82  }
83  }
84 
85  /**
86  * Filter tree by some schema
87  *
88  * @param integer $user_id Id of the user to personalize tree for
89  *
90  * @return array
91  */
92  private function _cleanUp($user_id)
93  {
94  $maxTimestamp = $this->loadMaxUpdatetimestamp();
95  $cacheId = 'persContent_PERS_'.md5(implode(',', $this->folderIds).$this->lang.$this->gccRequestParams.$this->sorting.$maxTimestamp.$this->tag);
96 
97  if (($data = Yii::app()->cache->get($cacheId)) === false) {
98  //get personalisation fields from settings
99  $filters = $this->getFiltersList();
100  $data = array();
101 
102  // apply filter here
103  if ($filters && $this->data) {
104  foreach ($this->data as $id=>$contentPage) {
105  if (!is_null($this->_unsetNodes($filters, $user_id, $contentPage))) {
106  $data[$id] = $contentPage;
107  }
108  }
109  }
110 
111  $this->data = $data;
112 
113  Yii::app()->cache->set($cacheId, $this->data);
114  } else {
115  $this->data = $data;
116  }
117  }
118 
119  /**
120  * Private method that will unset not allowed data
121  *
122  * @param array $filters contains keys that will be used as filters
123  * @param array $user_id contains user permissions
124  * @param array $data points to the array with nodes tree
125  *
126  * @return array|null
127  */
128  private function _unsetNodes($filters, $user_id, $data)
129  {
130  /* check permissions for current node */
131  $persAttributes = array();
132  foreach ($filters as $filter) {
133  if (!empty($data['attributes'][$filter])) {
134  $persAttributes = array_merge($persAttributes, $data['attributes'][$filter]);
135  }
136  }
137 
138  //check if page has allowed startpageurl and exlude the branch if it does not.
139  $excludeURLs = Yii::app()->getModule('personalizedContent')->excludeURLs;
140  if ((isset($data['attributes']['url']) && in_array($data['attributes']['url'], $excludeURLs)) || !isset($data['attributes']['url'])) {
141  return null;
142  }
143 
144  // Call function that will check permissions
145  if ($this->usePersonalisation) {
146  if (!Yii::app()->getModule('personalisation')->rule->checkAccess($user_id, $persAttributes)) {
147  /* if user does not have permissions - unset the node */
148  return null;
149  }
150  }
151 
152  return $data;
153  }
154 
155  /**
156  * Filter tree by some schema
157  *
158  * @return array|bool
159  */
160  public function getFiltersList()
161  {
162  if (Yii::app()->getModule('contentSource')->contentSource->usePersonalisation) {
163  $filters = Yii::app()->getModule('contentSource')->contentSource->personalisationFields;
164  return $filters;
165  }
166 
167  return false;
168  }
169 
170  /**
171  * Load required tree data from cache. If not exists request Gentics Content Connector API for a new tree.
172  *
173  * @return array
174  */
175  private function _loadData()
176  {
177  $data = array();
178  $filtersList = '';
179 
180  $this->gccRequestParams = rtrim($this->gccRequestParams, ',');
181  $requertFields = explode(',', $this->gccRequestParams);
182 
183  $requertFields[] = 'updatetimestamp';
184  $requertFields[] = 'name';
185  $requertFields[] = 'url';
186 
187  $requertFields = array_unique($requertFields);
188 
189  // get max timestamp for given folderIds
190  $maxTimestamp = $this->loadMaxUpdatetimestamp();
191 
192  //create cache key that includes folderIds+language+gccRequestString+timestamp of last updated folder;
193  $cacheId = 'persContent_'.md5(implode(',', $this->folderIds).$this->lang.$this->gccRequestParams.$maxTimestamp.$this->tag);
194 
195  //Load data
196  if (($data = Yii::app()->cache->get($cacheId)) === false) {
197  $params = array(
198  'filter' => 'object.obj_type==10007 AND object.hideinoverview != 1 AND object.languagecode=="'.$this->lang.'" AND (object.folder_id=="'.implode('" OR object.folder_id=="', $this->folderIds).'")',
199  'type' => 'php',
200  'sorting' => $this->sorting,
201  );
202 
203  if (!empty($this->tag)) {
204  $params['filter'] .= 'AND object.tagging LIKE "*'.$this->tag.'*"';
205  }
206 
207  $params = Yii::app()->getComponent('repositoryApi')->addAdditionalParameters($params, 'contentRepositorySearch');
208 
209  $data = Yii::app()->repositoryApi->request(
210  $params,
211  CMap::mergeArray($this->getFiltersList(), $requertFields)
212  );
213  $data = unserialize($data);
214 
215  if (isset($data['status']) && $data['status'] == 'ok') {
216  unset($data['status']);
217  } else {
218  $data = array();
219  }
220 
221  Yii::app()->cache->set($cacheId, $data);
222  }
223 
224  $this->data = $data;
225  }
226 
227  /**
228  * extracts max updatetimestamp from array of CMS objects
229  *
230  * @return int|bool
231  */
232  public function loadMaxUpdatetimestamp()
233  {
234  $timestampCacheId = 'persContent_UTS_'.md5(implode(',', $this->folderIds).$this->lang.$this->gccRequestParams.$this->sorting.$this->tag);
235 
236  //try to get $maxTimestamp from cache
237  if (($maxTimestamp = Yii::app()->cache->get($timestampCacheId)) === false) {
238  $params = array(
239  'filter' => 'object.obj_type==10007 AND object.hideinoverview != 1 AND object.languagecode=="'.$this->lang.'" AND (object.folder_id=="'.implode('" OR object.folder_id=="', $this->folderIds).'")',
240  'type' => 'php',
241  'sorting' => $this->sorting,
242  );
243  if (!empty($this->tag)) {
244  $params['filter'] .= 'AND object.tagging LIKE "*'.$this->tag.'*"';
245  }
246 
247  $params = Yii::app()->getComponent('repositoryApi')->addAdditionalParameters($params, 'contentRepositorySearch');
248 
249  $timestamps = Yii::app()->repositoryApi->request(
250  $params,
251  array('updatetimestamp')
252  );
253  $timestamps = unserialize($timestamps);
254 
255  if (isset($timestamps['status']) && $timestamps['status']=='ok') {
256  unset($timestamps['status']);
257  $maxTimestamp = 0;
258  foreach ($timestamps as $id=>$contentFolder) {
259  if (isset($contentFolder['attributes']['updatetimestamp']) && $contentFolder['attributes']['updatetimestamp'] > $maxTimestamp) {
260  $maxTimestamp = $contentFolder['attributes']['updatetimestamp'];
261  }
262  }
263 
264  Yii::app()->cache->set($timestampCacheId, $maxTimestamp, Yii::app()->getModule('personalizedContent')->cacheTime);
265  } else {
266  $maxTimestamp = false;
267  }
268  }
269  return $maxTimestamp;
270  }
271 }