Completed
Pull Request — master (#173)
by Gordon
02:19
created

CommentsExtension::getReplyFormForJavaScript()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 1
Metric Value
c 1
b 1
f 1
dl 0
loc 11
rs 9.4285
cc 1
eloc 9
nc 1
nop 0
1
<?php
2
3
/**
4
 * Extension to {@link DataObject} to enable tracking comments.
5
 *
6
 * @package comments
7
 */
8
class CommentsExtension extends DataExtension
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
9
{
10
    /**
11
     * Default configuration values
12
     *
13
     * enabled:                     Allows commenting to be disabled even if the extension is present
14
     * enabled_cms:                 Allows commenting to be enabled or disabled via the CMS
15
     * require_login:               Boolean, whether a user needs to login (required for required_permission)
16
     * require_login_cms:           Allows require_login to be set via the CMS
17
     * required_permission:         Permission (or array of permissions) required to comment
18
     * include_js:                  Enhance operation by ajax behaviour on moderation links (required for use_preview)
19
     * use_gravatar:                Set to true to show gravatar icons
20
     * gravatar_default:            Theme for 'not found' gravatar {@see http://gravatar.com/site/implement/images}
21
     * gravatar_rating:             Gravatar rating (same as the standard default)
22
     * show_comments_when_disabled: Show older comments when commenting has been disabled.
23
     * order_comments_by:           Default sort order.
24
     * order_replies_by:            Sort order for replies.
25
     * comments_holder_id:          ID for the comments holder
26
     * comment_permalink_prefix:    ID prefix for each comment
27
     * require_moderation:          Require moderation for all comments
28
     * require_moderation_cms:      Ignore other comment moderation config settings and set via CMS
29
     * frontend_moderation:         Display unmoderated comments in the frontend, if the user can moderate them.
30
     * frontend_spam:               Display spam comments in the frontend, if the user can moderate them.
31
     * html_allowed:                Allow for sanitized HTML in comments
32
     * use_preview:                 Preview formatted comment (when allowing HTML)
33
     * nested_comments:             Enable nested comments
34
     * nested_depth:                Max depth of nested comments in levels (where root is 1 depth) 0 means no limit.
35
     *
36
     * @var array
37
     *
38
     * @config
39
     */
40
    private static $comments = array(
0 ignored issues
show
Unused Code introduced by
The property $comments is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
41
        'enabled' => true,
42
        'enabled_cms' => false,
43
        'require_login' => false,
44
        'require_login_cms' => false,
45
        'required_permission' => false,
46
        'include_js' => true,
47
        'use_gravatar' => false,
48
        'gravatar_size' => 80,
49
        'gravatar_default' => 'identicon',
50
        'gravatar_rating' => 'g',
51
        'show_comments_when_disabled' => false,
52
        'order_comments_by' => '"Created" DESC',
53
        'order_replies_by' => false,
54
        'comments_per_page' => 10,
55
        'comments_holder_id' => 'comments-holder',
56
        'comment_permalink_prefix' => 'comment-',
57
        'require_moderation' => false,
58
        'require_moderation_nonmembers' => false,
59
        'require_moderation_cms' => false,
60
        'frontend_moderation' => false,
61
        'frontend_spam' => false,
62
        'html_allowed' => false,
63
        'html_allowed_elements' => array('a', 'img', 'i', 'b'),
64
        'use_preview' => false,
65
        'nested_comments' => false,
66
        'nested_depth' => 2,
67
    );
68
69
    /**
70
     * @var array
71
     */
72
    private static $db = array(
0 ignored issues
show
Unused Code introduced by
The property $db is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
73
        'ProvideComments' => 'Boolean',
74
        'ModerationRequired' => 'Enum(\'None,Required,NonMembersOnly\',\'None\')',
75
        'CommentsRequireLogin' => 'Boolean',
76
    );
77
78
    /**
79
     * CMS configurable options should default to the config values, but respect
80
     * default values specified by the object
81
     */
82
    public function populateDefaults()
83
    {
84
        $defaults = $this->owner->config()->defaults;
85
86
        // Set if comments should be enabled by default
87 View Code Duplication
        if (isset($defaults['ProvideComments'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
88
            $this->owner->ProvideComments = $defaults['ProvideComments'];
89
        } else {
90
            $this->owner->ProvideComments = $this->owner->getCommentsOption('enabled') ? 1 : 0;
91
        }
92
93
        // If moderation options should be configurable via the CMS then
94
        if (isset($defaults['ModerationRequired'])) {
95
            $this->owner->ModerationRequired = $defaults['ModerationRequired'];
96
        } elseif ($this->owner->getCommentsOption('require_moderation')) {
97
            $this->owner->ModerationRequired = 'Required';
98
        } elseif ($this->owner->getCommentsOption('require_moderation_nonmembers')) {
99
            $this->owner->ModerationRequired = 'NonMembersOnly';
100
        } else {
101
            $this->owner->ModerationRequired = 'None';
102
        }
103
104
        // Set login required
105 View Code Duplication
        if (isset($defaults['CommentsRequireLogin'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
106
            $this->owner->CommentsRequireLogin = $defaults['CommentsRequireLogin'];
107
        } else {
108
            $this->owner->CommentsRequireLogin = $this->owner->getCommentsOption('require_login') ? 1 : 0;
109
        }
110
    }
111
112
113
    /**
114
     * If this extension is applied to a {@link SiteTree} record then
115
     * append a Provide Comments checkbox to allow authors to trigger
116
     * whether or not to display comments
117
     *
118
     * @todo Allow customization of other {@link Commenting} configuration
119
     *
120
     * @param FieldList $fields
121
     */
122
    public function updateSettingsFields(FieldList $fields)
123
    {
124
        $options = FieldGroup::create()->setTitle(_t('CommentsExtension.COMMENTOPTIONS', 'Comments'));
125
126
        // Check if enabled setting should be cms configurable
127
        if ($this->owner->getCommentsOption('enabled_cms')) {
128
            $options->push(new CheckboxField('ProvideComments', _t('Comment.ALLOWCOMMENTS', 'Allow Comments')));
129
        }
130
131
        // Check if we should require users to login to comment
132
        if ($this->owner->getCommentsOption('require_login_cms')) {
133
            $options->push(
134
                new CheckboxField(
135
                    'CommentsRequireLogin',
136
                    _t('Comments.COMMENTSREQUIRELOGIN', 'Require login to comment')
137
                )
138
            );
139
        }
140
141
        if ($options->FieldList()->count()) {
142
            if ($fields->hasTabSet()) {
143
                $fields->addFieldsToTab('Root.Settings', $options);
0 ignored issues
show
Documentation introduced by
$options is of type object<FieldGroup>, 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...
144
            } else {
145
                $fields->push($options);
146
            }
147
        }
148
149
        // Check if moderation should be enabled via cms configurable
150
        if ($this->owner->getCommentsOption('require_moderation_cms')) {
151
            $moderationField = new DropdownField('ModerationRequired', 'Comment Moderation', array(
152
                'None' => _t('CommentsExtension.MODERATIONREQUIRED_NONE', 'No moderation required'),
153
                'Required' => _t('CommentsExtension.MODERATIONREQUIRED_REQUIRED', 'Moderate all comments'),
154
                'NonMembersOnly' => _t(
155
                    'CommentsExtension.MODERATIONREQUIRED_NONMEMBERSONLY',
156
                    'Only moderate non-members'
157
                ),
158
            ));
159
            if ($fields->hasTabSet()) {
160
                $fields->addFieldsToTab('Root.Settings', $moderationField);
0 ignored issues
show
Documentation introduced by
$moderationField is of type object<DropdownField>, 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...
161
            } else {
162
                $fields->push($moderationField);
163
            }
164
        }
165
    }
166
167
    /**
168
     * Get comment moderation rules for this parent
169
     *
170
     * None:           No moderation required
171
     * Required:       All comments
172
     * NonMembersOnly: Only anonymous users
173
     *
174
     * @return string
175
     */
176
    public function getModerationRequired()
177
    {
178
        if ($this->owner->getCommentsOption('require_moderation_cms')) {
179
            return $this->owner->getField('ModerationRequired');
180
        } elseif ($this->owner->getCommentsOption('require_moderation')) {
181
            return 'Required';
182
        } elseif ($this->owner->getCommentsOption('require_moderation_nonmembers')) {
183
            return 'NonMembersOnly';
184
        } else {
185
            return 'None';
186
        }
187
    }
188
189
    /**
190
     * Determine if users must be logged in to post comments
191
     *
192
     * @return boolean
193
     */
194
    public function getCommentsRequireLogin()
195
    {
196
        if ($this->owner->getCommentsOption('require_login_cms')) {
197
            return (bool) $this->owner->getField('CommentsRequireLogin');
198
        } else {
199
            return (bool) $this->owner->getCommentsOption('require_login');
200
        }
201
    }
202
203
    /**
204
     * Returns the RelationList of all comments against this object. Can be used as a data source
205
     * for a gridfield with write access.
206
     *
207
     * @return CommentList
208
     */
209
    public function AllComments()
210
    {
211
        $order = $this->owner->getCommentsOption('order_comments_by');
212
        $comments = CommentList::create($this->ownerBaseClass)
213
            ->forForeignID($this->owner->ID)
214
            ->sort($order);
215
        $this->owner->extend('updateAllComments', $comments);
216
        return $comments;
217
    }
218
219
    /**
220
     * Returns all comments against this object, with with spam and unmoderated items excluded, for use in the frontend
221
     *
222
     * @return CommentList
223
     */
224
    public function AllVisibleComments()
225
    {
226
        $list = $this->AllComments();
227
228
        // Filter spam comments for non-administrators if configured
229
        $showSpam = $this->owner->getCommentsOption('frontend_spam') && $this->owner->canModerateComments();
230
        if (!$showSpam) {
231
            $list = $list->filter('IsSpam', 0);
232
        }
233
234
        // Filter un-moderated comments for non-administrators if moderation is enabled
235
        $showUnmoderated = ($this->owner->ModerationRequired === 'None')
236
            || ($this->owner->getCommentsOption('frontend_moderation') && $this->owner->canModerateComments());
237
        if (!$showUnmoderated) {
238
            $list = $list->filter('Moderated', 1);
239
        }
240
241
        $this->owner->extend('updateAllVisibleComments', $list);
242
        return $list;
243
    }
244
245
    /**
246
     * Returns the root level comments, with spam and unmoderated items excluded, for use in the frontend
247
     *
248
     * @return CommentList
249
     */
250
    public function Comments()
251
    {
252
        $list = $this->AllVisibleComments();
253
254
        // If nesting comments, only show root level
255
        if ($this->owner->getCommentsOption('nested_comments')) {
256
            $list = $list->filter('ParentCommentID', 0);
257
        }
258
259
        $this->owner->extend('updateComments', $list);
260
        return $list;
261
    }
262
263
    /**
264
     * Returns a paged list of the root level comments, with spam and unmoderated items excluded,
265
     * for use in the frontend
266
     *
267
     * @return PaginatedList
268
     */
269 View Code Duplication
    public function PagedComments()
0 ignored issues
show
Duplication introduced by
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...
270
    {
271
        $list = $this->Comments();
272
273
        // Add pagination
274
        $list = new PaginatedList($list, Controller::curr()->getRequest());
0 ignored issues
show
Documentation introduced by
\Controller::curr()->getRequest() is of type object<SS_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...
275
        $list->setPaginationGetVar('commentsstart' . $this->owner->ID);
276
        $list->setPageLength($this->owner->getCommentsOption('comments_per_page'));
277
278
        $this->owner->extend('updatePagedComments', $list);
279
        return $list;
280
    }
281
282
    /**
283
     * Check if comments are configured for this page even if they are currently disabled.
284
     * Do not include the comments on pages which don't have id's such as security pages
285
     *
286
     * @deprecated since version 2.0
287
     *
288
     * @return boolean
289
     */
290
    public function getCommentsConfigured()
291
    {
292
        Deprecation::notice('2.0', 'getCommentsConfigured is deprecated. Use getCommentsEnabled instead');
293
        return true; // by virtue of all classes with this extension being 'configured'
294
    }
295
296
    /**
297
     * Determine if comments are enabled for this instance
298
     *
299
     * @return boolean
300
     */
301
    public function getCommentsEnabled()
302
    {
303
        // Don't display comments form for pseudo-pages (such as the login form)
304
        if (!$this->owner->exists()) {
305
            return false;
306
        }
307
308
        // Determine which flag should be used to determine if this is enabled
309
        if ($this->owner->getCommentsOption('enabled_cms')) {
310
            return $this->owner->ProvideComments;
311
        } else {
312
            return $this->owner->getCommentsOption('enabled');
313
        }
314
    }
315
316
    /**
317
     * Get the HTML ID for the comment holder in the template
318
     *
319
     * @return string
320
     */
321
    public function getCommentHolderID()
322
    {
323
        return $this->owner->getCommentsOption('comments_holder_id');
324
    }
325
326
    /**
327
     * @deprecated since version 2.0
328
     */
329
    public function getPostingRequiresPermission()
330
    {
331
        Deprecation::notice('2.0', 'Use getPostingRequiredPermission instead');
332
        return $this->getPostingRequiredPermission();
333
    }
334
335
    /**
336
     * Permission codes required in order to post (or empty if none required)
337
     *
338
     * @return string|array Permission or list of permissions, if required
339
     */
340
    public function getPostingRequiredPermission()
341
    {
342
        return $this->owner->getCommentsOption('required_permission');
343
    }
344
345
    public function canPost()
346
    {
347
        Deprecation::notice('2.0', 'Use canPostComment instead');
348
        return $this->canPostComment();
349
    }
350
351
    /**
352
     * Determine if a user can post comments on this item
353
     *
354
     * @param Member $member Member to check
0 ignored issues
show
Documentation introduced by
Should the type for parameter $member not be Member|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

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...
355
     *
356
     * @return boolean
357
     */
358
    public function canPostComment($member = null)
359
    {
360
        // Deny if not enabled for this object
361
        if (!$this->owner->CommentsEnabled) {
362
            return false;
363
        }
364
365
        // Check if member is required
366
        $requireLogin = $this->owner->CommentsRequireLogin;
367
        if (!$requireLogin) {
368
            return true;
369
        }
370
371
        // Check member is logged in
372
        $member = $member ?: Member::currentUser();
373
        if (!$member) {
374
            return false;
375
        }
376
377
        // If member required check permissions
378
        $requiredPermission = $this->owner->PostingRequiredPermission;
379
        if ($requiredPermission && !Permission::checkMember($member, $requiredPermission)) {
0 ignored issues
show
Unused Code introduced by
This if statement, and the following return statement can be replaced with return !($requiredPermis... $requiredPermission));.
Loading history...
380
            return false;
381
        }
382
        return true;
383
    }
384
385
    /**
386
     * Determine if this member can moderate comments in the CMS
387
     *
388
     * @param Member $member
0 ignored issues
show
Documentation introduced by
Should the type for parameter $member not be Member|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

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...
389
     *
390
     * @return boolean
391
     */
392
    public function canModerateComments($member = null)
393
    {
394
        // Deny if not enabled for this object
395
        if (!$this->owner->CommentsEnabled) {
396
            return false;
397
        }
398
399
        // Fallback to can-edit
400
        return $this->owner->canEdit($member);
401
    }
402
403
    public function getRssLink()
404
    {
405
        Deprecation::notice('2.0', 'Use getCommentRSSLink instead');
406
        return $this->getCommentRSSLink();
407
    }
408
409
    /**
410
     * Gets the RSS link to all comments
411
     *
412
     * @return string
413
     */
414
    public function getCommentRSSLink()
415
    {
416
        return Controller::join_links(Director::baseURL(), 'CommentingController/rss');
417
    }
418
419
    public function getRssLinkPage()
420
    {
421
        Deprecation::notice('2.0', 'Use getCommentRSSLinkPage instead');
422
        return $this->getCommentRSSLinkPage();
423
    }
424
425
    /**
426
     * Get the RSS link to all comments on this page
427
     *
428
     * @return string
429
     */
430
    public function getCommentRSSLinkPage()
431
    {
432
        return Controller::join_links(
433
            $this->getCommentRSSLink(), $this->ownerBaseClass, $this->owner->ID
434
        );
435
    }
436
437
    /**
438
     * Comments interface for the front end. Includes the CommentAddForm and the composition
439
     * of the comments display.
440
     *
441
     * To customize the html see templates/CommentInterface.ss or extend this function with
442
     * your own extension.
443
     *
444
     * @todo Cleanup the passing of all this configuration based functionality
445
     *
446
     * @see  docs/en/Extending
447
     */
448
    public function CommentsForm()
0 ignored issues
show
Documentation introduced by
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 @return annotation as described here.

Loading history...
449
    {
450
        // Check if enabled
451
        $enabled = $this->getCommentsEnabled();
452
        if ($enabled && $this->owner->getCommentsOption('include_js')) {
453
            Requirements::javascript(THIRDPARTY_DIR . '/jquery/jquery.js');
454
            Requirements::javascript(THIRDPARTY_DIR . '/jquery-entwine/dist/jquery.entwine-dist.js');
455
            Requirements::javascript(THIRDPARTY_DIR . '/jquery-validate/lib/jquery.form.js');
456
            Requirements::javascript(COMMENTS_THIRDPARTY . '/jquery-validate/jquery.validate.min.js');
457
            Requirements::add_i18n_javascript('comments/javascript/lang');
458
            Requirements::javascript('comments/javascript/CommentsInterface.js');
459
        }
460
461
        $controller = CommentingController::create();
462
        $controller->setOwnerRecord($this->owner);
463
        $controller->setBaseClass($this->ownerBaseClass);
464
        $controller->setOwnerController(Controller::curr());
465
466
        $moderatedSubmitted = Session::get('CommentsModerated');
467
        Session::clear('CommentsModerated');
468
469
        $form = ($enabled) ? $controller->CommentsForm() : false;
470
471
        // a little bit all over the show but to ensure a slightly easier upgrade for users
472
        // return back the same variables as previously done in comments
473
        return $this
474
            ->owner
475
            ->customise(array(
476
                'AddCommentForm' => $form,
477
                'ModeratedSubmitted' => $moderatedSubmitted,
478
            ))
479
            ->renderWith('CommentsInterface');
480
    }
481
482
    /*
483
    JavaScript form reply requires an empty form, when the reply button is
484
    clicked the correct values are inserted, the form moved, and then shown
485
     */
486
    public function getReplyFormForJavaScript() {
0 ignored issues
show
Documentation introduced by
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 @return annotation as described here.

Loading history...
487
        // Build reply controller
488
        $controller = CommentingController::create();
489
        $controller->setOwnerRecord($this->owner);
490
        $controller->setBaseClass($this->owner->ClassName);
491
        $controller->setOwnerController(Controller::curr());
492
        $comment = new Comment();
493
        $comment->ID='JSOnly';
494
        $comment->ParentID = $this->owner->ID;
495
        return $controller->ReplyForm($comment);
496
    }
497
498
    /**
499
     * Returns whether this extension instance is attached to a {@link SiteTree} object
500
     *
501
     * @return bool
502
     */
503
    public function attachedToSiteTree()
504
    {
505
        $class = $this->ownerBaseClass;
506
        return (is_subclass_of($class, 'SiteTree')) || ($class == 'SiteTree');
507
    }
508
509
    /**
510
     * @deprecated 1.0 Please use {@link CommentsExtension->CommentsForm()}
511
     */
512
    public function PageComments()
0 ignored issues
show
Documentation introduced by
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 @return annotation as described here.

Loading history...
513
    {
514
        // This method is very commonly used, don't throw a warning just yet
515
        Deprecation::notice('1.0', '$PageComments is deprecated. Please use $CommentsForm');
516
        return $this->CommentsForm();
517
    }
518
519
    /**
520
     * Get the commenting option for this object
521
     *
522
     * This can be overridden in any instance or extension to customise the option available
523
     *
524
     * @param string $key
525
     *
526
     * @return mixed Result if the setting is available, or null otherwise
527
     */
528
    public function getCommentsOption($key)
529
    {
530
        $settings = $this->owner // In case singleton is called on the extension directly
531
            ? $this->owner->config()->comments
532
            : Config::inst()->get(__CLASS__, 'comments');
533
        $value = null;
534
        if (isset($settings[$key])) {
535
            $value = $settings[$key];
536
        }
537
538
        // To allow other extensions to customise this option
539
        if ($this->owner) {
540
            $this->owner->extend('updateCommentsOption', $key, $value);
541
        }
542
        return $value;
543
    }
544
545
    /**
546
     * Add moderation functions to the current fieldlist
547
     *
548
     * @param FieldList $fields
549
     */
550
    protected function updateModerationFields(FieldList $fields)
551
    {
552
        Requirements::css(COMMENTS_DIR . '/css/cms.css');
553
554
        $newComments = $this->owner->AllComments()->filter('Moderated', 0);
555
556
        $newGrid = new CommentsGridField(
557
            'NewComments',
558
            _t('CommentsAdmin.NewComments', 'New'),
559
            $newComments,
560
            CommentsGridFieldConfig::create()
561
        );
562
563
        $approvedComments = $this->owner->AllComments()->filter('Moderated', 1)->filter('IsSpam', 0);
564
565
        $approvedGrid = new CommentsGridField(
566
            'ApprovedComments',
567
            _t('CommentsAdmin.Comments', 'Approved'),
568
            $approvedComments,
569
            CommentsGridFieldConfig::create()
570
        );
571
572
        $spamComments = $this->owner->AllComments()->filter('Moderated', 1)->filter('IsSpam', 1);
573
574
        $spamGrid = new CommentsGridField(
575
            'SpamComments',
576
            _t('CommentsAdmin.SpamComments', 'Spam'),
577
            $spamComments,
578
            CommentsGridFieldConfig::create()
579
        );
580
581
        $newCount = '(' . count($newComments) . ')';
582
        $approvedCount = '(' . count($approvedComments) . ')';
583
        $spamCount = '(' . count($spamComments) . ')';
584
585
        if ($fields->hasTabSet()) {
586
            $tabs = new TabSet(
587
                'Comments',
588
                new Tab('CommentsNewCommentsTab', _t('CommentAdmin.NewComments', 'New') . ' ' . $newCount,
589
                    $newGrid
590
                ),
591
                new Tab('CommentsCommentsTab', _t('CommentAdmin.Comments', 'Approved') . ' ' . $approvedCount,
592
                    $approvedGrid
593
                ),
594
                new Tab('CommentsSpamCommentsTab', _t('CommentAdmin.SpamComments', 'Spam') . ' ' . $spamCount,
595
                    $spamGrid
596
                )
597
            );
598
            $fields->addFieldToTab('Root', $tabs);
599
        } else {
600
            $fields->push($newGrid);
601
            $fields->push($approvedGrid);
602
            $fields->push($spamGrid);
603
        }
604
    }
605
606
    public function updateCMSFields(FieldList $fields)
607
    {
608
        // Disable moderation if not permitted
609
        if ($this->owner->canModerateComments()) {
610
            $this->updateModerationFields($fields);
611
        }
612
613
        // If this isn't a page we should merge the settings into the CMS fields
614
        if (!$this->attachedToSiteTree()) {
615
            $this->updateSettingsFields($fields);
616
        }
617
    }
618
}
619