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  'pages' => $comments['pages']
75  )
76  );
77  }
78 
79  /**
80  * Load comments from cache.
81  *
82  * @return Like
83  */
84  private function _loadComments()
85  {
86  $currentPage = $this->getCurrentPage();
87  $manageCommentsAccess = Yii::app()->user->checkAccess('manageComments');
88  $isEmailModerator = $manageCommentsAccess ? false : CommentsModule::isEmailModerator(Yii::app()->user->email);
89  //Complex cacheId. Merge dependency on: contentId, if user is administrator and if user is moderator.
90  //For all administrator users cache is generic.
91  //For each moderator user cache is specific.
92  //For all other users cache is generic.
93  $cacheId = md5(
94  implode(
95  ',',
96  array(
97  'parentComments',
98  $this->contentId,
99  $currentPage,
100  $manageCommentsAccess,
101  $isEmailModerator ? Yii::app()->user->email : null
102  )
103  )
104  );
105  //load comments hierarchy
106  if (($comments = Yii::app()->cache->get($cacheId)) === false) {
107  $criteria = new CDbCriteria();
108  $criteria->addCondition('t.content_id=:content_id');
109  if (!$manageCommentsAccess) {
110  if ($isEmailModerator) {
111  $criteria->addCondition('(t.moderator_email=:moderator_email OR t.status=:status)');
112  $criteria->params[':moderator_email'] = Yii::app()->user->email;
113  } else {
114  $criteria->addCondition('t.status=:status');
115  }
116  $criteria->params[':status'] = Comment::APPROVED;
117  }
118  $criteria->order = 't.createtime DESC';
119  $criteria->params[':content_id'] = (string)$this->contentId;
120 
121  //apply pagination
122  $commentsTotal = Comment::model()->isParent()->count($criteria);
123  $paginator = new CPagination($commentsTotal);
124  $paginator->pageSize = $this->commentsPerPage;
125  $paginator->currentPage = $currentPage;
126  $paginator->applyLimit($criteria);
127  $comments = Comment::model()->isParent()->findAll($criteria);
128 
129  $childComments = array();
130  if ($this->oneLevelReply) {
131  $pIds = array();
132  foreach ($comments as $pc) {
133  $pIds[] = $pc->id;
134  }
135  $criteria->addInCondition('parent_id', $pIds);
136  $criteria->order = 't.createtime ASC';
137  $criteria->limit = -1;
138  $criteria->offset = -1;
139  $childComments = Comment::model()->findAll($criteria);
140  $childrenByParents = array();
141  foreach ($childComments as $cc) {
142  $childrenByParents[$cc->parent_id][] = $cc;
143  }
144  foreach ($comments as $pc) {
145  $pc->childs = !empty($childrenByParents[$pc->id]) ? $childrenByParents[$pc->id] : array();
146  }
147  }
148 
149  //save to cache
150  if (Yii::app()->db->getDriverName() == 'mysql') {
151  //use MySql specific function for dependency
152  $dependency = new CDbCacheDependency("SELECT group_concat(id, ' - ' ,status) FROM " . Comment::model()->tableName() . " WHERE content_id=:content_id ");
153  $dependency->params['content_id'] = $this->contentId;
154  } else {
155  //use general sql expression for all db. more memory usage
156  $dependency = new CExpressionDependency(
157  'Yii::app()->db->createCommand()->select("id, status")->from(Comment::model()->tableName())->where("content_id=:content_id", array("content_id" => ' . $this->contentId . '))->queryAll()'
158  );
159  }
160  $comments = array(
161  'comments' => $comments,
162  'countWithChildren' => count($comments) + count($childComments),
163  'total' => $commentsTotal,
164  'pages' => $paginator
165  );
166  Yii::app()->cache->set($cacheId, $comments, Yii::app()->getModule('comments')->cacheTime, $dependency);
167  }
168 
169  return $comments;
170  }
171 
172  /**
173  * Returns current page
174  *
175  * @return integer
176  */
177  public function getCurrentPage()
178  {
179  return Yii::app()->request->getParam("clw{$this->contentId}", 0);
180  }
181 
182  /**
183  * Check if reply possibility allowed for current comments list
184  *
185  * @return bool flag that shows if user allowed reply for comment or not
186  */
187  public function canReply()
188  {
189  return $this->oneLevelReply && $this->formWidget && ($this->formWidget->allowAnonymous || !Yii::app()->user->isGuest);
190  }
191 
192  /**
193  * Returns current page
194  *
195  * @param integer $page page number
196  *
197  * @return string
198  */
199  public function createPaginationUrl($page)
200  {
201  $url = Yii::app()->request->getUrl();
202  $name = "clw{$this->contentId}";
203  $newParam = "clw{$this->contentId}=$page";
204  if (($oldValue = Yii::app()->request->getParam($name)) !== null) {
205  $url = str_replace("$name=$oldValue", $newParam, $url);
206  } else {
207  if (strpos($url, '?') !== false) {
208  $url .= '&' . $newParam;
209  } else {
210  $url .= '?' . $newParam;
211  }
212  }
213  $url .= '#list_' . $this->contentId;
214 
215  return $url;
216  }
217 
218  /**
219  * Returns comment attributes
220  *
221  * @param array $comments array of comments
222  *
223  * @return array
224  */
225  public function getSafeCommentAttributes($comments)
226  {
227  $commentsAttributes = array();
228  foreach ($comments as $parent) {
229  $parentData = array(
230  'id' => $parent->id,
231  'subject' => $parent->subject
232  );
233  foreach ($parent->childs as $child) {
234  $parentData['childs'][] = array(
235  'id' => $child->id,
236  'subject' => $child->subject
237  );
238  }
239  $commentsAttributes[] = $parentData;
240  }
241  return $commentsAttributes;
242  }
243 
244  /**
245  * Get comment author avatar image
246  *
247  * @param array $comment a comment
248  *
249  * @return String
250  */
251  public function getAvatar($comment)
252  {
253  return Gravatar::getImage($comment->email, Yii::app()->request->isSecureConnection ? 'https' : 'http');
254  }
255 }
256 
257 ?>