These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace SilverStripe\Comments\Model; |
||
4 | |||
5 | use HTMLPurifier_Config; |
||
6 | use HTMLPurifier; |
||
7 | use SilverStripe\Comments\Controllers\CommentingController; |
||
8 | use SilverStripe\Comments\Extensions\CommentsExtension; |
||
9 | use SilverStripe\Comments\Model\Comment\SecurityToken; |
||
10 | use SilverStripe\Control\Controller; |
||
11 | use SilverStripe\Control\Director; |
||
12 | use SilverStripe\Core\Email\Email; |
||
13 | use SilverStripe\Core\Injector\Injector; |
||
14 | use SilverStripe\Core\TempFolder; |
||
15 | use SilverStripe\Forms\CheckboxField; |
||
16 | use SilverStripe\Forms\EmailField; |
||
17 | use SilverStripe\Forms\FieldGroup; |
||
18 | use SilverStripe\Forms\FieldList; |
||
19 | use SilverStripe\Forms\HeaderField; |
||
20 | use SilverStripe\Forms\HTMLEditor\HTMLEditorField; |
||
21 | use SilverStripe\Forms\TextareaField; |
||
22 | use SilverStripe\Forms\TextField; |
||
23 | use SilverStripe\ORM\ArrayList; |
||
24 | use SilverStripe\ORM\DataObject; |
||
25 | use SilverStripe\ORM\DB; |
||
26 | use SilverStripe\ORM\PaginatedList; |
||
27 | use SilverStripe\Security\Member; |
||
28 | use SilverStripe\Security\Permission; |
||
29 | use SilverStripe\CMS\Model\SiteTree; |
||
30 | |||
31 | /** |
||
32 | * Represents a single comment object. |
||
33 | * |
||
34 | * @property string $Name |
||
35 | * @property string $Comment |
||
36 | * @property string $Email |
||
37 | * @property string $URL |
||
38 | * @property string $BaseClass |
||
39 | * @property boolean $Moderated |
||
40 | * @property boolean $IsSpam True if the comment is known as spam |
||
41 | * @property integer $ParentID ID of the parent page / dataobject |
||
42 | * @property boolean $AllowHtml If true, treat $Comment as HTML instead of plain text |
||
43 | * @property string $SecretToken Secret admin token required to provide moderation links between sessions |
||
44 | * @property integer $Depth Depth of this comment in the nested chain |
||
45 | * |
||
46 | * @method HasManyList ChildComments() List of child comments |
||
47 | * @method Member Author() Member object who created this comment |
||
48 | * @method Comment ParentComment() Parent comment this is a reply to |
||
49 | * @package comments |
||
50 | */ |
||
51 | class Comment extends DataObject |
||
52 | { |
||
53 | /** |
||
54 | * {@inheritDoc} |
||
55 | */ |
||
56 | private static $db = array( |
||
0 ignored issues
–
show
Comprehensibility
introduced
by
Loading history...
|
|||
57 | 'Name' => 'Varchar(200)', |
||
58 | 'Comment' => 'Text', |
||
59 | 'Email' => 'Varchar(200)', |
||
60 | 'URL' => 'Varchar(255)', |
||
61 | 'Moderated' => 'Boolean(0)', |
||
62 | 'IsSpam' => 'Boolean(0)', |
||
63 | 'AllowHtml' => 'Boolean', |
||
64 | 'SecretToken' => 'Varchar(255)', |
||
65 | 'Depth' => 'Int' |
||
66 | ); |
||
67 | |||
68 | /** |
||
69 | * {@inheritDoc} |
||
70 | */ |
||
71 | private static $has_one = array( |
||
0 ignored issues
–
show
|
|||
72 | 'Author' => Member::class, |
||
73 | 'ParentComment' => self::class, |
||
74 | 'Parent' => DataObject::class |
||
75 | ); |
||
76 | |||
77 | /** |
||
78 | * {@inheritDoc} |
||
79 | */ |
||
80 | private static $has_many = array( |
||
0 ignored issues
–
show
|
|||
81 | 'ChildComments' => self::class |
||
82 | ); |
||
83 | |||
84 | /** |
||
85 | * {@inheritDoc} |
||
86 | */ |
||
87 | private static $default_sort = '"Created" DESC'; |
||
0 ignored issues
–
show
|
|||
88 | |||
89 | /** |
||
90 | * {@inheritDoc} |
||
91 | */ |
||
92 | private static $defaults = array( |
||
0 ignored issues
–
show
|
|||
93 | 'Moderated' => 0, |
||
94 | 'IsSpam' => 0, |
||
95 | ); |
||
96 | |||
97 | /** |
||
98 | * {@inheritDoc} |
||
99 | */ |
||
100 | private static $casting = array( |
||
0 ignored issues
–
show
|
|||
101 | 'Title' => 'Varchar', |
||
102 | 'ParentTitle' => 'Varchar', |
||
103 | 'ParentClassName' => 'Varchar', |
||
104 | 'AuthorName' => 'Varchar', |
||
105 | 'RSSName' => 'Varchar', |
||
106 | 'DeleteLink' => 'Varchar', |
||
107 | 'SpamLink' => 'Varchar', |
||
108 | 'HamLink' => 'Varchar', |
||
109 | 'ApproveLink' => 'Varchar', |
||
110 | 'Permalink' => 'Varchar' |
||
111 | ); |
||
112 | |||
113 | /** |
||
114 | * {@inheritDoc} |
||
115 | */ |
||
116 | private static $searchable_fields = array( |
||
0 ignored issues
–
show
|
|||
117 | 'Name', |
||
118 | 'Email', |
||
119 | 'Comment', |
||
120 | 'Created' |
||
121 | ); |
||
122 | |||
123 | /** |
||
124 | * {@inheritDoc} |
||
125 | */ |
||
126 | private static $summary_fields = array( |
||
0 ignored issues
–
show
|
|||
127 | 'Name' => 'Submitted By', |
||
128 | 'Email' => 'Email', |
||
129 | 'Comment.LimitWordCount' => 'Comment', |
||
130 | 'Created' => 'Date Posted', |
||
131 | 'Parent.Title' => 'Post', |
||
132 | 'IsSpam' => 'Is Spam' |
||
133 | ); |
||
134 | |||
135 | /** |
||
136 | * {@inheritDoc} |
||
137 | */ |
||
138 | private static $field_labels = array( |
||
0 ignored issues
–
show
|
|||
139 | 'Author' => 'Author Member' |
||
140 | ); |
||
141 | |||
142 | /** |
||
143 | * {@inheritDoc} |
||
144 | */ |
||
145 | private static $table_name = 'Comment'; |
||
0 ignored issues
–
show
|
|||
146 | |||
147 | /** |
||
148 | * {@inheritDoc} |
||
149 | */ |
||
150 | public function onBeforeWrite() |
||
151 | { |
||
152 | parent::onBeforeWrite(); |
||
153 | |||
154 | // Sanitize HTML, because its expected to be passed to the template unescaped later |
||
155 | if ($this->AllowHtml) { |
||
156 | $this->Comment = $this->purifyHtml($this->Comment); |
||
157 | } |
||
158 | |||
159 | // Check comment depth |
||
160 | $this->updateDepth(); |
||
161 | } |
||
162 | |||
163 | /** |
||
164 | * {@inheritDoc} |
||
165 | */ |
||
166 | public function onBeforeDelete() |
||
167 | { |
||
168 | parent::onBeforeDelete(); |
||
169 | |||
170 | // Delete all children |
||
171 | foreach ($this->ChildComments() as $comment) { |
||
172 | $comment->delete(); |
||
173 | } |
||
174 | } |
||
175 | |||
176 | /** |
||
177 | * @return Comment_SecurityToken |
||
178 | */ |
||
179 | public function getSecurityToken() |
||
180 | { |
||
181 | return Injector::inst()->createWithArgs(SecurityToken::class, array($this)); |
||
182 | } |
||
183 | |||
184 | /** |
||
185 | * Migrates the old {@link PageComment} objects to {@link Comment} |
||
186 | */ |
||
187 | public function requireDefaultRecords() |
||
188 | { |
||
189 | parent::requireDefaultRecords(); |
||
190 | |||
191 | if (DB::get_schema()->hasTable('PageComment')) { |
||
192 | $comments = DB::query('SELECT * FROM "PageComment"'); |
||
193 | |||
194 | if ($comments) { |
||
195 | while ($pageComment = $comments->next()) { |
||
196 | // create a new comment from the older page comment |
||
197 | $comment = new Comment(); |
||
198 | $comment->update($pageComment); |
||
199 | |||
200 | // set the variables which have changed |
||
201 | $comment->BaseClass = SiteTree::class; |
||
202 | $comment->URL = (isset($pageComment['CommenterURL'])) ? $pageComment['CommenterURL'] : ''; |
||
203 | if ((int) $pageComment['NeedsModeration'] == 0) { |
||
204 | $comment->Moderated = true; |
||
205 | } |
||
206 | |||
207 | $comment->write(); |
||
208 | } |
||
209 | } |
||
210 | |||
211 | DB::alteration_message('Migrated PageComment to Comment', 'changed'); |
||
212 | DB::get_schema()->dontRequireTable('PageComment'); |
||
213 | } |
||
214 | } |
||
215 | |||
216 | /** |
||
217 | * Return a link to this comment |
||
218 | * |
||
219 | * @param string $action |
||
220 | * |
||
221 | * @return string link to this comment. |
||
0 ignored issues
–
show
|
|||
222 | */ |
||
223 | public function Link($action = '') |
||
224 | { |
||
225 | if ($parent = $this->Parent()) { |
||
0 ignored issues
–
show
The method
Parent() does not exist on SilverStripe\Comments\Model\Comment . Did you maybe mean getParent() ?
This check marks calls to methods that do not seem to exist on an object. This is most likely the result of a method being renamed without all references to it being renamed likewise.
Loading history...
|
|||
226 | return $parent->Link($action) . '#' . $this->Permalink(); |
||
227 | } |
||
228 | } |
||
229 | |||
230 | /** |
||
231 | * Returns the permalink for this {@link Comment}. Inserted into |
||
232 | * the ID tag of the comment |
||
233 | * |
||
234 | * @return string |
||
235 | */ |
||
236 | public function Permalink() |
||
237 | { |
||
238 | $prefix = $this->getOption('comment_permalink_prefix'); |
||
239 | return $prefix . $this->ID; |
||
240 | } |
||
241 | |||
242 | /** |
||
243 | * Translate the form field labels for the CMS administration |
||
244 | * |
||
245 | * @param boolean $includerelations |
||
246 | * |
||
247 | * @return array |
||
0 ignored issues
–
show
|
|||
248 | */ |
||
249 | public function fieldLabels($includerelations = true) |
||
250 | { |
||
251 | $labels = parent::fieldLabels($includerelations); |
||
252 | |||
253 | $labels['Name'] = _t('SilverStripe\\Comments\\Model\\Comment.NAME', 'Author Name'); |
||
254 | $labels['Comment'] = _t('SilverStripe\\Comments\\Model\\Comment.COMMENT', 'Comment'); |
||
255 | $labels['Email'] = _t('SilverStripe\\Comments\\Model\\Comment.EMAIL', 'Email'); |
||
256 | $labels['URL'] = _t('SilverStripe\\Comments\\Model\\Comment.URL', 'URL'); |
||
257 | $labels['IsSpam'] = _t('SilverStripe\\Comments\\Model\\Comment.ISSPAM', 'Spam?'); |
||
258 | $labels['Moderated'] = _t('SilverStripe\\Comments\\Model\\Comment.MODERATED', 'Moderated?'); |
||
259 | $labels['ParentTitle'] = _t('SilverStripe\\Comments\\Model\\Comment.PARENTTITLE', 'Parent'); |
||
260 | $labels['Created'] = _t('SilverStripe\\Comments\\Model\\Comment.CREATED', 'Date posted'); |
||
261 | |||
262 | return $labels; |
||
263 | } |
||
264 | |||
265 | /** |
||
266 | * Get the commenting option |
||
267 | * |
||
268 | * @param string $key |
||
269 | * |
||
270 | * @return mixed Result if the setting is available, or null otherwise |
||
271 | */ |
||
272 | public function getOption($key) |
||
273 | { |
||
274 | // If possible use the current record |
||
275 | $record = $this->Parent(); |
||
0 ignored issues
–
show
The method
Parent() does not exist on SilverStripe\Comments\Model\Comment . Did you maybe mean getParent() ?
This check marks calls to methods that do not seem to exist on an object. This is most likely the result of a method being renamed without all references to it being renamed likewise.
Loading history...
|
|||
276 | |||
277 | if (!$record && $this->Parent()) { |
||
0 ignored issues
–
show
The method
Parent() does not exist on SilverStripe\Comments\Model\Comment . Did you maybe mean getParent() ?
This check marks calls to methods that do not seem to exist on an object. This is most likely the result of a method being renamed without all references to it being renamed likewise.
Loading history...
|
|||
278 | // Otherwise a singleton of that record |
||
279 | $record = singleton($this->Parent()->dataClass()); |
||
0 ignored issues
–
show
The method
Parent() does not exist on SilverStripe\Comments\Model\Comment . Did you maybe mean getParent() ?
This check marks calls to methods that do not seem to exist on an object. This is most likely the result of a method being renamed without all references to it being renamed likewise.
Loading history...
|
|||
280 | } elseif (!$record) { |
||
281 | // Otherwise just use the default options |
||
282 | $record = singleton(CommentsExtension::class); |
||
283 | } |
||
284 | |||
285 | return ($record instanceof CommentsExtension || $record->hasExtension(CommentsExtension::class)) |
||
286 | ? $record->getCommentsOption($key) |
||
287 | : null; |
||
288 | } |
||
289 | |||
290 | /** |
||
291 | * Returns the parent {@link DataObject} this comment is attached too |
||
292 | * |
||
293 | * @deprecated 4.0.0 Use $this->Parent() instead |
||
294 | * @return DataObject |
||
0 ignored issues
–
show
|
|||
295 | */ |
||
296 | public function getParent() |
||
297 | { |
||
298 | return $this->BaseClass && $this->ParentID |
||
299 | ? DataObject::get_by_id($this->BaseClass, $this->ParentID, true) |
||
300 | : null; |
||
301 | } |
||
302 | |||
303 | |||
304 | /** |
||
305 | * Returns a string to help identify the parent of the comment |
||
306 | * |
||
307 | * @return string |
||
308 | */ |
||
309 | public function getParentTitle() |
||
310 | { |
||
311 | if ($parent = $this->Parent()) { |
||
0 ignored issues
–
show
The method
Parent() does not exist on SilverStripe\Comments\Model\Comment . Did you maybe mean getParent() ?
This check marks calls to methods that do not seem to exist on an object. This is most likely the result of a method being renamed without all references to it being renamed likewise.
Loading history...
|
|||
312 | return $parent->Title ?: ($parent->ClassName . ' #' . $parent->ID); |
||
313 | } |
||
314 | } |
||
315 | |||
316 | /** |
||
317 | * Comment-parent classnames obviously vary, return the parent classname |
||
318 | * |
||
319 | * @return string |
||
320 | */ |
||
321 | public function getParentClassName() |
||
322 | { |
||
323 | return $this->Parent()->getClassName(); |
||
0 ignored issues
–
show
The method
Parent() does not exist on SilverStripe\Comments\Model\Comment . Did you maybe mean getParent() ?
This check marks calls to methods that do not seem to exist on an object. This is most likely the result of a method being renamed without all references to it being renamed likewise.
Loading history...
|
|||
324 | } |
||
325 | |||
326 | /** |
||
327 | * {@inheritDoc} |
||
328 | */ |
||
329 | public function castingHelper($field) |
||
0 ignored issues
–
show
The return type could not be reliably inferred; please add a
@return annotation.
Our type inference engine in quite powerful, but sometimes the code does not
provide enough clues to go by. In these cases we request you to add a
Loading history...
|
|||
330 | { |
||
331 | // Safely escape the comment |
||
332 | if (in_array($field, ['EscapedComment', 'Comment'], true)) { |
||
333 | return $this->AllowHtml ? 'HTMLText' : 'Text'; |
||
334 | } |
||
335 | return parent::castingHelper($field); |
||
336 | } |
||
337 | |||
338 | /** |
||
339 | * Content to be safely escaped on the frontend |
||
340 | * |
||
341 | * @return string |
||
342 | */ |
||
343 | public function getEscapedComment() |
||
344 | { |
||
345 | return $this->Comment; |
||
346 | } |
||
347 | |||
348 | /** |
||
349 | * Return whether this comment is a preview (has not been written to the db) |
||
350 | * |
||
351 | * @return boolean |
||
352 | */ |
||
353 | public function isPreview() |
||
354 | { |
||
355 | return !$this->exists(); |
||
356 | } |
||
357 | |||
358 | /** |
||
359 | * @todo needs to compare to the new {@link Commenting} configuration API |
||
360 | * |
||
361 | * @param Member $member |
||
0 ignored issues
–
show
Should the type for parameter
$member not be Member|null ?
This check looks for It makes a suggestion as to what type it considers more descriptive. Most often this is a case of a parameter that can be null in addition to its declared types.
Loading history...
|
|||
362 | * @param array $context |
||
363 | * @return bool |
||
364 | */ |
||
365 | public function canCreate($member = null, $context = []) |
||
366 | { |
||
367 | return false; |
||
368 | } |
||
369 | |||
370 | /** |
||
371 | * Checks for association with a page, and {@link SiteTree->ProvidePermission} |
||
372 | * flag being set to true. |
||
373 | * |
||
374 | * @param Member $member |
||
0 ignored issues
–
show
Should the type for parameter
$member not be Member|null ?
This check looks for It makes a suggestion as to what type it considers more descriptive. Most often this is a case of a parameter that can be null in addition to its declared types.
Loading history...
|
|||
375 | * @return Boolean |
||
376 | */ |
||
377 | public function canView($member = null) |
||
378 | { |
||
379 | $member = $this->getMember($member); |
||
380 | |||
381 | $extended = $this->extendedCan('canView', $member); |
||
0 ignored issues
–
show
$member is of type object<SilverStripe\ORM\DataObject>|null , but the function expects a object<SilverStripe\Security\Member>|integer .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
Loading history...
|
|||
382 | if ($extended !== null) { |
||
383 | return $extended; |
||
384 | } |
||
385 | |||
386 | if (Permission::checkMember($member, 'CMS_ACCESS_CommentAdmin')) { |
||
387 | return true; |
||
388 | } |
||
389 | |||
390 | if ($parent = $this->Parent()) { |
||
0 ignored issues
–
show
The method
Parent() does not exist on SilverStripe\Comments\Model\Comment . Did you maybe mean getParent() ?
This check marks calls to methods that do not seem to exist on an object. This is most likely the result of a method being renamed without all references to it being renamed likewise.
Loading history...
|
|||
391 | return $parent->canView($member) |
||
392 | && $parent->hasExtension(CommentsExtension::class) |
||
393 | && $parent->CommentsEnabled; |
||
394 | } |
||
395 | |||
396 | return false; |
||
397 | } |
||
398 | |||
399 | /** |
||
400 | * Checks if the comment can be edited. |
||
401 | * |
||
402 | * @param null|int|Member $member |
||
403 | * @return Boolean |
||
404 | */ |
||
405 | public function canEdit($member = null) |
||
406 | { |
||
407 | $member = $this->getMember($member); |
||
408 | |||
409 | if (!$member) { |
||
410 | return false; |
||
411 | } |
||
412 | |||
413 | $extended = $this->extendedCan('canEdit', $member); |
||
0 ignored issues
–
show
$member is of type object<SilverStripe\ORM\DataObject> , but the function expects a object<SilverStripe\Security\Member>|integer .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
Loading history...
|
|||
414 | if ($extended !== null) { |
||
415 | return $extended; |
||
416 | } |
||
417 | |||
418 | if (Permission::checkMember($member, 'CMS_ACCESS_CommentAdmin')) { |
||
419 | return true; |
||
420 | } |
||
421 | |||
422 | if ($parent = $this->Parent()) { |
||
0 ignored issues
–
show
The method
Parent() does not exist on SilverStripe\Comments\Model\Comment . Did you maybe mean getParent() ?
This check marks calls to methods that do not seem to exist on an object. This is most likely the result of a method being renamed without all references to it being renamed likewise.
Loading history...
|
|||
423 | return $parent->canEdit($member); |
||
424 | } |
||
425 | |||
426 | return false; |
||
427 | } |
||
428 | |||
429 | /** |
||
430 | * Checks if the comment can be deleted. |
||
431 | * |
||
432 | * @param null|int|Member $member |
||
433 | * @return Boolean |
||
434 | */ |
||
435 | public function canDelete($member = null) |
||
436 | { |
||
437 | $member = $this->getMember($member); |
||
438 | |||
439 | if (!$member) { |
||
440 | return false; |
||
441 | } |
||
442 | |||
443 | $extended = $this->extendedCan('canDelete', $member); |
||
0 ignored issues
–
show
$member is of type object<SilverStripe\ORM\DataObject> , but the function expects a object<SilverStripe\Security\Member>|integer .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
Loading history...
|
|||
444 | if ($extended !== null) { |
||
445 | return $extended; |
||
446 | } |
||
447 | |||
448 | return $this->canEdit($member); |
||
0 ignored issues
–
show
$member is of type object<SilverStripe\ORM\DataObject> , but the function expects a null|integer|object<SilverStripe\Security\Member> .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
Loading history...
|
|||
449 | } |
||
450 | |||
451 | /** |
||
452 | * Resolves Member object. |
||
453 | * |
||
454 | * @param Member|int|null $member |
||
455 | * @return Member|null |
||
0 ignored issues
–
show
|
|||
456 | */ |
||
457 | protected function getMember($member = null) |
||
458 | { |
||
459 | if (!$member) { |
||
460 | $member = Member::currentUser(); |
||
0 ignored issues
–
show
The method
SilverStripe\Security\Member::currentUser() has been deprecated with message: 5.0.0 use Security::getCurrentUser()
This method has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.
Loading history...
|
|||
461 | } |
||
462 | |||
463 | if (is_numeric($member)) { |
||
464 | $member = DataObject::get_by_id(Member::class, $member, true); |
||
465 | } |
||
466 | |||
467 | return $member; |
||
468 | } |
||
469 | |||
470 | /** |
||
471 | * Return the authors name for the comment |
||
472 | * |
||
473 | * @return string |
||
0 ignored issues
–
show
|
|||
474 | */ |
||
475 | public function getAuthorName() |
||
476 | { |
||
477 | if ($this->Name) { |
||
478 | return $this->Name; |
||
479 | } elseif ($author = $this->Author()) { |
||
480 | return $author->getName(); |
||
481 | } |
||
482 | } |
||
483 | |||
484 | /** |
||
485 | * Generate a secure admin-action link authorised for the specified member |
||
486 | * |
||
487 | * @param string $action An action on CommentingController to link to |
||
488 | * @param Member $member The member authorised to invoke this action |
||
0 ignored issues
–
show
Should the type for parameter
$member not be Member|null ?
This check looks for It makes a suggestion as to what type it considers more descriptive. Most often this is a case of a parameter that can be null in addition to its declared types.
Loading history...
|
|||
489 | * |
||
490 | * @return string |
||
491 | */ |
||
492 | protected function actionLink($action, $member = null) |
||
493 | { |
||
494 | if (!$member) { |
||
495 | $member = Member::currentUser(); |
||
0 ignored issues
–
show
The method
SilverStripe\Security\Member::currentUser() has been deprecated with message: 5.0.0 use Security::getCurrentUser()
This method has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.
Loading history...
|
|||
496 | } |
||
497 | if (!$member) { |
||
498 | return false; |
||
499 | } |
||
500 | |||
501 | /** |
||
502 | * @todo: How do we handle "DataObject" instances that don't have a Link to reject/spam/delete?? This may |
||
503 | * we have to make CMS a hard dependency instead. |
||
504 | */ |
||
505 | // if (!$this->Parent()->hasMethod('Link')) { |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
73% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them.
Loading history...
|
|||
506 | // return false; |
||
507 | // } |
||
508 | |||
509 | $url = Controller::join_links( |
||
510 | Director::baseURL(), |
||
511 | 'comments', |
||
512 | $action, |
||
513 | $this->ID |
||
514 | ); |
||
515 | |||
516 | // Limit access for this user |
||
517 | $token = $this->getSecurityToken(); |
||
518 | return $token->addToUrl($url, $member); |
||
519 | } |
||
520 | |||
521 | /** |
||
522 | * Link to delete this comment |
||
523 | * |
||
524 | * @param Member $member |
||
0 ignored issues
–
show
Should the type for parameter
$member not be Member|null ?
This check looks for It makes a suggestion as to what type it considers more descriptive. Most often this is a case of a parameter that can be null in addition to its declared types.
Loading history...
|
|||
525 | * |
||
526 | * @return string |
||
0 ignored issues
–
show
|
|||
527 | */ |
||
528 | public function DeleteLink($member = null) |
||
529 | { |
||
530 | if ($this->canDelete($member)) { |
||
531 | return $this->actionLink('delete', $member); |
||
532 | } |
||
533 | } |
||
534 | |||
535 | /** |
||
536 | * Link to mark as spam |
||
537 | * |
||
538 | * @param Member $member |
||
0 ignored issues
–
show
Should the type for parameter
$member not be Member|null ?
This check looks for It makes a suggestion as to what type it considers more descriptive. Most often this is a case of a parameter that can be null in addition to its declared types.
Loading history...
|
|||
539 | * |
||
540 | * @return string |
||
0 ignored issues
–
show
|
|||
541 | */ |
||
542 | public function SpamLink($member = null) |
||
543 | { |
||
544 | if ($this->canEdit($member) && !$this->IsSpam) { |
||
545 | return $this->actionLink('spam', $member); |
||
546 | } |
||
547 | } |
||
548 | |||
549 | /** |
||
550 | * Link to mark as not-spam (ham) |
||
551 | * |
||
552 | * @param Member $member |
||
0 ignored issues
–
show
Should the type for parameter
$member not be Member|null ?
This check looks for It makes a suggestion as to what type it considers more descriptive. Most often this is a case of a parameter that can be null in addition to its declared types.
Loading history...
|
|||
553 | * |
||
554 | * @return string |
||
0 ignored issues
–
show
|
|||
555 | */ |
||
556 | public function HamLink($member = null) |
||
557 | { |
||
558 | if ($this->canEdit($member) && $this->IsSpam) { |
||
559 | return $this->actionLink('ham', $member); |
||
560 | } |
||
561 | } |
||
562 | |||
563 | /** |
||
564 | * Link to approve this comment |
||
565 | * |
||
566 | * @param Member $member |
||
0 ignored issues
–
show
Should the type for parameter
$member not be Member|null ?
This check looks for It makes a suggestion as to what type it considers more descriptive. Most often this is a case of a parameter that can be null in addition to its declared types.
Loading history...
|
|||
567 | * |
||
568 | * @return string |
||
0 ignored issues
–
show
|
|||
569 | */ |
||
570 | public function ApproveLink($member = null) |
||
571 | { |
||
572 | if ($this->canEdit($member) && !$this->Moderated) { |
||
573 | return $this->actionLink('approve', $member); |
||
574 | } |
||
575 | } |
||
576 | |||
577 | /** |
||
578 | * Mark this comment as spam |
||
579 | */ |
||
580 | public function markSpam() |
||
581 | { |
||
582 | $this->IsSpam = true; |
||
583 | $this->Moderated = true; |
||
584 | $this->write(); |
||
585 | $this->extend('afterMarkSpam'); |
||
586 | } |
||
587 | |||
588 | /** |
||
589 | * Mark this comment as approved |
||
590 | */ |
||
591 | public function markApproved() |
||
592 | { |
||
593 | $this->IsSpam = false; |
||
594 | $this->Moderated = true; |
||
595 | $this->write(); |
||
596 | $this->extend('afterMarkApproved'); |
||
597 | } |
||
598 | |||
599 | /** |
||
600 | * Mark this comment as unapproved |
||
601 | */ |
||
602 | public function markUnapproved() |
||
603 | { |
||
604 | $this->Moderated = false; |
||
605 | $this->write(); |
||
606 | $this->extend('afterMarkUnapproved'); |
||
607 | } |
||
608 | |||
609 | /** |
||
610 | * @return string |
||
611 | */ |
||
612 | public function SpamClass() |
||
613 | { |
||
614 | if ($this->IsSpam) { |
||
615 | return 'spam'; |
||
616 | } elseif (!$this->Moderated) { |
||
617 | return 'unmoderated'; |
||
618 | } else { |
||
619 | return 'notspam'; |
||
620 | } |
||
621 | } |
||
622 | |||
623 | /** |
||
624 | * @return string |
||
625 | */ |
||
626 | public function getTitle() |
||
627 | { |
||
628 | $title = sprintf(_t('SilverStripe\\Comments\\Model\\Comment.COMMENTBY', 'Comment by %s', 'Name'), $this->getAuthorName()); |
||
629 | |||
630 | if ($parent = $this->Parent()) { |
||
0 ignored issues
–
show
The method
Parent() does not exist on SilverStripe\Comments\Model\Comment . Did you maybe mean getParent() ?
This check marks calls to methods that do not seem to exist on an object. This is most likely the result of a method being renamed without all references to it being renamed likewise.
Loading history...
|
|||
631 | if ($parent->Title) { |
||
632 | $title .= sprintf(' %s %s', _t('SilverStripe\\Comments\\Model\\Comment.ON', 'on'), $parent->Title); |
||
633 | } |
||
634 | } |
||
635 | |||
636 | return $title; |
||
637 | } |
||
638 | |||
639 | /* |
||
640 | * Modify the default fields shown to the user |
||
641 | */ |
||
642 | public function getCMSFields() |
||
643 | { |
||
644 | $commentField = $this->AllowHtml ? HTMLEditorField::class : TextareaField::class; |
||
645 | $fields = new FieldList( |
||
646 | $this |
||
647 | ->obj('Created') |
||
648 | ->scaffoldFormField($this->fieldLabel('Created')) |
||
649 | ->performReadonlyTransformation(), |
||
650 | TextField::create('Name', $this->fieldLabel('Name')), |
||
651 | $commentField::create('Comment', $this->fieldLabel('Comment')), |
||
652 | EmailField::create('Email', $this->fieldLabel('Email')), |
||
653 | TextField::create('URL', $this->fieldLabel('URL')), |
||
654 | FieldGroup::create(array( |
||
655 | CheckboxField::create('Moderated', $this->fieldLabel('Moderated')), |
||
656 | CheckboxField::create('IsSpam', $this->fieldLabel('IsSpam')), |
||
657 | )) |
||
658 | ->setTitle(_t('SilverStripe\\Comments\\Model\\Comment.OPTIONS', 'Options')) |
||
659 | ->setDescription(_t( |
||
660 | 'SilverStripe\\Comments\\Model\\Comment.OPTION_DESCRIPTION', |
||
661 | 'Unmoderated and spam comments will not be displayed until approved' |
||
662 | )) |
||
663 | ); |
||
664 | |||
665 | // Show member name if given |
||
666 | if (($author = $this->Author()) && $author->exists()) { |
||
667 | $fields->insertAfter( |
||
668 | TextField::create('AuthorMember', $this->fieldLabel('Author'), $author->Title) |
||
669 | ->performReadonlyTransformation(), |
||
670 | 'Name' |
||
0 ignored issues
–
show
'Name' is of type string , but the function expects a object<SilverStripe\Forms\FormField> .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
Loading history...
|
|||
671 | ); |
||
672 | } |
||
673 | |||
674 | // Show parent comment if given |
||
675 | if (($parent = $this->ParentComment()) && $parent->exists()) { |
||
676 | $fields->push(new HeaderField( |
||
677 | 'ParentComment_Title', |
||
678 | _t('SilverStripe\\Comments\\Model\\Comment.ParentComment_Title', 'This comment is a reply to the below') |
||
679 | )); |
||
680 | // Created date |
||
681 | // FIXME - the method setName in DatetimeField is not chainable, hence |
||
682 | // the lack of chaining here |
||
683 | $createdField = $parent |
||
684 | ->obj('Created') |
||
685 | ->scaffoldFormField($parent->fieldLabel('Created')); |
||
686 | $createdField->setName('ParentComment_Created'); |
||
687 | $createdField->setValue($parent->Created); |
||
688 | $createdField->performReadonlyTransformation(); |
||
689 | $fields->push($createdField); |
||
690 | |||
691 | // Name (could be member or string value) |
||
692 | $fields->push( |
||
693 | $parent |
||
694 | ->obj('AuthorName') |
||
695 | ->scaffoldFormField($parent->fieldLabel('AuthorName')) |
||
696 | ->setName('ParentComment_AuthorName') |
||
697 | ->setValue($parent->getAuthorName()) |
||
698 | ->performReadonlyTransformation() |
||
699 | ); |
||
700 | |||
701 | // Comment body |
||
702 | $fields->push( |
||
703 | $parent |
||
704 | ->obj('EscapedComment') |
||
705 | ->scaffoldFormField($parent->fieldLabel(self::class)) |
||
706 | ->setName('ParentComment_EscapedComment') |
||
707 | ->setValue($parent->Comment) |
||
708 | ->performReadonlyTransformation() |
||
709 | ); |
||
710 | } |
||
711 | |||
712 | $this->extend('updateCMSFields', $fields); |
||
713 | return $fields; |
||
714 | } |
||
715 | |||
716 | /** |
||
717 | * @param string $dirtyHtml |
||
718 | * |
||
719 | * @return string |
||
720 | */ |
||
721 | public function purifyHtml($dirtyHtml) |
||
722 | { |
||
723 | if ($service = $this->getHtmlPurifierService()) { |
||
724 | return $service->purify($dirtyHtml); |
||
725 | } |
||
726 | |||
727 | return $dirtyHtml; |
||
728 | } |
||
729 | |||
730 | /** |
||
731 | * @return HTMLPurifier (or anything with a "purify()" method) |
||
0 ignored issues
–
show
|
|||
732 | */ |
||
733 | public function getHtmlPurifierService() |
||
734 | { |
||
735 | if (!class_exists(HTMLPurifier_Config::class)) { |
||
736 | return null; |
||
737 | } |
||
738 | |||
739 | $config = HTMLPurifier_Config::createDefault(); |
||
740 | $allowedElements = (array) $this->getOption('html_allowed_elements'); |
||
741 | if (!empty($allowedElements)) { |
||
742 | $config->set('HTML.AllowedElements', $allowedElements); |
||
743 | } |
||
744 | |||
745 | // This injector cannot be set unless the 'p' element is allowed |
||
746 | if (in_array('p', $allowedElements)) { |
||
747 | $config->set('AutoFormat.AutoParagraph', true); |
||
748 | } |
||
749 | |||
750 | $config->set('AutoFormat.Linkify', true); |
||
751 | $config->set('URI.DisableExternalResources', true); |
||
752 | $config->set('Cache.SerializerPath', TempFolder::getTempFolder(BASE_PATH)); |
||
753 | return new HTMLPurifier($config); |
||
754 | } |
||
755 | |||
756 | /** |
||
757 | * Calculate the Gravatar link from the email address |
||
758 | * |
||
759 | * @return string |
||
760 | */ |
||
761 | public function Gravatar() |
||
762 | { |
||
763 | $gravatar = ''; |
||
764 | $use_gravatar = $this->getOption('use_gravatar'); |
||
765 | |||
766 | if ($use_gravatar) { |
||
767 | $gravatar = 'http://www.gravatar.com/avatar/' . md5(strtolower(trim($this->Email))); |
||
768 | $gravatarsize = $this->getOption('gravatar_size'); |
||
769 | $gravatardefault = $this->getOption('gravatar_default'); |
||
770 | $gravatarrating = $this->getOption('gravatar_rating'); |
||
771 | $gravatar .= '?s=' . $gravatarsize . '&d=' . $gravatardefault . '&r=' . $gravatarrating; |
||
772 | } |
||
773 | |||
774 | return $gravatar; |
||
775 | } |
||
776 | |||
777 | /** |
||
778 | * Determine if replies are enabled for this instance |
||
779 | * |
||
780 | * @return boolean |
||
781 | */ |
||
782 | public function getRepliesEnabled() |
||
783 | { |
||
784 | // Check reply option |
||
785 | if (!$this->getOption('nested_comments')) { |
||
786 | return false; |
||
787 | } |
||
788 | |||
789 | // Check if depth is limited |
||
790 | $maxLevel = $this->getOption('nested_depth'); |
||
791 | $notSpam = ($this->SpamClass() == 'notspam'); |
||
792 | return $notSpam && (!$maxLevel || $this->Depth < $maxLevel); |
||
793 | } |
||
794 | |||
795 | /** |
||
796 | * Returns the list of all replies |
||
797 | * |
||
798 | * @return SS_List |
||
799 | */ |
||
800 | public function AllReplies() |
||
801 | { |
||
802 | // No replies if disabled |
||
803 | if (!$this->getRepliesEnabled()) { |
||
804 | return new ArrayList(); |
||
805 | } |
||
806 | |||
807 | // Get all non-spam comments |
||
808 | $order = $this->getOption('order_replies_by') |
||
809 | ?: $this->getOption('order_comments_by'); |
||
810 | $list = $this |
||
811 | ->ChildComments() |
||
812 | ->sort($order); |
||
813 | |||
814 | $this->extend('updateAllReplies', $list); |
||
815 | return $list; |
||
816 | } |
||
817 | |||
818 | /** |
||
819 | * Returns the list of replies, with spam and unmoderated items excluded, for use in the frontend |
||
820 | * |
||
821 | * @return SS_List |
||
822 | */ |
||
823 | public function Replies() |
||
824 | { |
||
825 | // No replies if disabled |
||
826 | if (!$this->getRepliesEnabled()) { |
||
827 | return new ArrayList(); |
||
828 | } |
||
829 | $list = $this->AllReplies(); |
||
830 | |||
831 | // Filter spam comments for non-administrators if configured |
||
832 | $parent = $this->Parent(); |
||
0 ignored issues
–
show
The method
Parent() does not exist on SilverStripe\Comments\Model\Comment . Did you maybe mean getParent() ?
This check marks calls to methods that do not seem to exist on an object. This is most likely the result of a method being renamed without all references to it being renamed likewise.
Loading history...
|
|||
833 | $showSpam = $this->getOption('frontend_spam') && $parent && $parent->canModerateComments(); |
||
834 | if (!$showSpam) { |
||
835 | $list = $list->filter('IsSpam', 0); |
||
836 | } |
||
837 | |||
838 | // Filter un-moderated comments for non-administrators if moderation is enabled |
||
839 | $showUnmoderated = $parent && ( |
||
840 | ($parent->ModerationRequired === 'None') |
||
841 | || ($this->getOption('frontend_moderation') && $parent->canModerateComments()) |
||
842 | ); |
||
843 | if (!$showUnmoderated) { |
||
844 | $list = $list->filter('Moderated', 1); |
||
845 | } |
||
846 | |||
847 | $this->extend('updateReplies', $list); |
||
848 | return $list; |
||
849 | } |
||
850 | |||
851 | /** |
||
852 | * Returns the list of replies paged, with spam and unmoderated items excluded, for use in the frontend |
||
853 | * |
||
854 | * @return PaginatedList |
||
855 | */ |
||
856 | View Code Duplication | public function PagedReplies() |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
857 | { |
||
858 | $list = $this->Replies(); |
||
859 | |||
860 | // Add pagination |
||
861 | $list = new PaginatedList($list, Controller::curr()->getRequest()); |
||
0 ignored issues
–
show
\SilverStripe\Control\Co...r::curr()->getRequest() is of type object<SilverStripe\Control\HTTPRequest> , but the function expects a array .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
Loading history...
|
|||
862 | $list->setPaginationGetVar('repliesstart' . $this->ID); |
||
863 | $list->setPageLength($this->getOption('comments_per_page')); |
||
864 | |||
865 | $this->extend('updatePagedReplies', $list); |
||
866 | return $list; |
||
867 | } |
||
868 | |||
869 | /** |
||
870 | * Generate a reply form for this comment |
||
871 | * |
||
872 | * @return Form |
||
0 ignored issues
–
show
|
|||
873 | */ |
||
874 | public function ReplyForm() |
||
875 | { |
||
876 | // Ensure replies are enabled |
||
877 | if (!$this->getRepliesEnabled()) { |
||
878 | return null; |
||
879 | } |
||
880 | |||
881 | // Check parent is available |
||
882 | $parent = $this->Parent(); |
||
0 ignored issues
–
show
The method
Parent() does not exist on SilverStripe\Comments\Model\Comment . Did you maybe mean getParent() ?
This check marks calls to methods that do not seem to exist on an object. This is most likely the result of a method being renamed without all references to it being renamed likewise.
Loading history...
|
|||
883 | if (!$parent || !$parent->exists()) { |
||
884 | return null; |
||
885 | } |
||
886 | |||
887 | // Build reply controller |
||
888 | $controller = CommentingController::create(); |
||
889 | $controller->setOwnerRecord($parent); |
||
890 | $controller->setParentClass($parent->ClassName); |
||
891 | $controller->setOwnerController(Controller::curr()); |
||
892 | |||
893 | return $controller->ReplyForm($this); |
||
894 | } |
||
895 | |||
896 | /** |
||
897 | * Refresh of this comment in the hierarchy |
||
898 | */ |
||
899 | public function updateDepth() |
||
900 | { |
||
901 | $parent = $this->ParentComment(); |
||
902 | if ($parent && $parent->exists()) { |
||
903 | $parent->updateDepth(); |
||
904 | $this->Depth = $parent->Depth + 1; |
||
905 | } else { |
||
906 | $this->Depth = 1; |
||
907 | } |
||
908 | } |
||
909 | } |
||
910 |