Completed
Pull Request — master (#479)
by Franco
01:33
created

Blog::isContributor()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 1
1
<?php
2
3
namespace SilverStripe\Blog\Model;
4
5
use Page;
6
use SilverStripe\Blog\Admin\GridFieldCategorisationConfig;
7
use SilverStripe\Blog\Forms\GridField\GridFieldConfig_BlogPost;
8
use SilverStripe\CMS\Controllers\RootURLController;
9
use SilverStripe\Control\Controller;
10
use SilverStripe\Core\Convert;
11
use SilverStripe\Core\Manifest\ModuleLoader;
12
use SilverStripe\Forms\GridField\GridField;
13
use SilverStripe\Forms\ListboxField;
14
use SilverStripe\Forms\LiteralField;
15
use SilverStripe\Forms\NumericField;
16
use SilverStripe\ORM\DataObject;
17
use SilverStripe\ORM\DB;
18
use SilverStripe\ORM\UnsavedRelationList;
19
use SilverStripe\Security\Group;
20
use SilverStripe\Security\Member;
21
use SilverStripe\Security\Permission;
22
use SilverStripe\Security\PermissionProvider;
23
use SilverStripe\Security\Security;
24
use SilverStripe\View\Requirements;
25
26
/**
27
 * Blog Holder
28
 *
29
 * @method HasManyList Tags() List of tags in this blog
30
 * @method HasManyList Categories() List of categories in this blog
31
 * @method ManyManyList Editors() List of editors
32
 * @method ManyManyList Writers() List of writers
33
 * @method ManyManyList Contributors() List of contributors
34
 */
35
class Blog extends Page implements PermissionProvider
36
{
37
    /**
38
     * Permission for user management.
39
     *
40
     * @var string
41
     */
42
    const MANAGE_USERS = 'BLOG_MANAGE_USERS';
43
44
    /**
45
     * If true, users assigned as editor, writer, or contributor will be automatically granted
46
     * CMS_ACCESS_CMSMain permission. If false, only users with this permission already may be
47
     * assigned.
48
     *
49
     * @config
50
     *
51
     * @var boolean
52
     */
53
    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...
54
55
    /**
56
     * Permission to either require, or grant to users assigned to work on this blog.
57
     *
58
     * @config
59
     *
60
     * @var string
61
     */
62
    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...
63
64
    /**
65
     * Group code to assign newly granted users to.
66
     *
67
     * @config
68
     *
69
     * @var string
70
     */
71
    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...
72
73
    /**
74
     * {@inheritDoc}
75
     * @var string
76
     */
77
    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...
78
79
    /**
80
     * @var array
81
     */
82
    private static $db = [
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...
83
        'PostsPerPage' => 'Int',
84
    ];
85
86
    /**
87
     * @var array
88
     */
89
    private static $has_many = [
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...
90
        'Tags' => BlogTag::class,
91
        'Categories' => BlogCategory::class,
92
    ];
93
94
    /**
95
     * @var array
96
     */
97
    private static $many_many = [
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...
98
        'Editors' => Member::class,
99
        'Writers' => Member::class,
100
        'Contributors' => Member::class,
101
    ];
102
103
    /**
104
     * @var array
105
     */
106
    private static $allowed_children = [
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...
107
        BlogPost::class,
108
    ];
109
110
    /**
111
     * @var array
112
     */
113
    private static $extensions = [
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...
114
        BlogFilter::class,
115
    ];
116
117
    /**
118
     * @var array
119
     */
120
    private static $defaults = [
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...
121
        'ProvideComments' => false,
122
        'PostsPerPage'    => 10
123
    ];
124
125
    /**
126
     * @var string
127
     */
128
    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...
129
130
    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...
131
132
    /**
133
     * {@inheritdoc}
134
     */
135
    public function getCMSFields()
136
    {
137
        $this->addCMSRequirements();
138
139
        $this->beforeUpdateCMSFields(function ($fields) {
140
            if (!$this->canEdit()) {
141
                return;
142
            }
143
144
            $categories = GridField::create(
145
                'Categories',
146
                _t(__CLASS__ . '.Categories', 'Categories'),
147
                $this->Categories(),
148
                GridFieldCategorisationConfig::create(
149
                    15,
150
                    $this->Categories()->sort('Title'),
151
                    BlogCategory::class,
152
                    'Categories',
153
                    'BlogPosts'
154
                )
155
            );
156
157
            $tags = GridField::create(
158
                'Tags',
159
                _t(__CLASS__ . '.Tags', 'Tags'),
160
                $this->Tags(),
161
                GridFieldCategorisationConfig::create(
162
                    15,
163
                    $this->Tags()->sort('Title'),
164
                    BlogTag::class,
165
                    'Tags',
166
                    'BlogPosts'
167
                )
168
            );
169
170
            /**
171
             * @var FieldList $fields
172
             */
173
            $fields->addFieldsToTab(
174
                'Root.Categorisation',
175
                [
176
                    $categories,
177
                    $tags
178
                ]
179
            );
180
181
            $fields->findOrMakeTab('Root.Categorisation')->addExtraClass('blog-cms-categorisation');
182
        });
183
184
        return parent::getCMSFields();
185
    }
186
187
    /**
188
     * Adds CMS related css and js overrides
189
     */
190
    protected function addCMSRequirements()
191
    {
192
        $module = ModuleLoader::getModule('silverstripe/blog');
193
        Requirements::css($module->getRelativeResourcePath('css/cms.css'));
194
        Requirements::javascript($module->getRelativeResourcePath('js/cms.js'));
195
    }
196
    /**
197
     * {@inheritdoc}
198
     */
199
    public function canEdit($member = null)
200
    {
201
        $member = $this->getMember($member);
202
203
        if ($this->isEditor($member)) {
204
            return true;
205
        }
206
207
        return parent::canEdit($member);
208
    }
209
210
    /**
211
     * @param null|int|Member $member
212
     *
213
     * @return null|Member
214
     */
215 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...
216
    {
217
        if (!$member) {
218
            $member = Security::getCurrentUser();
219
        }
220
221
        if (is_numeric($member)) {
222
            $member = Member::get()->byID($member);
223
        }
224
225
        return $member;
226
    }
227
228
    /**
229
     * Check if this member is an editor of the blog.
230
     *
231
     * @param Member $member
232
     *
233
     * @return bool
234
     */
235
    public function isEditor($member)
236
    {
237
        $isEditor = $this->isMemberOf($member, $this->Editors());
238
        $this->extend('updateIsEditor', $isEditor, $member);
239
240
        return $isEditor;
241
    }
242
243
    /**
244
     * Determine if the given member belongs to the given relation.
245
     *
246
     * @param Member $member
247
     * @param DataList $relation
248
     *
249
     * @return bool
250
     */
251 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...
252
    {
253
        if (!$member || !$member->exists()) {
254
            return false;
255
        }
256
257
        if ($relation instanceof UnsavedRelationList) {
258
            return in_array($member->ID, $relation->getIDList());
259
        }
260
261
        return $relation->byID($member->ID) !== null;
262
    }
263
264
    /**
265
     * Determine the role of the given member.
266
     *
267
     * Call be called via template to determine the current user.
268
     *
269
     * @example "Hello $RoleOf($CurrentMember.ID)"
270
     *
271
     * @param int|Member $member
272
     *
273
     * @return null|string
274
     */
275
    public function RoleOf($member)
276
    {
277
        if (is_numeric($member)) {
278
            $member = Member::get()->byId($member);
279
        }
280
281
        if (!$member) {
282
            return null;
283
        }
284
285
        if ($this->isEditor($member)) {
286
            return _t(__CLASS__ . '.EDITOR', 'Editor');
287
        }
288
289
        if ($this->isWriter($member)) {
290
            return _t(__CLASS__ . '.WRITER', 'Writer');
291
        }
292
293
        if ($this->isContributor($member)) {
294
            return _t(__CLASS__ . '.CONTRIBUTOR', 'Contributor');
295
        }
296
297
        return null;
298
    }
299
300
    /**
301
     * Check if this member is a writer of the blog.
302
     *
303
     * @param Member $member
304
     *
305
     * @return bool
306
     */
307
    public function isWriter($member)
308
    {
309
        $isWriter = $this->isMemberOf($member, $this->Writers());
310
        $this->extend('updateIsWriter', $isWriter, $member);
311
312
        return $isWriter;
313
    }
314
315
    /**
316
     * Check if this member is a contributor of the blog.
317
     *
318
     * @param Member $member
319
     *
320
     * @return bool
321
     */
322
    public function isContributor($member)
323
    {
324
        $isContributor = $this->isMemberOf($member, $this->Contributors());
325
        $this->extend('updateIsContributor', $isContributor, $member);
326
327
        return $isContributor;
328
    }
329
330
    /**
331
     * {@inheritdoc}
332
     */
333
    public function canAddChildren($member = null)
334
    {
335
        $member = $this->getMember($member);
336
337
        if ($this->isEditor($member) || $this->isWriter($member) || $this->isContributor($member)) {
338
            return true;
339
        }
340
341
        return parent::canAddChildren($member);
342
    }
343
344
    /**
345
     * {@inheritdoc}
346
     */
347
    public function getSettingsFields()
348
    {
349
        $this->addCMSRequirements();
350
        $fields = parent::getSettingsFields();
351
352
        $fields->addFieldToTab(
353
            'Root.Settings',
354
            NumericField::create('PostsPerPage', _t(__CLASS__ . '.PostsPerPage', 'Posts Per Page'))
355
        );
356
357
        $members = $this->getCandidateUsers()->map()->toArray();
358
        $toggleButton = LiteralField::create('ToggleButton', '<a class="toggle-description"></a>');
359
360
        $editorField = ListboxField::create('Editors', 'Editors', $members)
361
            ->setRightTitle($toggleButton)
362
            ->setDescription(
363
                _t(
364
                    __CLASS__ . '.UsersEditorsFieldDescription',
365
                    'An editor has control over specific Blogs, and all posts included within it. 
366
                     Short of being able to assign other editors to a blog, they are able to handle most changes to
367
                     their assigned blog. <br /><br />
368
                    Editors have these permissions:<br />
369
                    <br />
370
                    Update or publish any BlogPost in their Blog<br />
371
                    Update or publish their Blog<br />
372
                    Assign/unassign writers to their Blog<br />
373
                    Assign/unassign contributors to their Blog<br />
374
                    Assign/unassign any member as an author of a particular BlogPost'
375
                )
376
            );
377
        if (!$this->canEditEditors()) {
378
            $editorField = $editorField->performDisabledTransformation();
379
        }
380
        $writerField = ListboxField::create('Writers', 'Writers', $members)
381
            ->setRightTitle($toggleButton)
382
            ->setDescription(
383
                _t(
384
                    __CLASS__ . '.UsersWritersFieldDescription',
385
                    'A writer has full control over creating, editing and publishing BlogPosts they have authored
386
                      or have been assigned to. Writers are unable to edit BlogPosts to which they are not assigned.
387
                    <br /><br />
388
                    Writers have these permissions:<br />
389
                    <br />
390
                    Update or publish any BlogPost they have authored or have been assigned to<br />
391
                    Assign/unassign any member as an author of a particular BlogPost they have authored or have been 
392
                    assigned to'
393
                )
394
            );
395
396
        if (!$this->canEditWriters()) {
397
            $writerField = $writerField->performDisabledTransformation();
398
        }
399
400
        $contributorField = ListboxField::create('Contributors', 'Contributors', $members)
401
            // ->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...
402
            ->setRightTitle($toggleButton)
403
            ->setDescription(
404
                _t(
405
                    __CLASS__ . '.UsersContributorsFieldDescription',
406
                    'Contributors have the ability to create or edit BlogPosts, but are unable to publish without 
407
                        authorisation of an editor. They are also unable to assign other contributing authors to any of
408
                         their BlogPosts.<br />
409
                        <br />
410
                        Contributors have these permissions:<br />
411
                        <br />
412
                        Update any BlogPost they have authored or have been assigned to'
413
                )
414
            );
415
416
        if (!$this->canEditContributors()) {
417
            $contributorField = $contributorField->performDisabledTransformation();
418
        }
419
420
        $fields->addFieldsToTab(
421
            'Root.Users',
422
            [
423
                $editorField,
424
                $writerField,
425
                $contributorField
426
            ]
427
        );
428
429
        return $fields;
430
    }
431
432
    /**
433
     * Gets the list of user candidates to be assigned to assist with this blog.
434
     *
435
     * @return SS_List
436
     */
437
    protected function getCandidateUsers()
438
    {
439
        if ($this->config()->get('grant_user_access')) {
440
            $list = Member::get();
441
            $this->extend('updateCandidateUsers', $list);
442
            return $list;
443
        } else {
444
            return Permission::get_members_by_permission(
445
                $this->config()->get('grant_user_permission')
446
            );
447
        }
448
    }
449
450
    /**
451
     * Determine if this user can edit the editors list.
452
     *
453
     * @param int|Member $member
454
     *
455
     * @return bool
456
     */
457
    public function canEditEditors($member = null)
458
    {
459
        $member = $this->getMember($member);
460
461
        $extended = $this->extendedCan('canEditEditors', $member);
462
463
        if ($extended !== null) {
464
            return $extended;
465
        }
466
467
        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 467 which is incompatible with the return type documented by SilverStripe\Blog\Model\Blog::canEditEditors of type boolean.
Loading history...
468
    }
469
470
    /**
471
     * Determine if this user can edit writers list.
472
     *
473
     * @param int|Member $member
474
     *
475
     * @return boolean
476
     */
477 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...
478
    {
479
        $member = $this->getMember($member);
480
481
        $extended = $this->extendedCan('canEditWriters', $member);
482
483
        if ($extended !== null) {
484
            return $extended;
485
        }
486
487
        if ($this->isEditor($member)) {
488
            return true;
489
        }
490
491
        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 491 which is incompatible with the return type documented by SilverStripe\Blog\Model\Blog::canEditWriters of type boolean.
Loading history...
492
    }
493
494
    /**
495
     * Determines if this user can edit the contributors list.
496
     *
497
     * @param int|Member $member
498
     *
499
     * @return boolean
500
     */
501 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...
502
    {
503
        $member = $this->getMember($member);
504
505
        $extended = $this->extendedCan('canEditContributors', $member);
506
507
        if ($extended !== null) {
508
            return $extended;
509
        }
510
511
        if ($this->isEditor($member)) {
512
            return true;
513
        }
514
515
        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 515 which is incompatible with the return type documented by SilverStripe\Blog\Model\Blog::canEditContributors of type boolean.
Loading history...
516
    }
517
518
    /**
519
     * Returns BlogPosts for a given date period.
520
     *
521
     * @param int $year
522
     * @param null|int $month
523
     * @param null|int $day
524
     *
525
     * @return DataList
526
     */
527
    public function getArchivedBlogPosts($year, $month = null, $day = null)
528
    {
529
        $query = $this->getBlogPosts()->dataQuery();
530
531
        $stage = $query->getQueryParam('Versioned.stage');
532
533
        if ($stage) {
534
            $stage = '_' . $stage;
535
        }
536
537
        $query->innerJoin(
538
            DataObject::getSchema()->tableName(BlogPost::class),
539
            sprintf('"SiteTree%s"."ID" = "BlogPost%s"."ID"', $stage, $stage)
540
        );
541
542
        $conn = DB::get_conn();
543
544
        // Filter by year
545
        $yearCond = $conn->formattedDatetimeClause('"BlogPost"."PublishDate"', '%Y');
546
        $query->where(sprintf('%s = \'%04d\'', $yearCond, Convert::raw2sql($year)));
547
548
        // Filter by month (if given)
549
        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...
550
            $monthCond = $conn->formattedDatetimeClause('"BlogPost"."PublishDate"', '%m');
551
            $query->where(sprintf('%s = \'%02d\'', $monthCond, Convert::raw2sql($month)));
552
553
            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...
554
                $dayCond = $conn->formattedDatetimeClause('"BlogPost"."PublishDate"', '%d');
555
                $query->where(sprintf('%s = \'%02d\'', $dayCond, Convert::raw2sql($day)));
556
            }
557
        }
558
559
560
        return $this->getBlogPosts()->setDataQuery($query);
561
    }
562
563
    /**
564
     * Return blog posts.
565
     *
566
     * @return DataList of BlogPost objects
567
     */
568
    public function getBlogPosts()
569
    {
570
        $blogPosts = BlogPost::get()->filter('ParentID', $this->ID);
571
572
        $this->extend('updateGetBlogPosts', $blogPosts);
573
574
        return $blogPosts;
575
    }
576
577
    /**
578
     * Get a link to a Member profile.
579
     *
580
     * @param string $urlSegment
581
     *
582
     * @return string
583
     */
584
    public function ProfileLink($urlSegment)
585
    {
586
        $baseLink = $this->Link();
587
        if ($baseLink === '/') {
588
            // Handle homepage blogs
589
            $baseLink = RootURLController::get_homepage_link();
590
        }
591
592
        return Controller::join_links($baseLink, 'profile', $urlSegment);
593
    }
594
595
    /**
596
     * This sets the title for our gridfield.
597
     *
598
     * @return string
599
     */
600
    public function getLumberjackTitle()
601
    {
602
        return _t(__CLASS__ . '.LumberjackTitle', 'Blog Posts');
603
    }
604
605
    /**
606
     * This overwrites lumberjacks default gridfield config.
607
     *
608
     * @return GridFieldConfig
609
     */
610
    public function getLumberjackGridFieldConfig()
611
    {
612
        return GridFieldConfig_BlogPost::create();
613
    }
614
615
    /**
616
     * {@inheritdoc}
617
     */
618
    public function providePermissions()
619
    {
620
        return [
621
            Blog::MANAGE_USERS => [
622
                'name' => _t(
623
                    __CLASS__ . '.PERMISSION_MANAGE_USERS_DESCRIPTION',
624
                    'Manage users for individual blogs'
625
                ),
626
                'help' => _t(
627
                    __CLASS__ . '.PERMISSION_MANAGE_USERS_HELP',
628
                    'Allow assignment of Editors, Writers, or Contributors to blogs'
629
                ),
630
                'category' => _t(__CLASS__ . '.PERMISSIONS_CATEGORY', 'Blog permissions'),
631
                'sort' => 100
632
            ]
633
        ];
634
    }
635
636
    /**
637
     * {@inheritdoc}
638
     */
639
    protected function onBeforeWrite()
640
    {
641
        parent::onBeforeWrite();
642
        $this->assignGroup();
643
    }
644
645
    /**
646
     * Assign users as necessary to the blog group.
647
     */
648
    protected function assignGroup()
649
    {
650
        if (!$this->config()->get('grant_user_access')) {
651
            return;
652
        }
653
654
        $group = $this->getUserGroup();
655
656
        // Must check if the method exists or else an error occurs when changing page type
657
        if ($this->hasMethod('Editors')) {
658
            foreach ([$this->Editors(), $this->Writers(), $this->Contributors()] as $levels) {
659
                foreach ($levels as $user) {
660
                    if (!$user->inGroup($group)) {
661
                        $user->Groups()->add($group);
662
                    }
663
                }
664
            }
665
        }
666
    }
667
668
    /**
669
     * Gets or creates the group used to assign CMS access.
670
     *
671
     * @return Group
672
     */
673
    protected function getUserGroup()
674
    {
675
        $code = $this->config()->get('grant_user_group');
676
677
        $group = Group::get()->filter('Code', $code)->first();
678
679
        if ($group) {
680
            return $group;
681
        }
682
683
        $group = Group::create();
684
        $group->Title = 'Blog users';
685
        $group->Code = $code;
686
687
        $group->write();
688
689
        $permission = Permission::create();
690
        $permission->Code = $this->config()->get('grant_user_permission');
691
692
        $group->Permissions()->add($permission);
693
694
        return $group;
695
    }
696
}
697