Gentics Portal.Node PHP API
 All Classes Namespaces Functions Variables Pages
ApaLinesWidget.php
1 <?php
2 /**
3  * Class for collecting necessary information about news from database
4  *
5  * @author Andrew Voloshin <andrew.voloshin@oberig.com>
6  *
7  *
8  */
9 class ApaLinesWidget extends CWidget
10 {
11  /**
12  * @var string comma separated names of the channels
13  */
14  public $channel;
15  /**
16  * @var string max age of news which are being visible starting from the newest
17  */
18  public $max_age_of_news;
19  /**
20  * @var string max count of news which are being visible starting from the newest
21  */
22  public $max_count_of_news;
23  /**
24  * @var string the data to return from widget
25  */
26  public $data;
27  /**
28  * Method collects overview info or detailed info about news line if id passed as $_GET['id']
29  */
30  public function init()
31  {
32  $module = Yii::app()->getModule('apalines');
33  //Trim channels
34  $this->channel = explode(',', $this->channel);
35  $this->channel = array_map('trim', $this->channel);
36  $cacheId = $this->getCacheId();
37 
38  if(false == ($this->data = Yii::app()->cache->get($cacheId))){
39  $id = Yii::app()->request->getParam('id');
40  if(!isset($id) || !$id){
41  $this->setOverviewData();
42  }else{
43  $this->setDetailedData(Yii::app()->request->getParam('id'));
44  }
45  Yii::app()->cache->set($cacheId, $this->data, $module->cacheTime);
46  }
47  }
48  /**
49  * Method collects detailed info about news line with DOCID of filename which was passed as $_GET['id']
50  *
51  * @param string $id DOCID or filename of news line
52  */
53  private function setDetailedData($id)
54  {
55  $line = ApalinesNews::model()->find('docid = :id OR filename = :id', array(
56  ':id' => $id
57  ));
58 
59  if(isset($line)){
60  $this->data = $this->lineToArray($line);
61  }
62  }
63  /**
64  * Method collects overview info about news in channels which were passed to widget
65  */
66  private function setOverviewData()
67  {
68  $this->data = array();
69 
70  $module = Yii::app()->getModule('apalines');
71  $channelNames = $this->channel;
72  //If should be shown one channel
73  if (count($channelNames) == 1) {
74 
75  $channelName = $channelNames[0];
76  if (isset($module->channels[$channelName])) {
77  $channelSettings = $module->channels[$channelName];
78  }
79  if (isset($channelSettings)) {
80  if (!isset($this->max_age_of_news)) {
81  $this->max_age_of_news = $channelSettings['max_age_of_news'];
82  }
83  if (!isset($this->max_count_of_news)) {
84  $this->max_count_of_news = $channelSettings['max_count_of_news'];
85  }
86  }
87  if (!isset($this->max_age_of_news)) {
88  $this->max_age_of_news = $channelSettings['max_age_of_news'];
89  }
90  if (!isset($this->max_count_of_news)) {
91  $this->max_count_of_news = $channelSettings['max_count_of_news'];
92  }
93 
94  } else {
95  //If should be shown few channels
96  $channelsCount = count($channelNames);
97 
98  if (!isset($this->max_age_of_news)) {
99  $this->max_age_of_news = $module->total_max_age_of_news;
100  }
101  if (!isset($this->max_count_of_news)) {
102  $this->max_count_of_news = $module->total_max_count_of_news;
103  }
104  //If news count is not divided into count of channels without remainder
105  $modulo = $this->max_count_of_news % $channelsCount;
106  $this->max_count_of_news = (integer)($this->max_count_of_news / $channelsCount);
107  }
108 
109  //Go throw the channels
110  foreach ($channelNames as $channelName){
111 
112  //equalize count by adding modulo to max count news of first channel
113  $max_count_of_news = $this->max_count_of_news;
114  if(count($channelNames) > 1 && isset($modulo)){
115  $max_count_of_news += $modulo;
116  }
117  //Finding the news and adding them to $data
118  $news = ApalinesNews::model()->findAll(array(
119  'condition' => 'channel = :channel AND deleted <> 1 AND (FROM_UNIXTIME(ndate) > (NOW() - interval :max_age_of_news hour))',
120  'order' => 'ndate DESC',
121  'limit' => $max_count_of_news,
122  'params' => array(
123  ':channel' => $channelName,
124  ':max_age_of_news' => $this->max_age_of_news
125  )
126  ));
127 
128  foreach ($news as $line) {
129  if (empty($line->related_maindoc_id)) {
130  $this->data[] = $this->lineToArray($line);
131  }
132  }
133  }
134  }
135  /**
136  * Method migrates date from model of news line to array , it is used for news and background news
137  * it also bind multimedia to news and background news
138  *
139  * @param object $line model of a news line or background news line
140  * @return array - news or background line date
141  */
142  private function lineToArray($line)
143  {
144  $data = array();
145  $bg_news = array();
146  $multimedia = array();
147  //main news line parameters
148  $data['doc_id'] = $line->docid;
149  $data['has_bg_news'] = $line->background_news;
150  $data['title'] = $line->title;
151  $data['place'] = $line->place;
152  $data['source'] = $line->source;
153  $data['header'] = $line->teaser;
154  $data['text'] = $line->content;
155  $data['author'] = $line->author;
156  $data['keywords'] = $line->keywords;
157  $data['filename'] = $line->filename;
158  $data['channel'] = $line->channel;
159  $data['date'] = $date = date('Y-m-d G:i:s',$line->ndate);
160  $data['detailed_link'] = $_SERVER['REDIRECT_URL']."?id=".$line->filename;
161 
162  foreach($line->bg_news as $bg_line){
163  $bg_news[] = $this->lineToArray($bg_line);
164  }
165  $data['bg_news'] = $bg_news;
166 
167  foreach($line->multimedia as $mm_line){
168  $multimedia[] = $this->mm_lineToArray($mm_line);
169  }
170  $data['multimedia'] = $multimedia;
171 
172  return $data;
173  }
174  /**
175  * Method migrates date from model of multimedia line to array , it is used for images and videos object
176  * it also bind files (thumbnails, originals) which represents this multimedia
177  *
178  * @param object $line model of a multimedia line
179  * @return array - multimedia line date
180  */
181  private function mm_lineToArray($mm_line){
182 
183  $data = array();
184 
185  $docid = $data['doc_id'] = $mm_line->docid;
186  $customer_number = Yii::app()->getModule('apalines')->customer_number;
187  $data['title'] = $mm_line->title;
188  $data['place'] = $mm_line->place;
189  $data['source'] = $mm_line->source;
190  $data['author'] = $mm_line->author;
191  $data['keywords'] = $mm_line->keywords;
192  $data['filename'] = $mm_line->filename;
193  $data['date'] = $date = date('Y-m-d G:i:s',$mm_line->ndate);
194 
195  $data['files'] = array();
196 
197  foreach($mm_line->files as $file){
198  $fileData = array();
199 
200  $fileData['href'] = $this->controller->createAbsoluteUrl("/apalines/{$mm_line->channel}/images/{$file->href}");
201  $fileData['width'] = $file->width;
202  $fileData['height'] = $file->height;
203  $fileData['format'] = $file->format;
204 
205  $type = '';
206  switch ($file->size) {
207  case 0:
208  $type = 'thumbnail';
209  break;
210  case 1:
211  $type = 'original';
212  break;
213  case 2:
214  $type = 'hires';
215  break;
216  }
217  if ($configSize = $this->getSize($type)) {
218  $fileData['width'] = $configSize['width'];
219  $fileData['height'] = $configSize['height'];
220  }
221  if (!isset($fileData['width'])
222  || !isset($fileData['height'])) {
223  $configSize = $this->getSize('default');
224  $fileData['width'] = $configSize['width'];
225  $fileData['height'] = $configSize['height'];
226  }
227  $data['files'][$type] = $fileData;
228  unset($fileData);
229  }
230 
231  switch($mm_line->type) {
232  case 0:
233  $data['type'] = 'image';
234  break;
235  case 1:
236  $videoUrl = Yii::app()->getModule('apalines')->video_url;
237  $videoWidth = 0;
238  $videoHeight = 0;
239  if($videoSize = $this->getSize('video')){
240  $videoWidth = $videoSize['width'];
241  $videoHeight = $videoSize['height'];
242  }else{
243  $videoSize = $this->getSize('default');
244  $videoWidth = $videoSize['width'];
245  $videoHeight = $videoSize['height'];
246  }
247  $data['iframe'] =
248  "<iframe margin='0' padding='0' width='{$videoWidth}px' height='{$videoHeight}px'
249  src='{$videoUrl}?customer={$customer_number}&data={$docid}'
250  border='0' frameborder='0' >";
251 
252  $data['type'] = 'video';
253  break;
254  }
255 
256  return $data;
257  }
258  /**
259  *
260  * Method returns parsed size if it is specified in the config
261  * @param string $type multimedia item type
262  *
263  * @return array - width and height
264  */
265  private function getSize($type) {
266 
267  $module = Yii::app()->getModule('apalines');
268  $type = ucfirst(strtolower($type)) . 'Size';
269  $size = isset($module->$type)?$module->$type:'';
270 
271  $size = explode('x',$size);
272  $size = array_map('trim', $size);
273  if (count($size)==2) {
274  return array(
275  'width' => $size[0],
276  'height'=> $size[1]
277  );
278  }
279  return false;
280  }
281  /**
282  * Method returns youngest timestamp among news lines, background news lines, multimedia lines
283  * coupled with total count of news, background news, multimedia lines those channel names coincided with the passed channels
284  *
285  * @return string - youngest timestamp among news, background news and multimedia concatenated with their number
286  */
287  public function getTimestampAndCount(){
288 
289  $channels = "'".implode("','",$this->channel)."'";
290 
291  $timestamp = Yii::app()->db->createCommand("(SELECT `updated` FROM {{apalines_news}} WHERE `channel` IN ($channels) AND `deleted`<>1)
292  UNION
293  (SELECT `updated` FROM {{apalines_mm}} WHERE `channel` IN ($channels) AND `deleted`<>1)
294  ORDER BY `updated` DESC LIMIT 1
295  ")->queryAll();
296 
297  $timestamp = isset($timestamp[0]['updated'])?$timestamp[0]['updated']:false;
298  $count = Yii::app()->db->createCommand("SELECT ((SELECT COUNT(*) FROM {{apalines_news}} WHERE `channel` IN ($channels))
299  +
300  (SELECT COUNT(*) FROM {{apalines_mm}} WHERE `channel` IN ($channels))) AS `count`
301  ")->queryAll();
302  //To check whether items were removed
303  $count = isset($count[0]['count'])?$count[0]['count']:false;
304 
305  $result = false;
306 
307  if($timestamp && $count){
308  $result = "$timestamp $count";
309  }
310 
311  return $result;
312  }
313  /**
314  * Method returns timestamp of the news line which DOCID or filename was passed
315  *
316  * @param string $id DOCID or filename of the news file
317  * @return string - timestamp
318  */
319  public function getItemTimestamp($id){
320 
321  $timestamp = Yii::app()->db->createCommand("(SELECT `updated` FROM {{apalines_news}} WHERE (`docid` = :id OR `filename` = :id) AND `deleted`<>1)
322  UNION
323  (SELECT `updated` FROM {{apalines_mm}} WHERE (`docid` = :id OR `filename` = :id) AND `deleted`<>1)
324  LIMIT 1
325  ")->bindValue(':id',$id)->queryAll();
326 
327  return isset($timestamp[0]['updated'])?$timestamp[0]['updated']:false;
328  }
329  /**
330  * Method makes cache id for current widget content
331  *
332  * @return string - cache id for widget content
333  */
334  public function getCacheId(){
335  $param = Yii::app()->request->getParam('id');
336  $id = isset($param) && $param != false?$param:false;
337 
338  $cacheId = '';
339  if($id){
340  $cacheId = $this->getItemTimestamp($id);
341  if(!$cacheId){
342  return false;
343  }
344  $cacheId .= $id;
345  }else{
346  $cacheId = $this->getTimestampAndCount();
347  if(!$cacheId){
348  return false;
349  }
350  $cacheId .= $this->channel;
351  $cacheId .= $this->max_age_of_news;
352  $cacheId .= $this->max_count_of_news;
353  }
354  $cacheId = md5($cacheId);
355 
356  return "apa_lines_{$cacheId}";
357  }
358 }