Version: current

      1 <?php
      2 /**
      3  * Sitewide configuration.
      4  *
      5  * h2. Translation
      6  *
      7  * To enable translation of configurations alongside the {@link Translatable} extension.
      8  * This also allows assigning language-specific toplevel permissions for viewing and editing
      9  * pages, in addition to the normal `TRANSLATE_*`/`TRANSLATE_ALL` permissions.
     10  *
     11  *  Object::add_extension('SiteConig', 'Translatable');
     12  *
     13  * @author Tom Rix
     14  * @package cms
     15  */
     16 class SiteConfig extends DataObject implements PermissionProvider {
     17     static $db = array(
     18         "Title" => "Varchar(255)",
     19         "Tagline" => "Varchar(255)",
     20         "Theme" => "Varchar(255)",
     21         "CanViewType" => "Enum('Anyone, LoggedInUsers, OnlyTheseUsers', 'Anyone')",
     22         "CanEditType" => "Enum('LoggedInUsers, OnlyTheseUsers', 'LoggedInUsers')",
     23         "CanCreateTopLevelType" => "Enum('LoggedInUsers, OnlyTheseUsers', 'LoggedInUsers')",
     24     );
     25
     26     static $many_many = array(
     27         "ViewerGroups" => "Group",
     28         "EditorGroups" => "Group",
     29         "CreateTopLevelGroups" => "Group"
     30     );
     31
     32     protected static $disabled_themes = array();
     33
     34     public static function disable_theme($theme) {
     35         self::$disabled_themes[$theme] = $theme;
     36     }
     37
     38     /**
     39      * Get the fields that are sent to the CMS. In
     40      * your decorators: updateCMSFields(&$fields)
     41      *
     42      * @return Fieldset
     43      */
     44     function getCMSFields() {
     45         Requirements::javascript(CMS_DIR . "/javascript/SitetreeAccess.js");
     46
     47         $fields = new FieldSet(
     48             new TabSet("Root",
     49                 $tabMain = new Tab('Main',
     50                     $titleField = new TextField("Title", _t('SiteConfig.SITETITLE', "Site title")),
     51                     $taglineField = new TextField("Tagline", _t('SiteConfig.SITETAGLINE', "Site Tagline/Slogan"))
     52                 ),
     53                 $tabAccess = new Tab('Access',
     54                     new HeaderField('WhoCanViewHeader', _t('SiteConfig.VIEWHEADER', "Who can view pages on this site?"), 2),
     55                     $viewersOptionsField = new OptionsetField("CanViewType"),
     56                     $viewerGroupsField = new TreeMultiselectField("ViewerGroups", _t('SiteTree.VIEWERGROUPS', "Viewer Groups")),
     57                     new HeaderField('WhoCanEditHeader', _t('SiteConfig.EDITHEADER', "Who can edit pages on this site?"), 2),
     58                     $editorsOptionsField = new OptionsetField("CanEditType"),
     59                     $editorGroupsField = new TreeMultiselectField("EditorGroups", _t('SiteTree.EDITORGROUPS', "Editor Groups")),
     60                     new HeaderField('WhoCanCreateTopLevelHeader', _t('SiteConfig.TOPLEVELCREATE', "Who can create pages in the root of the site?"), 2),
     61                     $topLevelCreatorsOptionsField = new OptionsetField("CanCreateTopLevelType"),
     62                     $topLevelCreatorsGroupsField = new TreeMultiselectField("CreateTopLevelGroups", _t('SiteTree.TOPLEVELCREATORGROUPS', "Top level creators"))
     63                 )
     64             )
     65         );
     66         $themes = $this->getAvailableThemes();
     67         if (count($themes) > 0)
     68             $fields->addFieldToTab('Root.Main', new DropdownField("Theme", _t('SiteConfig.THEME', 'Theme'), $themes, '', null, _t('SiteConfig.DEFAULTTHEME', '(Use default theme)')));
     69
     70         $viewersOptionsSource = array();
     71         $viewersOptionsSource["Anyone"] = _t('SiteTree.ACCESSANYONE', "Anyone");
     72         $viewersOptionsSource["LoggedInUsers"] = _t('SiteTree.ACCESSLOGGEDIN', "Logged-in users");
     73         $viewersOptionsSource["OnlyTheseUsers"] = _t('SiteTree.ACCESSONLYTHESE', "Only these people (choose from list)");
     74         $viewersOptionsField->setSource($viewersOptionsSource);
     75
     76         $editorsOptionsSource = array();
     77         $editorsOptionsSource["LoggedInUsers"] = _t('SiteTree.EDITANYONE', "Anyone who can log-in to the CMS");
     78         $editorsOptionsSource["OnlyTheseUsers"] = _t('SiteTree.EDITONLYTHESE', "Only these people (choose from list)");
     79         $editorsOptionsField->setSource($editorsOptionsSource);
     80
     81         $topLevelCreatorsOptionsField->setSource($editorsOptionsSource);
     82
     83         // Translatable doesn't handle updateCMSFields on DataObjects,
     84         // so add it here to save the current Locale,
     85         // because onBeforeWrite does not work.
     86         if(Object::has_extension('SiteConfig',"Translatable")){
     87             $fields->push(new HiddenField("Locale"));
     88         }
     89
     90         $tabMain->setTitle(_t('SiteConfig.TABMAIN', "Main"));
     91         $tabAccess->setTitle(_t('SiteConfig.TABACCESS', "Access"));
     92         $this->extend('updateCMSFields', $fields);
     93
     94         if (!Permission::check('EDIT_SITECONFIG')) {
     95             return $fields->makeReadonly();
     96         }
     97         return $fields;
     98     }
     99
    100     /**
    101      * Get all available themes that haven't been marked as disabled.
    102      * @param string $baseDir Optional alternative theme base directory for testing
    103      * @return array of theme directory names
    104      */
    105     public function getAvailableThemes($baseDir = null) {
    106         $themes = ManifestBuilder::get_themes($baseDir);
    107         foreach(self::$disabled_themes as $theme) {
    108             if(isset($themes[$theme])) unset($themes[$theme]);
    109         }
    110         return $themes;
    111     }
    112
    113     /**
    114      * Get the actions that are sent to the CMS. In
    115      * your decorators: updateEditFormActions(&$actions)
    116      *
    117      * @return Fieldset
    118      */
    119     function getCMSActions() {
    120         if (Permission::check('ADMIN') || Permission::check('EDIT_SITECONFIG')) {
    121             $actions = new FieldSet(
    122                 new FormAction('save_siteconfig', _t('CMSMain.SAVE', 'Save'))
    123             );
    124         } else {
    125             $actions = new FieldSet();
    126         }
    127
    128         $this->extend('updateCMSActions', $actions);
    129
    130         return $actions;
    131     }
    132
    133     /**
    134      * Get the current sites SiteConfig, and creates a new one
    135      * through {@link make_site_config()} if none is found.
    136      *
    137      * @param string $locale
    138      * @return SiteConfig
    139      */
    140     static function current_site_config($locale = null) {
    141         if(Object::has_extension('SiteConfig',"Translatable")){
    142             $locale = isset($locale) ? $locale : Translatable::get_current_locale();
    143             $siteConfig = Translatable::get_one_by_locale('SiteConfig', $locale);
    144         } else {
    145             $siteConfig = DataObject::get_one('SiteConfig');
    146         }
    147
    148         if (!$siteConfig) $siteConfig = self::make_site_config($locale);
    149
    150         return $siteConfig;
    151     }
    152
    153     /**
    154      * Setup a default SiteConfig record if none exists
    155      */
    156     function requireDefaultRecords() {
    157         parent::requireDefaultRecords();
    158         $siteConfig = DataObject::get_one('SiteConfig');
    159         if(!$siteConfig) {
    160             self::make_site_config();
    161             DB::alteration_message("Added default site config","created");
    162         }
    163     }
    164
    165     /**
    166      * Create SiteConfig with defaults from language file.
    167      * if Translatable is enabled on SiteConfig, see if one already exist
    168      * and use those values for the translated defaults.
    169      *
    170      * @param string $locale
    171      * @return SiteConfig
    172      */
    173     static function make_site_config($locale = null) {
    174         if(Object::has_extension('SiteConfig',"Translatable")){
    175             if(!$locale) $locale = Translatable::get_current_locale();
    176         }
    177
    178         $siteConfig = new SiteConfig();
    179         $siteConfig->Title = _t('SiteConfig.SITENAMEDEFAULT',"Your Site Name");
    180         $siteConfig->Tagline = _t('SiteConfig.TAGLINEDEFAULT',"your tagline here");
    181
    182         if($siteConfig->hasExtension('Translatable')){
    183             $defaultConfig = DataObject::get_one('SiteConfig');
    184             if($defaultConfig){
    185                 $siteConfig->Title = $defaultConfig->Title;
    186                 $siteConfig->Tagline = $defaultConfig->Tagline;
    187             }
    188
    189             // TODO Copy view/edit group settings
    190
    191             // set the correct Locale
    192             $siteConfig->Locale = $locale;
    193         }
    194
    195         $siteConfig->write();
    196
    197         return $siteConfig;
    198     }
    199
    200     /**
    201      * Can a user view pages on this site? This method is only
    202      * called if a page is set to Inherit, but there is nothing
    203      * to inherit from.
    204      *
    205      * @param mixed $member
    206      * @return boolean
    207      */
    208     public function canView($member = null) {
    209         if(!$member) $member = Member::currentUserID();
    210         if($member && is_numeric($member)) $member = DataObject::get_by_id('Member', $member);
    211
    212         if (!$this->CanViewType || $this->CanViewType == 'Anyone') return true;
    213
    214         // check for any logged-in users
    215         if($this->CanViewType == 'LoggedInUsers' && $member) return true;
    216
    217         // check for specific groups
    218         if($this->CanViewType == 'OnlyTheseUsers' && $member && $member->inGroups($this->ViewerGroups())) return true;
    219
    220         return false;
    221     }
    222
    223     /**
    224      * Can a user edit pages on this site? This method is only
    225      * called if a page is set to Inherit, but there is nothing
    226      * to inherit from.
    227      *
    228      * @param mixed $member
    229      * @return boolean
    230      */
    231     public function canEdit($member = null) {
    232         if(!$member) $member = Member::currentUserID();
    233         if($member && is_numeric($member)) $member = DataObject::get_by_id('Member', $member);
    234
    235         // check for any logged-in users
    236         if(!$this->CanEditType || $this->CanEditType == 'LoggedInUsers' && $member) return true;
    237
    238         // check for specific groups
    239         if($this->CanEditType == 'OnlyTheseUsers' && $member && $member->inGroups($this->EditorGroups())) return true;
    240
    241         return false;
    242     }
    243
    244     function providePermissions() {
    245         return array(
    246             'EDIT_SITECONFIG' => array(
    247                 'name' => _t('SiteConfig.EDIT_PERMISSION', 'Manage site configuration'),
    248                 'category' => _t('Permissions.PERMISSIONS_CATEGORY', 'Roles and access permissions'),
    249                 'help' => _t('SiteConfig.EDIT_PERMISSION_HELP', 'Ability to edit global access settings/top-level page permissions.'),
    250                 'sort' => 400
    251             )
    252         );
    253     }
    254
    255     /**
    256      * Can a user create pages in the root of this site?
    257      *
    258      * @param mixed $member
    259      * @return boolean
    260      */
    261     public function canCreateTopLevel($member = null) {
    262         if(!$member || !(is_a($member, 'Member')) || is_numeric($member)) {
    263             $member = Member::currentUserID();
    264         }
    265
    266         $results = $this->extend('canCreateTopLevel', $member);
    267         if($results && is_array($results)) if(!min($results)) return false;
    268
    269         if (Permission::check('ADMIN')) return true;
    270
    271         // check for any logged-in users
    272         if($this->CanCreateTopLevelType == 'LoggedInUsers' && $member) return true;
    273
    274         // check for specific groups
    275         if($member && is_numeric($member)) $member = DataObject::get_by_id('Member', $member);
    276         if($this->CanCreateTopLevelType == 'OnlyTheseUsers' && $member && $member->inGroups($this->CreateTopLevelGroups())) return true;
    277
    278
    279         return false;
    280     }
    281 }
    282

[Raise a SilverStripe Framework issue/bug](https://github.com/silverstripe/silverstripe-framework/issues/new)
- [Raise a SilverStripe CMS issue/bug](https://github.com/silverstripe/silverstripe-cms/issues/new)
- Please use the Silverstripe Forums to ask development related questions. -