Completed
Push — master ( db942d...dc6dc4 )
by Daniel
13:09
created

code/SiteConfig.php (4 issues)

Upgrade to new PHP Analysis Engine

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\SiteConfig;
4
5
use SilverStripe\Forms\TextField;
6
use SilverStripe\Forms\Tab;
7
use SilverStripe\Forms\OptionsetField;
8
use SilverStripe\Forms\ListboxField;
9
use SilverStripe\Forms\TabSet;
10
use SilverStripe\Forms\HiddenField;
11
use SilverStripe\Forms\FieldList;
12
use SilverStripe\Forms\LiteralField;
13
use SilverStripe\Forms\FormAction;
14
use SilverStripe\ORM\DataObject;
15
use SilverStripe\ORM\DB;
16
use SilverStripe\ORM\ManyManyList;
17
use SilverStripe\Security\Group;
18
use SilverStripe\Security\Permission;
19
use SilverStripe\Security\Member;
20
use SilverStripe\Security\PermissionProvider;
21
use SilverStripe\Security\Security;
22
use SilverStripe\View\TemplateGlobalProvider;
23
24
/**
25
 * SiteConfig
26
 *
27
 * @property string Title Title of the website.
28
 * @property string Tagline Tagline of the website.
29
 * @property string CanViewType Type of restriction used for view permissions.
30
 * @property string CanEditType Type of restriction used for edit permissions.
31
 * @property string CanCreateTopLevelType Type of restriction used for creation of root-level pages.
32
 * @method ManyManyList ViewerGroups() List of groups that can view SiteConfig.
33
 * @method ManyManyList EditorGroups() List of groups that can edit SiteConfig.
34
 * @method ManyManyList CreateTopLevelGroups() List of groups that can create root-level pages.
35
 */
36
class SiteConfig extends DataObject implements PermissionProvider, TemplateGlobalProvider
37
{
38
    private static $db = array(
39
        "Title" => "Varchar(255)",
40
        "Tagline" => "Varchar(255)",
41
        "CanViewType" => "Enum('Anyone, LoggedInUsers, OnlyTheseUsers', 'Anyone')",
42
        "CanEditType" => "Enum('LoggedInUsers, OnlyTheseUsers', 'LoggedInUsers')",
43
        "CanCreateTopLevelType" => "Enum('LoggedInUsers, OnlyTheseUsers', 'LoggedInUsers')",
44
    );
45
46
    private static $many_many = array(
47
        "ViewerGroups" => "SilverStripe\\Security\\Group",
48
        "EditorGroups" => "SilverStripe\\Security\\Group",
49
        "CreateTopLevelGroups" => "SilverStripe\\Security\\Group"
50
    );
51
52
    private static $defaults = array(
53
        "CanViewType" => "Anyone",
54
        "CanEditType" => "LoggedInUsers",
55
        "CanCreateTopLevelType" => "LoggedInUsers",
56
    );
57
58
    private static $table_name = 'SiteConfig';
59
60
    /**
61
     * Default permission to check for 'LoggedInUsers' to create or edit pages
62
     *
63
     * @var array
64
     * @config
65
     */
66
    private static $required_permission = array('CMS_ACCESS_CMSMain', 'CMS_ACCESS_LeftAndMain');
67
68
69
    public function populateDefaults()
70
    {
71
        $this->Title = _t('SilverStripe\\SiteConfig\\SiteConfig.SITENAMEDEFAULT', "Your Site Name");
72
        $this->Tagline = _t('SilverStripe\\SiteConfig\\SiteConfig.TAGLINEDEFAULT', "your tagline here");
73
74
        // Allow these defaults to be overridden
75
        parent::populateDefaults();
76
    }
77
78
    /**
79
     * Get the fields that are sent to the CMS.
80
     *
81
     * In your extensions: updateCMSFields($fields).
82
     *
83
     * @return FieldList
84
     */
85
    public function getCMSFields()
86
    {
87
        $mapFn = function ($groups = []) {
88
            $map = [];
89
            foreach ($groups as $group) {
90
                // Listboxfield values are escaped, use ASCII char instead of &raquo;
91
                $map[$group->ID] = $group->getBreadcrumbs(' > ');
92
            }
93
            asort($map);
94
            return $map;
95
        };
96
        $groupsMap = $mapFn(Group::get());
97
        $viewAllGroupsMap = $mapFn(Permission::get_groups_by_permission(['SITETREE_VIEW_ALL', 'ADMIN']));
98
        $editAllGroupsMap = $mapFn(Permission::get_groups_by_permission(['SITETREE_EDIT_ALL', 'ADMIN']));
99
100
        $fields = new FieldList(
101
            new TabSet(
102
                "Root",
103
                $tabMain = new Tab(
104
                    'Main',
105
                    $titleField = new TextField("Title", _t('SilverStripe\\SiteConfig\\SiteConfig.SITETITLE', "Site title")),
106
                    $taglineField = new TextField("Tagline", _t('SilverStripe\\SiteConfig\\SiteConfig.SITETAGLINE', "Site Tagline/Slogan"))
107
                ),
108
                $tabAccess = new Tab(
109
                    'Access',
110
                    $viewersOptionsField = new OptionsetField("CanViewType", _t('SilverStripe\\SiteConfig\\SiteConfig.VIEWHEADER', "Who can view pages on this site?")),
111
                    $viewerGroupsField = ListboxField::create("ViewerGroups", _t('SilverStripe\\CMS\\Model\\SiteTree.VIEWERGROUPS', "Viewer Groups"))
112
                        ->setSource($groupsMap)
113
                        ->setAttribute(
114
                            'data-placeholder',
115
                            _t('SilverStripe\\CMS\\Model\\SiteTree.GroupPlaceholder', 'Click to select group')
116
                        ),
117
                    $editorsOptionsField = new OptionsetField("CanEditType", _t('SilverStripe\\SiteConfig\\SiteConfig.EDITHEADER', "Who can edit pages on this site?")),
118
                    $editorGroupsField = ListboxField::create("EditorGroups", _t('SilverStripe\\CMS\\Model\\SiteTree.EDITORGROUPS', "Editor Groups"))
119
                        ->setSource($groupsMap)
120
                        ->setAttribute(
121
                            'data-placeholder',
122
                            _t('SilverStripe\\CMS\\Model\\SiteTree.GroupPlaceholder', 'Click to select group')
123
                        ),
124
                    $topLevelCreatorsOptionsField = new OptionsetField("CanCreateTopLevelType", _t('SilverStripe\\SiteConfig\\SiteConfig.TOPLEVELCREATE', "Who can create pages in the root of the site?")),
125
                    $topLevelCreatorsGroupsField = ListboxField::create("CreateTopLevelGroups", _t(__CLASS__.'.TOPLEVELCREATORGROUPS', "Top level creators"))
126
                        ->setSource($groupsMap)
127
                        ->setAttribute(
128
                            'data-placeholder',
129
                            _t('SilverStripe\\CMS\\Model\\SiteTree.GroupPlaceholder', 'Click to select group')
130
                        )
131
                )
132
            ),
133
            new HiddenField('ID')
134
        );
135
136
        $viewersOptionsSource = array();
137
        $viewersOptionsSource["Anyone"] = _t('SilverStripe\\CMS\\Model\\SiteTree.ACCESSANYONE', "Anyone");
138
        $viewersOptionsSource["LoggedInUsers"] = _t('SilverStripe\\CMS\\Model\\SiteTree.ACCESSLOGGEDIN', "Logged-in users");
139
        $viewersOptionsSource["OnlyTheseUsers"] = _t('SilverStripe\\CMS\\Model\\SiteTree.ACCESSONLYTHESE', "Only these people (choose from list)");
140
        $viewersOptionsField->setSource($viewersOptionsSource);
141
142
        if ($viewAllGroupsMap) {
143
            $viewerGroupsField->setDescription(_t(
144
                'SilverStripe\\CMS\\Model\\SiteTree.VIEWER_GROUPS_FIELD_DESC',
145
                'Groups with global view permissions: {groupList}',
146
                ['groupList' => implode(', ', array_values($viewAllGroupsMap))]
147
            ));
148
        }
149
150
        if ($editAllGroupsMap) {
151
            $editorGroupsField->setDescription(_t(
152
                'SilverStripe\\CMS\\Model\\SiteTree.EDITOR_GROUPS_FIELD_DESC',
153
                'Groups with global edit permissions: {groupList}',
154
                ['groupList' => implode(', ', array_values($editAllGroupsMap))]
155
            ));
156
        }
157
158
        $editorsOptionsSource = array();
159
        $editorsOptionsSource["LoggedInUsers"] = _t('SilverStripe\\CMS\\Model\\SiteTree.EDITANYONE', "Anyone who can log-in to the CMS");
160
        $editorsOptionsSource["OnlyTheseUsers"] = _t('SilverStripe\\CMS\\Model\\SiteTree.EDITONLYTHESE', "Only these groups (choose from list)");
161
        $editorsOptionsField->setSource($editorsOptionsSource);
162
163
        $topLevelCreatorsOptionsField->setSource($editorsOptionsSource);
164
165
        if (!Permission::check('EDIT_SITECONFIG')) {
166
            $fields->makeFieldReadonly($viewersOptionsField);
167
            $fields->makeFieldReadonly($viewerGroupsField);
168
            $fields->makeFieldReadonly($editorsOptionsField);
169
            $fields->makeFieldReadonly($editorGroupsField);
170
            $fields->makeFieldReadonly($topLevelCreatorsOptionsField);
171
            $fields->makeFieldReadonly($topLevelCreatorsGroupsField);
172
            $fields->makeFieldReadonly($taglineField);
173
            $fields->makeFieldReadonly($titleField);
174
        }
175
176
        if (file_exists(BASE_PATH . '/install.php')) {
177
            $fields->addFieldToTab(
178
                "Root.Main",
179
                new LiteralField(
180
                    "InstallWarningHeader",
181
                    "<p class=\"message warning\">" . _t(
182
                        "SilverStripe\\CMS\\Model\\SiteTree.REMOVE_INSTALL_WARNING",
183
                        "Warning: You should remove install.php from this SilverStripe install for security reasons."
184
                    ) . "</p>"
185
                ),
186
                "Title"
187
            );
188
        }
189
190
        $tabMain->setTitle(_t('SilverStripe\\SiteConfig\\SiteConfig.TABMAIN', "Main"));
191
        $tabAccess->setTitle(_t('SilverStripe\\SiteConfig\\SiteConfig.TABACCESS', "Access"));
192
        $this->extend('updateCMSFields', $fields);
193
194
        return $fields;
195
    }
196
197
    /**
198
     * Get the actions that are sent to the CMS.
199
     *
200
     * In your extensions: updateEditFormActions($actions)
201
     *
202
     * @return FieldList
203
     */
204
    public function getCMSActions()
205
    {
206
        if (Permission::check('ADMIN') || Permission::check('EDIT_SITECONFIG')) {
207
            $actions = new FieldList(
208
                FormAction::create(
209
                    'save_siteconfig',
210
                    _t('SilverStripe\\CMS\\Controllers\\CMSMain.SAVE', 'Save')
211
                )->addExtraClass('btn-primary font-icon-save')
212
            );
213
        } else {
214
            $actions = new FieldList();
215
        }
216
217
        $this->extend('updateCMSActions', $actions);
218
219
        return $actions;
220
    }
221
222
    /**
223
     * @return string
224
     */
225
    public function CMSEditLink()
226
    {
227
        return SiteConfigLeftAndMain::singleton()->Link();
228
    }
229
230
    /**
231
     * Get the current sites SiteConfig, and creates a new one through
232
     * {@link make_site_config()} if none is found.
233
     *
234
     * @return SiteConfig
235
     */
236
    public static function current_site_config()
237
    {
238
        /** @var SiteConfig $siteConfig */
239
        $siteConfig = DataObject::get_one(SiteConfig::class);
240
        if ($siteConfig) {
241
            return $siteConfig;
242
        }
243
244
        return self::make_site_config();
245
    }
246
247
    /**
248
     * Setup a default SiteConfig record if none exists.
249
     */
250
    public function requireDefaultRecords()
251
    {
252
        parent::requireDefaultRecords();
253
254
        $config = DataObject::get_one(SiteConfig::class);
255
256
        if (!$config) {
257
            self::make_site_config();
258
259
            DB::alteration_message("Added default site config", "created");
260
        }
261
    }
262
263
    /**
264
     * Create SiteConfig with defaults from language file.
265
     *
266
     * @return SiteConfig
267
     */
268
    public static function make_site_config()
269
    {
270
        $config = SiteConfig::create();
271
        $config->write();
272
273
        return $config;
274
    }
275
276
    /**
277
     * Can a user view this SiteConfig instance?
278
     *
279
     * @param Member $member
280
     * @return boolean
281
     */
282 View Code Duplication
    public function canView($member = null)
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...
283
    {
284
        if (!$member) {
285
            $member = Security::getCurrentUser();
286
        }
287
288
        $extended = $this->extendedCan('canView', $member);
289
        if ($extended !== null) {
290
            return $extended;
291
        }
292
293
        // Assuming all that can edit this object can also view it
294
        return $this->canEdit($member);
295
    }
296
297
    /**
298
     * Can a user view pages on this site? This method is only
299
     * called if a page is set to Inherit, but there is nothing
300
     * to inherit from.
301
     *
302
     * @param Member $member
303
     * @return boolean
304
     */
305
    public function canViewPages($member = null)
306
    {
307
        if (!$member) {
308
            $member = Security::getCurrentUser();
309
        }
310
311
        if ($member && Permission::checkMember($member, "ADMIN")) {
312
            return true;
313
        }
314
315
        $extended = $this->extendedCan('canViewPages', $member);
316
        if ($extended !== null) {
317
            return $extended;
318
        }
319
320
        if (!$this->CanViewType || $this->CanViewType == 'Anyone') {
321
            return true;
322
        }
323
324
        // check for any logged-in users
325
        if ($this->CanViewType === 'LoggedInUsers' && $member) {
326
            return true;
327
        }
328
329
        // check for specific groups
330
        if ($this->CanViewType === 'OnlyTheseUsers' && $member && $member->inGroups($this->ViewerGroups())) {
331
            return true;
332
        }
333
334
        return false;
335
    }
336
337
    /**
338
     * Can a user edit pages on this site? This method is only
339
     * called if a page is set to Inherit, but there is nothing
340
     * to inherit from, or on new records without a parent.
341
     *
342
     * @param Member $member
343
     * @return boolean
344
     */
345 View Code Duplication
    public function canEditPages($member = null)
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...
346
    {
347
        if (!$member) {
348
            $member = Security::getCurrentUser();
349
        }
350
351
        if ($member && Permission::checkMember($member, "ADMIN")) {
352
            return true;
353
        }
354
355
        $extended = $this->extendedCan('canEditPages', $member);
356
        if ($extended !== null) {
357
            return $extended;
358
        }
359
360
        // check for any logged-in users with CMS access
361
        if ($this->CanEditType === 'LoggedInUsers'
362
            && Permission::checkMember($member, $this->config()->get('required_permission'))
363
        ) {
364
            return true;
365
        }
366
367
            // check for specific groups
368
        if ($this->CanEditType === 'OnlyTheseUsers' && $member && $member->inGroups($this->EditorGroups())) {
369
            return true;
370
        }
371
372
        return false;
373
    }
374
375 View Code Duplication
    public function canEdit($member = null)
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...
376
    {
377
        if (!$member) {
378
            $member = Security::getCurrentUser();
379
        }
380
381
        $extended = $this->extendedCan('canEdit', $member);
382
        if ($extended !== null) {
383
            return $extended;
384
        }
385
386
        return Permission::checkMember($member, "EDIT_SITECONFIG");
387
    }
388
389
    /**
390
     * @return array
391
     */
392
    public function providePermissions()
393
    {
394
        return array(
395
            'EDIT_SITECONFIG' => array(
396
                'name' => _t('SilverStripe\\SiteConfig\\SiteConfig.EDIT_PERMISSION', 'Manage site configuration'),
397
                'category' => _t('SilverStripe\\Security\\Permission.PERMISSIONS_CATEGORY', 'Roles and access permissions'),
398
                'help' => _t('SilverStripe\\SiteConfig\\SiteConfig.EDIT_PERMISSION_HELP', 'Ability to edit global access settings/top-level page permissions.'),
399
                'sort' => 400
400
            )
401
        );
402
    }
403
404
    /**
405
     * Can a user create pages in the root of this site?
406
     *
407
     * @param Member $member
408
     * @return boolean
409
     */
410 View Code Duplication
    public function canCreateTopLevel($member = null)
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...
411
    {
412
        if (!$member) {
413
            $member = Security::getCurrentUser();
414
        }
415
416
        if ($member && Permission::checkMember($member, "ADMIN")) {
417
            return true;
418
        }
419
420
        $extended = $this->extendedCan('canCreateTopLevel', $member);
421
        if ($extended !== null) {
422
            return $extended;
423
        }
424
425
        // check for any logged-in users with CMS permission
426
        if ($this->CanCreateTopLevelType === 'LoggedInUsers'
427
            && Permission::checkMember($member, $this->config()->get('required_permission'))
428
        ) {
429
            return true;
430
        }
431
432
        // check for specific groups
433
        if ($this->CanCreateTopLevelType === 'OnlyTheseUsers'
434
            && $member
435
            && $member->inGroups($this->CreateTopLevelGroups())
436
        ) {
437
            return true;
438
        }
439
440
        return false;
441
    }
442
443
    /**
444
     * Add $SiteConfig to all SSViewers
445
     */
446
    public static function get_template_global_variables()
447
    {
448
        return array(
449
            'SiteConfig' => 'current_site_config',
450
        );
451
    }
452
}
453