Gentics Portal.Node PHP API
 All Classes Namespaces Functions Variables Pages
CommentsListWidget.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  * Widget for view comments for current model
11  */
13 {
14  /**
15  * @var bool If threaded commenting allowed (only 1 level)
16  */
17  public $oneLevelReply = false;
18 
19  /**
20  * @var string Widget options hash, to get this options in controller
21  */
22  public $hash;
23 
24  /**
25  * @var CommentsFormWidget comment form which is used together with this CommentsListWidget
26  */
27  public $formWidget;
28 
29  /**
30  * @var int comments per page
31  */
32  public $commentsPerPage = 5;
33 
34  /**
35  * @var int how many pagination pages numbers will be displayed at the same time
36  */
37  public $paginationPagesCount = 5;
38 
39  /**
40  * Make widgets options hash key and store options in session
41  *
42  * @return void
43  */
44  public function init()
45  {
46  parent::init();
47  $assetsUrl = Yii::app()->getModule('comments')->getAssetsUrl();
48  Yii::app()->clientScript->registerCssFile($assetsUrl . '/css/pagination.css');
49  Yii::app()->clientScript->registerScriptFile($assetsUrl . '/js/initCommentsReply.js');
50 
51  $options = array(
52  'contentId' => $this->contentId
53  );
54  $this->hash = md5(serialize($options) . Yii::app()->getModule('comments')->hashSalt);
55  if (Yii::app()->cache->get($this->hash) != $options) {
56  Yii::app()->cache->set($this->hash, $options);
57  }
58  }
59 
60  /**
61  * Find all comments by contentId. Preload child comments.
62  *
63  * @return void
64  */
65  public function run()
66  {
67  $comments = $this->_loadComments();
68  $this->render(
69  'CommentsListWidget',
70  array(
71  'comments' => $comments['comments'],
72  'commentsTotal' => $comments['total'],
73  'commentsCountWithChildren' => $comments['countWithChildren']
74  )
75  );
76  }
77 
78  /**
79  * Load comments from cache.
80  *
81  * @return Like
82  */
83  private function _loadComments()
84  {
85  $currentPage = $this->getCurrentPage();
86  $manageCommentsAccess = Yii::app()->user->checkAccess('manageComments');
87  $isEmailModerator = $manageCommentsAccess ? false : CommentsModule::isEmailModerator(Yii::app()->user->email);
88  //Complex cacheId. Merge dependency on: contentId, if user is administrator and if user is moderator.
89  //For all administrator users cache is generic.
90  //For each moderator user cache is specific.
91  //For all other users cache is generic.
92  $cacheId = md5(
93  implode(
94  ',',
95  array(
96  'parentComments',
97  $this->contentId,
98  $currentPage,
99  $manageCommentsAccess,
100  $isEmailModerator ? Yii::app()->user->email : null
101  )
102  )
103  );
104  //load comments hierarchy
105  if (($comments = Yii::app()->cache->get($cacheId)) === false) {
106  $criteria = new CDbCriteria();
107  $criteria->addCondition('t.content_id=:content_id');
108  if (!$manageCommentsAccess) {
109  if ($isEmailModerator) {
110  $criteria->addCondition('(t.moderator_email=:moderator_email OR t.status=:status)');
111  $criteria->params[':moderator_email'] = Yii::app()->user->email;
112  } else {
113  $criteria->addCondition('t.status=:status');
114  }
115  $criteria->params[':status'] = Comment::APPROVED;
116  }
117  $criteria->order = 't.createtime DESC';
118  $criteria->params[':content_id'] = (string)$this->contentId;
119 
120  //apply pagination
121  $commentsTotal = Comment::model()->isParent()->count($criteria);
122  $paginator = new CPagination($commentsTotal);
123  $paginator->pageSize = $this->commentsPerPage;
124  $paginator->currentPage = $currentPage;
125  $paginator->applyLimit($criteria);
126  $comments = Comment::model()->isParent()->findAll($criteria);
127 
128  $childComments = array();
129  if ($this->oneLevelReply) {
130  $pIds = array();
131  foreach ($comments as $pc) {
132  $pIds[] = $pc->id;
133  }
134  $criteria->addInCondition('parent_id', $pIds);
135  $criteria->order = 't.createtime ASC';
136  $criteria->limit = -1;
137  $criteria->offset = -1;
138  $childComments = Comment::model()->findAll($criteria);
139  $childrenByParents = array();
140  foreach ($childComments as $cc) {
141  $childrenByParents[$cc->parent_id][] = $cc;
142  }
143  foreach ($comments as $pc) {
144  $pc->childs = !empty($childrenByParents[$pc->id]) ? $childrenByParents[$pc->id] : array();
145  }
146  }
147 
148  //save to cache
149  if (Yii::app()->db->getDriverName() == 'mysql') {
150  //use MySql specific function for dependency
151  $dependency = new CDbCacheDependency("SELECT group_concat(id, ' - ' ,status) FROM " . Comment::model()->tableName() . " WHERE content_id=:content_id ");
152  $dependency->params['content_id'] = $this->contentId;
153  } else {
154  //use general sql expression for all db. more memory usage
155  $dependency = new CExpressionDependency(
156  'Yii::app()->db->createCommand()->select("id, status")->from(Comment::model()->tableName())->where("content_id=:content_id", array("content_id" => ' . $this->contentId . '))->queryAll()'
157  );
158  }
159  $comments = array(
160  'comments' => $comments,
161  'countWithChildren' => count($comments) + count($childComments),
162  'total' => $commentsTotal,
163  );
164  Yii::app()->cache->set($cacheId, $comments, Yii::app()->getModule('comments')->cacheTime, $dependency);
165  }
166 
167  return $comments;
168  }
169 
170  /**
171  * Returns current page
172  *
173  * @return integer
174  */
175  public function getCurrentPage()
176  {
177  return Yii::app()->request->getParam("clw{$this->contentId}", 0);
178  }
179 
180  /**
181  * Check if reply possibility allowed for current comments list
182  *
183  * @return bool flag that shows if user allowed reply for comment or not
184  */
185  public function canReply()
186  {
187  return $this->oneLevelReply && $this->formWidget && ($this->formWidget->allowAnonymous || !Yii::app()->user->isGuest);
188  }
189 
190  /**
191  * Returns current page
192  *
193  * @param integer $page page number
194  *
195  * @return string
196  */
197  public function createPaginationUrl($page)
198  {
199  $url = Yii::app()->request->getUrl();
200  $name = "clw{$this->contentId}";
201  $newParam = "clw{$this->contentId}=$page";
202  if (($oldValue = Yii::app()->request->getParam($name)) !== null) {
203  $url = str_replace("$name=$oldValue", $newParam, $url);
204  } else {
205  if (strpos($url, '?') !== false) {
206  $url .= '&' . $newParam;
207  } else {
208  $url .= '?' . $newParam;
209  }
210  }
211  $url .= '#list_' . $this->contentId;
212 
213  return $url;
214  }
215 
216  /**
217  * Returns comment attributes
218  *
219  * @param array $comments array of comments
220  *
221  * @return array
222  */
223  public function getSafeCommentAttributes($comments)
224  {
225  $commentsAttributes = array();
226  foreach ($comments as $parent) {
227  $parentData = array(
228  'id' => $parent->id,
229  'subject' => $parent->subject
230  );
231  foreach ($parent->childs as $child) {
232  $parentData['childs'][] = array(
233  'id' => $child->id,
234  'subject' => $child->subject
235  );
236  }
237  $commentsAttributes[] = $parentData;
238  }
239  return $commentsAttributes;
240  }
241 
242  /**
243  * Get comment author avatar image
244  *
245  * @param array $comment a comment
246  *
247  * @return String
248  */
249  public function getAvatar($comment)
250  {
251  return Gravatar::getImage($comment->email, Yii::app()->request->isSecureConnection ? 'https' : 'http');
252  }
253 }
254 
255 ?>