Completed
Pull Request — master (#421)
by Robbie
02:31
created

Blog::getSettingsFields()   B

Complexity

Conditions 4
Paths 8

Size

Total Lines 72
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 72
rs 8.7033
c 0
b 0
f 0
cc 4
eloc 28
nc 8
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace SilverStripe\Blog\Model;
4
5
use Page;
6
use PageController;
7
use SilverStripe\Blog\Admin\GridFieldCategorisationConfig;
8
use SilverStripe\Blog\Forms\GridField\GridFieldConfig_BlogPost;
9
use SilverStripe\CMS\Controllers\RootURLController;
10
use SilverStripe\Control\Controller;
11
use SilverStripe\Control\RSS\RSSFeed;
12
use SilverStripe\Core\Convert;
13
use SilverStripe\Forms\GridField\GridField;
14
use SilverStripe\Forms\ListboxField;
15
use SilverStripe\Forms\NumericField;
16
use SilverStripe\ORM\ArrayList;
17
use SilverStripe\ORM\DataObject;
18
use SilverStripe\ORM\DB;
19
use SilverStripe\ORM\FieldType\DBDatetime;
20
use SilverStripe\ORM\PaginatedList;
21
use SilverStripe\ORM\UnsavedRelationList;
22
use SilverStripe\Security\Group;
23
use SilverStripe\Security\Member;
24
use SilverStripe\Security\Permission;
25
use SilverStripe\Security\PermissionProvider;
26
use SilverStripe\View\Requirements;
27
28
/**
29
 * Blog Holder
30
 *
31
 * @package silverstripe
32
 * @subpackage blog
33
 *
34
 * @method HasManyList Tags() List of tags in this blog
35
 * @method HasManyList Categories() List of categories in this blog
36
 * @method ManyManyList Editors() List of editors
37
 * @method ManyManyList Writers() List of writers
38
 * @method ManyManyList Contributors() List of contributors
39
 */
40
class Blog extends Page implements PermissionProvider
41
{
42
    /**
43
     * Permission for user management.
44
     *
45
     * @var string
46
     */
47
    const MANAGE_USERS = 'BLOG_MANAGE_USERS';
48
49
    /**
50
     * If true, users assigned as editor, writer, or contributor will be automatically granted
51
     * CMS_ACCESS_CMSMain permission. If false, only users with this permission already may be
52
     * assigned.
53
     *
54
     * @config
55
     *
56
     * @var boolean
57
     */
58
    private static $grant_user_access = true;
0 ignored issues
show
Unused Code introduced by
The property $grant_user_access 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...
59
60
    /**
61
     * Permission to either require, or grant to users assigned to work on this blog.
62
     *
63
     * @config
64
     *
65
     * @var string
66
     */
67
    private static $grant_user_permission = 'CMS_ACCESS_CMSMain';
0 ignored issues
show
Unused Code introduced by
The property $grant_user_permission 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...
68
69
    /**
70
     * Group code to assign newly granted users to.
71
     *
72
     * @config
73
     *
74
     * @var string
75
     */
76
    private static $grant_user_group = 'blog-users';
0 ignored issues
show
Unused Code introduced by
The property $grant_user_group 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...
77
78
    /**
79
     * {@inheritDoc}
80
     * @var string
81
     */
82
    private static $table_name = 'Blog';
0 ignored issues
show
Unused Code introduced by
The property $table_name 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...
83
84
    /**
85
     * @var array
86
     */
87
    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...
88
        'PostsPerPage' => 'Int',
89
    );
90
91
    /**
92
     * @var array
93
     */
94
    private static $has_many = array(
0 ignored issues
show
Unused Code introduced by
The property $has_many 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...
95
        'Tags' => 'SilverStripe\\Blog\\Model\\BlogTag',
96
        'Categories' => 'SilverStripe\\Blog\\Model\\BlogCategory',
97
    );
98
99
    /**
100
     * @var array
101
     */
102
    private static $many_many = array(
0 ignored issues
show
Unused Code introduced by
The property $many_many 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...
103
        'Editors' => 'SilverStripe\\Security\\Member',
104
        'Writers' => 'SilverStripe\\Security\\Member',
105
        'Contributors' => 'SilverStripe\\Security\\Member',
106
    );
107
108
    /**
109
     * @var array
110
     */
111
    private static $allowed_children = array(
0 ignored issues
show
Unused Code introduced by
The property $allowed_children 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...
112
        'SilverStripe\\Blog\\Model\\BlogPost',
113
    );
114
115
    /**
116
     * @var array
117
     */
118
    private static $extensions = array(
0 ignored issues
show
Unused Code introduced by
The property $extensions 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...
119
        'SilverStripe\\Blog\\Model\\BlogFilter',
120
    );
121
122
    /**
123
     * @var array
124
     */
125
    private static $defaults = array(
0 ignored issues
show
Unused Code introduced by
The property $defaults 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...
126
        'ProvideComments' => false,
127
        'PostsPerPage'    => 10
128
    );
129
130
    /**
131
     * @var string
132
     */
133
    private static $description = 'Adds a blog to your website.';
0 ignored issues
show
Unused Code introduced by
The property $description 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...
134
135
    private static $icon = 'blog/images/site-tree-icon.png';
0 ignored issues
show
Unused Code introduced by
The property $icon 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...
136
137
    /**
138
     * {@inheritdoc}
139
     */
140
    public function getCMSFields()
141
    {
142
        Requirements::css(BLOGGER_DIR . '/css/cms.css');
143
        Requirements::javascript(BLOGGER_DIR . '/js/cms.js');
144
145
        $this->beforeUpdateCMSFields(function ($fields) {
146
            if (!$this->canEdit()) {
147
                return;
148
            }
149
150
            $categories = GridField::create(
151
                'Categories',
152
                _t('Blog.Categories', 'Categories'),
153
                $this->Categories(),
154
                GridFieldCategorisationConfig::create(
155
                    15,
156
                    $this->Categories()->sort('Title'),
157
                    BlogCategory::class,
158
                    'Categories',
159
                    'BlogPosts'
160
                )
161
            );
162
163
            $tags = GridField::create(
164
                'Tags',
165
                _t('Blog.Tags', 'Tags'),
166
                $this->Tags(),
167
                GridFieldCategorisationConfig::create(
168
                    15,
169
                    $this->Tags()->sort('Title'),
170
                    BlogTag::class,
171
                    'Tags',
172
                    'BlogPosts'
173
                )
174
            );
175
176
            /**
177
             * @var FieldList $fields
178
             */
179
            $fields->addFieldsToTab(
180
                'Root.Categorisation',
181
                array(
182
                    $categories,
183
                    $tags
184
                )
185
            );
186
187
            $fields->findOrMakeTab('Root.Categorisation')->addExtraClass('blog-cms-categorisation');
188
        });
189
190
        return parent::getCMSFields();
191
    }
192
193
    /**
194
     * {@inheritdoc}
195
     */
196
    public function canEdit($member = null)
197
    {
198
        $member = $this->getMember($member);
199
200
        if ($this->isEditor($member)) {
201
            return true;
202
        }
203
204
        return parent::canEdit($member);
205
    }
206
207
    /**
208
     * @param null|int|Member $member
209
     *
210
     * @return null|Member
211
     */
212 View Code Duplication
    protected function getMember($member = null)
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...
213
    {
214
        if (!$member) {
215
            $member = Member::currentUser();
216
        }
217
218
        if (is_numeric($member)) {
219
            $member = Member::get()->byID($member);
220
        }
221
222
        return $member;
223
    }
224
225
    /**
226
     * Check if this member is an editor of the blog.
227
     *
228
     * @param Member $member
229
     *
230
     * @return bool
231
     */
232
    public function isEditor($member)
233
    {
234
        $isEditor = $this->isMemberOf($member, $this->Editors());
235
        $this->extend('updateIsEditor', $isEditor, $member);
236
237
        return $isEditor;
238
    }
239
240
    /**
241
     * Determine if the given member belongs to the given relation.
242
     *
243
     * @param Member $member
244
     * @param DataList $relation
245
     *
246
     * @return bool
247
     */
248 View Code Duplication
    protected function isMemberOf($member, $relation)
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...
249
    {
250
        if (!$member || !$member->exists()) {
251
            return false;
252
        }
253
254
        if ($relation instanceof UnsavedRelationList) {
255
            return in_array($member->ID, $relation->getIDList());
256
        }
257
258
        return $relation->byID($member->ID) !== null;
259
    }
260
261
    /**
262
     * Determine the role of the given member.
263
     *
264
     * Call be called via template to determine the current user.
265
     *
266
     * @example "Hello $RoleOf($CurrentMember.ID)"
267
     *
268
     * @param int|Member $member
269
     *
270
     * @return null|string
271
     */
272
    public function RoleOf($member)
273
    {
274
        if (is_numeric($member)) {
275
            $member = Member::get()->byId($member);
276
        }
277
278
        if (!$member) {
279
            return null;
280
        }
281
282
        if ($this->isEditor($member)) {
283
            return _t('Blog.EDITOR', 'Editor');
284
        }
285
286
        if ($this->isWriter($member)) {
287
            return _t('Blog.WRITER', 'Writer');
288
        }
289
290
        if ($this->isContributor($member)) {
291
            return _t('Blog.CONTRIBUTOR', 'Contributor');
292
        }
293
294
        return null;
295
    }
296
297
    /**
298
     * Check if this member is a writer of the blog.
299
     *
300
     * @param Member $member
301
     *
302
     * @return bool
303
     */
304
    public function isWriter($member)
305
    {
306
        $isWriter = $this->isMemberOf($member, $this->Writers());
307
        $this->extend('updateIsWriter', $isWriter, $member);
308
309
        return $isWriter;
310
    }
311
312
    /**
313
     * Check if this member is a contributor of the blog.
314
     *
315
     * @param Member $member
316
     *
317
     * @return bool
318
     */
319
    public function isContributor($member)
320
    {
321
        $isContributor = $this->isMemberOf($member, $this->Contributors());
322
        $this->extend('updateIsContributor', $isContributor, $member);
323
324
        return $isContributor;
325
    }
326
327
    /**
328
     * {@inheritdoc}
329
     */
330
    public function canAddChildren($member = null)
331
    {
332
        $member = $this->getMember($member);
333
334
        if ($this->isEditor($member) || $this->isWriter($member) || $this->isContributor($member)) {
335
            return true;
336
        }
337
338
        return parent::canAddChildren($member);
339
    }
340
341
    /**
342
     * {@inheritdoc}
343
     */
344
    public function getSettingsFields()
345
    {
346
        $fields = parent::getSettingsFields();
347
348
        $fields->addFieldToTab(
349
            'Root.Settings',
350
            NumericField::create('PostsPerPage', _t('Blog.PostsPerPage', 'Posts Per Page'))
351
        );
352
353
        $members = $this->getCandidateUsers()->map()->toArray();
354
355
        $editorField = ListboxField::create('Editors', 'Editors', $members)
356
            // ->setMultiple(true)
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% 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...
357
            ->setRightTitle('<a class="toggle-description">help</a>')
358
            ->setDescription('
359
				An editor has control over specific Blogs, and all posts included within it. Short of being able to assign other editors to a blog, they are able to handle most changes to their assigned blog.<br />
360
				<br />
361
				Editors have these permissions:<br />
362
				<br />
363
				Update or publish any BlogPost in their Blog<br />
364
				Update or publish their Blog<br />
365
				Assign/unassign writers to their Blog<br />
366
				Assign/unassign contributors to their Blog<br />
367
				Assign/unassign any member as an author of a particular BlogPost
368
			');
369
370
        if (!$this->canEditEditors()) {
371
            $editorField = $editorField->performDisabledTransformation();
372
        }
373
374
        $writerField = ListboxField::create('Writers', 'Writers', $members)
375
            // ->setMultiple(true)
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% 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...
376
            ->setRightTitle('<a class="toggle-description">help</a>')
377
            ->setDescription('
378
				A writer has full control over creating, editing and publishing BlogPosts they have authored or have been assigned to. Writers are unable to edit BlogPosts to which they are not assigned.<br />
379
				<br />
380
				Writers have these permissions:<br />
381
				<br />
382
				Update or publish any BlogPost they have authored or have been assigned to<br />
383
				Assign/unassign any member as an author of a particular BlogPost they have authored or have been assigned to
384
			');
385
386
        if (!$this->canEditWriters()) {
387
            $writerField = $writerField->performDisabledTransformation();
388
        }
389
390
        $contributorField = ListboxField::create('Contributors', 'Contributors', $members)
391
            // ->setMultiple(true)
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% 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...
392
            ->setRightTitle('<a class="toggle-description">help</a>')
393
            ->setDescription('
394
				Contributors have the ability to create or edit BlogPosts, but are unable to publish without authorisation of an editor. They are also unable to assign other contributing authors to any of their BlogPosts.<br />
395
				<br />
396
				Contributors have these permissions:<br />
397
				<br />
398
				Update any BlogPost they have authored or have been assigned to
399
			');
400
401
        if (!$this->canEditContributors()) {
402
            $contributorField = $contributorField->performDisabledTransformation();
403
        }
404
405
        $fields->addFieldsToTab(
406
            'Root.Users',
407
            array(
408
                $editorField,
409
                $writerField,
410
                $contributorField
411
            )
412
        );
413
414
        return $fields;
415
    }
416
417
    /**
418
     * Gets the list of user candidates to be assigned to assist with this blog.
419
     *
420
     * @return SS_List
421
     */
422
    protected function getCandidateUsers()
423
    {
424
        if ($this->config()->grant_user_access) {
425
            $list = Member::get();
426
            $this->extend('updateCandidateUsers', $list);
427
            return $list;
428
        } else {
429
            return Permission::get_members_by_permission(
430
                $this->config()->grant_user_permission
431
            );
432
        }
433
    }
434
435
    /**
436
     * Determine if this user can edit the editors list.
437
     *
438
     * @param int|Member $member
439
     *
440
     * @return bool
441
     */
442
    public function canEditEditors($member = null)
443
    {
444
        $member = $this->getMember($member);
445
446
        $extended = $this->extendedCan('canEditEditors', $member);
447
448
        if ($extended !== null) {
449
            return $extended;
450
        }
451
452
        return Permission::checkMember($member, self::MANAGE_USERS);
0 ignored issues
show
Bug Compatibility introduced by
The expression \SilverStripe\Security\P...r, self::MANAGE_USERS); of type boolean|string adds the type string to the return on line 452 which is incompatible with the return type documented by SilverStripe\Blog\Model\Blog::canEditEditors of type boolean.
Loading history...
453
    }
454
455
    /**
456
     * Determine if this user can edit writers list.
457
     *
458
     * @param int|Member $member
459
     *
460
     * @return boolean
461
     */
462 View Code Duplication
    public function canEditWriters($member = null)
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...
463
    {
464
        $member = $this->getMember($member);
465
466
        $extended = $this->extendedCan('canEditWriters', $member);
467
468
        if ($extended !== null) {
469
            return $extended;
470
        }
471
472
        if ($this->isEditor($member)) {
473
            return true;
474
        }
475
476
        return Permission::checkMember($member, self::MANAGE_USERS);
0 ignored issues
show
Bug Compatibility introduced by
The expression \SilverStripe\Security\P...r, self::MANAGE_USERS); of type boolean|string adds the type string to the return on line 476 which is incompatible with the return type documented by SilverStripe\Blog\Model\Blog::canEditWriters of type boolean.
Loading history...
477
    }
478
479
    /**
480
     * Determines if this user can edit the contributors list.
481
     *
482
     * @param int|Member $member
483
     *
484
     * @return boolean
485
     */
486 View Code Duplication
    public function canEditContributors($member = null)
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...
487
    {
488
        $member = $this->getMember($member);
489
490
        $extended = $this->extendedCan('canEditContributors', $member);
491
492
        if ($extended !== null) {
493
            return $extended;
494
        }
495
496
        if ($this->isEditor($member)) {
497
            return true;
498
        }
499
500
        return Permission::checkMember($member, self::MANAGE_USERS);
0 ignored issues
show
Bug Compatibility introduced by
The expression \SilverStripe\Security\P...r, self::MANAGE_USERS); of type boolean|string adds the type string to the return on line 500 which is incompatible with the return type documented by SilverStripe\Blog\Model\Blog::canEditContributors of type boolean.
Loading history...
501
    }
502
503
    /**
504
     * Returns BlogPosts for a given date period.
505
     *
506
     * @param int $year
507
     * @param null|int $month
508
     * @param null|int $day
509
     *
510
     * @return DataList
511
     */
512
    public function getArchivedBlogPosts($year, $month = null, $day = null)
513
    {
514
        $query = $this->getBlogPosts()->dataQuery();
515
516
        $stage = $query->getQueryParam('Versioned.stage');
517
518
        if ($stage) {
519
            $stage = '_' . $stage;
520
        }
521
522
        $query->innerJoin(
523
            DataObject::getSchema()->tableName(BlogPost::class),
524
            sprintf('"SiteTree%s"."ID" = "BlogPost%s"."ID"', $stage, $stage)
525
        );
526
527
        $conn = DB::getConn();
0 ignored issues
show
Deprecated Code introduced by
The method SilverStripe\ORM\DB::getConn() has been deprecated with message: since version 4.0 Use DB::get_conn instead

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...
528
529
        // Filter by year
530
        $yearCond = $conn->formattedDatetimeClause('"BlogPost"."PublishDate"', '%Y');
531
        $query->where(sprintf('%s = \'%04d\'', $yearCond, Convert::raw2sql($year)));
532
533
        // Filter by month (if given)
534
        if ($month) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $month of type null|integer is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
535
            $monthCond = $conn->formattedDatetimeClause('"BlogPost"."PublishDate"', '%m');
536
            $query->where(sprintf('%s = \'%02d\'', $monthCond, Convert::raw2sql($month)));
537
538
            if ($day) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $day of type null|integer is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
539
                $dayCond = $conn->formattedDatetimeClause('"BlogPost"."PublishDate"', '%d');
540
                $query->where(sprintf('%s = \'%02d\'', $dayCond, Convert::raw2sql($day)));
541
            }
542
        }
543
544
545
        return $this->getBlogPosts()->setDataQuery($query);
546
    }
547
548
    /**
549
     * Return blog posts.
550
     *
551
     * @return DataList of BlogPost objects
552
     */
553
    public function getBlogPosts()
554
    {
555
        $blogPosts = BlogPost::get()->filter('ParentID', $this->ID);
556
557
        $this->extend('updateGetBlogPosts', $blogPosts);
558
559
        return $blogPosts;
560
    }
561
562
    /**
563
     * Get a link to a Member profile.
564
     *
565
     * @param string $urlSegment
566
     *
567
     * @return string
568
     */
569
    public function ProfileLink($urlSegment)
570
    {
571
        $baseLink = $this->Link();
572
        if ($baseLink === '/') {
573
            // Handle homepage blogs
574
            $baseLink = RootURLController::get_homepage_link();
575
        }
576
577
        return Controller::join_links($baseLink, 'profile', $urlSegment);
578
    }
579
580
    /**
581
     * This sets the title for our gridfield.
582
     *
583
     * @return string
584
     */
585
    public function getLumberjackTitle()
586
    {
587
        return _t('Blog.LumberjackTitle', 'Blog Posts');
588
    }
589
590
    /**
591
     * This overwrites lumberjacks default gridfield config.
592
     *
593
     * @return GridFieldConfig
594
     */
595
    public function getLumberjackGridFieldConfig()
596
    {
597
        return GridFieldConfig_BlogPost::create();
598
    }
599
600
    /**
601
     * {@inheritdoc}
602
     */
603
    public function providePermissions()
604
    {
605
        return array(
606
            Blog::MANAGE_USERS => array(
607
                'name' => _t(
608
                    'Blog.PERMISSION_MANAGE_USERS_DESCRIPTION',
609
                    'Manage users for individual blogs'
610
                ),
611
                'help' => _t(
612
                    'Blog.PERMISSION_MANAGE_USERS_HELP',
613
                    'Allow assignment of Editors, Writers, or Contributors to blogs'
614
                ),
615
                'category' => _t('Blog.PERMISSIONS_CATEGORY', 'Blog permissions'),
616
                'sort' => 100
617
            )
618
        );
619
    }
620
621
    /**
622
     * {@inheritdoc}
623
     */
624
    protected function onBeforeWrite()
625
    {
626
        parent::onBeforeWrite();
627
        $this->assignGroup();
628
    }
629
630
    /**
631
     * Assign users as necessary to the blog group.
632
     */
633
    protected function assignGroup()
634
    {
635
        if (!$this->config()->grant_user_access) {
636
            return;
637
        }
638
639
        $group = $this->getUserGroup();
640
641
        // Must check if the method exists or else an error occurs when changing page type
642
        if ($this->hasMethod('Editors')) {
643
            foreach (array($this->Editors(), $this->Writers(), $this->Contributors()) as $levels) {
644
                foreach ($levels as $user) {
645
                    if (!$user->inGroup($group)) {
646
                        $user->Groups()->add($group);
647
                    }
648
                }
649
            }
650
        }
651
    }
652
653
    /**
654
     * Gets or creates the group used to assign CMS access.
655
     *
656
     * @return Group
657
     */
658
    protected function getUserGroup()
659
    {
660
        $code = $this->config()->grant_user_group;
661
662
        $group = Group::get()->filter('Code', $code)->first();
663
664
        if ($group) {
665
            return $group;
666
        }
667
668
        $group = Group::create();
669
        $group->Title = 'Blog users';
670
        $group->Code = $code;
671
672
        $group->write();
673
674
        $permission = Permission::create();
675
        $permission->Code = $this->config()->grant_user_permission;
676
677
        $group->Permissions()->add($permission);
678
679
        return $group;
680
    }
681
}
682