Version: current

      1 <?php
      2 /**
      3  * Базовые настройки сайта
      4  *
      5  * @package Webylon
      6  * @author inxo, menedem, dvp
      7  */
      8 class WebylonSiteConfig extends SiteConfigDecorator {
      9
     10     /**
     11      * Список скрытых из админки полей
     12      */
     13     static $hidden_fields = array('HeaderPhone', 'Theme', 'Tagline', 'HtmlLeftBlock', 'HtmlRightBlock');
     14
     15     /**
     16      * Флаг блокировки админки при превышении допустимого размера сайта
     17      */
     18     static $block_oversized = true;
     19
     20     /**
     21      * Флаг запрета доступа в админку
     22      */
     23     static $cms_disabled = '';
     24
     25     /**
     26      * Флаг запрета доступа в админку
     27      */
     28     static $use_site_agreement = false;
     29
     30     /**
     31      * Имя поля с чекбоксом Согласен с правилами...
     32      */
     33     static $site_agreement_field = 'AgreeWithSiteRules';
     34
     35     /**
     36      * Max размер загружаемого файла (90 МБ)
     37      */
     38     static $max_file_upload_size = 94371840;
     39
     40     /**
     41      * Max размер загружаемого изображения (8 МБ)
     42      */
     43     static $max_image_upload_size = 8388608;
     44
     45     /**
     46      * URL используемого API карт на сайте. !!!Должен заканчиваться на параметр для api ключа (например, для яндекс - на 'apikey=')
     47      */
     48     static $map_base_url = "https://api-maps.yandex.ru/2.0.48/?load=package.full&lang=ru-RU&apikey=";
     49
     50     function extraStatics() {
     51         return array(
     52             'db' => array(
     53                 'AdminEmail' => 'Varchar',
     54 //              'SenderEmail' => 'Varchar',
     55                 'Copyrights' => 'HTMLText',
     56
     57                 'Address' => 'HTMLText',
     58                 'WorkingHours' => 'HTMLText',
     59                 'Phone' => 'HTMLText',
     60                 'Fax' => 'HTMLText',
     61                 'ContactEmail' => 'Varchar',
     62
     63                 'LinkVK' => 'Varchar(255)',
     64                 'LinkFB' => 'Varchar(255)',
     65                 'LinkGP' => 'Varchar(255)',
     66                 'LinkTW' => 'Varchar(255)',
     67                 'LinkLJ' => 'Varchar(255)',
     68                 'LinkIG' => 'Varchar(255)',
     69                 'HeaderPhone' => 'HtmlText',
     70
     71                 'HtmlLeftBlock' => 'HTMLText',
     72                 'HtmlRightBlock' => 'HTMLText',
     73                 'HtmlFooterBlock' => 'HTMLText',
     74                 'HtmlShare' => 'HTMLText',
     75
     76                 'MetaKeywords' => 'Text',
     77                 'MetaDescription' => 'Text',
     78                 'MetaTags' => 'Text',
     79
     80                 'SiteAgreementText' => 'Text',
     81
     82                 // для API Карт
     83                 'MapApiKey' => 'Varchar(250)',
     84             ),
     85
     86             'defaults' => array(
     87                 'MetaKeywords' => '',
     88                 'MetaDescription' => '',
     89                 'MetaTags' => ''
     90             ),
     91             'has_one' => array(
     92                 'SiteAgreementPage' => 'SiteTree',
     93                 'FavIcon' => 'Image',
     94             )
     95         );
     96     }
     97
     98     static function set_map_base_url($url) {
     99         self::$map_base_url = $url;
    100     }
    101
    102     static $field_types = array();
    103
    104     static function set_field_type($name, $type) {
    105         self::$field_types[$name] = $type;
    106     }
    107
    108     static function get_field_type($name) {
    109         if (array_key_exists($name, self::$field_types))
    110             return self::$field_types[$name];
    111
    112         if (preg_match('/(address|email|fax|phone|link)/i', $name, $m))
    113             return strtolower($m[1]);
    114
    115         return 'default';
    116     }
    117
    118     public function updateCMSFields(FieldSet &$fields) {
    119         $tab = self::get_config_tab($fields);
    120
    121         if (method_exists('LeftAndMainQuota', 'sizeStatus')) {
    122             $sizeInfo = LeftAndMainQuota::sizeStatus();
    123
    124             if ($sizeInfo->Blocked) {
    125                 $fields->insertBefore(new LiteralField('oversize', '<div id="oversizeMessage">' . sprintf(_t('SiteConfig.SITEBLOCKEDOVERSIZED', 'Site oversized used %d Mb from %d'), $sizeInfo->Used, $sizeInfo->Quota) . '</div>'), 'Title');
    126             } elseif ($sizeInfo->State == 'over') {
    127                 $fields->insertBefore(new LiteralField('oversize', '<div id="oversizeMessage">' . sprintf(_t('SiteConfig.SITEOVERSIZED', 'Site oversized used %d Mb from %d'), $sizeInfo->Used, $sizeInfo->Quota) . '</div>'), 'Title');
    128             }
    129         }
    130
    131         $tab->push(new EmailField('AdminEmail', $this->owner->fieldLabel('AdminEmail').sprintf(' (%s)', Email::getAdminEmail())));
    132 //      $tab->push(new EmailField('SenderEmail', $this->owner->fieldLabel('SenderEmail').sprintf(' (%s)', Email::getAdminEmail())));
    133         $tab->push(new TextAreaField('Copyrights', $this->owner->fieldLabel('Copyrights')));
    134
    135         if (self::$use_site_agreement) {
    136             $tab->push(new TreeDropdownField('SiteAgreementPageID', $this->owner->fieldLabel('SiteAgreementPage'), 'SiteTree'));
    137             $tab->push(new TextAreaField('SiteAgreementText', $this->owner->fieldLabel('SiteAgreementText')));
    138         }
    139         $tab->push(new ImageField('FavIcon', $this->owner->fieldLabel('FavIcon')));
    140
    141         $tab = self::get_config_tab($fields, 'Contacts');
    142         $tab->push(new TextAreaField('Address', $this->owner->fieldLabel('Address')));
    143         $tab->push(new TextAreaField('WorkingHours', $this->owner->fieldLabel('WorkingHours')));
    144         $tab->push(new TextAreaField('Phone', $this->owner->fieldLabel('Phone')));
    145         $tab->push(new TextAreaField('Fax', $this->owner->fieldLabel('Fax')));
    146         $tab->push(new EmailField('ContactEmail', $this->owner->fieldLabel('ContactEmail')));
    147         $tab->push(new TextareaField('HeaderPhone', $this->owner->fieldLabel('HeaderPhone')));
    148
    149         $tab->push(new TextField('LinkVK', $this->owner->fieldLabel('LinkVK')));
    150         $tab->push(new TextField('LinkFB', $this->owner->fieldLabel('LinkFB')));
    151         $tab->push(new TextField('LinkGP', $this->owner->fieldLabel('LinkGP')));
    152         $tab->push(new TextField('LinkTW', $this->owner->fieldLabel('LinkTW')));
    153         $tab->push(new TextField('LinkLJ', $this->owner->fieldLabel('LinkLJ')));
    154         $tab->push(new Textfield('LinkIG', $this->owner->fieldLabel('LinkIG')));
    155
    156         $tab = self::get_config_tab($fields, 'HtmlBlocks');
    157         $tab->push(new TextAreaField('HtmlLeftBlock', $this->owner->fieldLabel('HtmlLeftBlock')));
    158         $tab->push(new TextAreaField('HtmlRightBlock', $this->owner->fieldLabel('HtmlRightBlock')));
    159         $tab->push(new TextAreaField('HtmlFooterBlock', $this->owner->fieldLabel('HtmlFooterBlock')));
    160         $tab->push($htmlShare = new TextAreaField('HtmlShare', $this->owner->fieldLabel('HtmlShare') . ' (<a target="_blank" href="http://api.yandex.ru/share/">http://api.yandex.ru/share/</a>)'));
    161         $tab->push(new TextField('MapApiKey', $this->owner->fieldLabel('MapApiKey') . _t("SiteConfig.GetMapApiKeyLink")));
    162
    163         $tab = self::get_config_tab($fields, 'SEO');
    164         $tab->push(new TextField('MetaKeywords', $this->owner->fieldLabel('MetaKeywords')));
    165         $tab->push(new TextAreaField('MetaDescription', $this->owner->fieldLabel('MetaDescription')));
    166         $tab->push(new TextAreaField('MetaTags', $this->owner->fieldLabel('MetaTags')));
    167
    168         // работа с robots.txt
    169         $robots = null;
    170         $error = null;
    171         if (!is_file(BASE_PATH . '/robots.txt')) {
    172             if (SSViewer::hasTemplate('robots')) {
    173                 $baseRobots = $this->owner->renderWith('robots');
    174                 $robots = @file_put_contents(BASE_PATH . '/robots.txt', $baseRobots);
    175             }
    176             if (!$robots) {
    177                 $error = _t('SiteConfig.CANNOTCREATEFILE');
    178             }
    179         }
    180         if (!$error && !is_writable(BASE_PATH . '/robots.txt')) {
    181             $error = _t('SiteConfig.CANNOTWRITETOFILE');
    182         }
    183         if ($robots = @file_get_contents(BASE_PATH . '/robots.txt')) {
    184             $this->owner->RobotsFile = $robots;
    185         }
    186         if ($error) {
    187             $tab->push(new LiteralField('BadRobotsFile', '<p>' . _t('SiteConfig.RobotsFile') . '</p>'));
    188             $tab->push(new LiteralField('BadRobotsFile', $error . '<p>&nbsp;</p>'));
    189         } else {
    190             $tab->push($f = new TextAreaField('RobotsFile', _t('SiteConfig.RobotsFile'), 20));
    191         }
    192
    193         $this->hideUnselectedFields($fields);
    194
    195         //добавляем скрипт для обновления дерева вставки файлов в визреде, чтобы сразу после загрузки админки (когда открывается SiteConfig) при переходе на MediawebPage все обновлялось
    196         Requirements::customScript("
    197             Behaviour.register({
    198                 '#Form_EditForm' : {
    199                     initialize : function() {
    200                         this.observeMethod('PageLoaded', this.MediawebPageHandler);
    201                         this.MediawebPageHandler();
    202                     },
    203                     MediawebPageHandler : function() {
    204                         (function($) {
    205                             if (($('#Form_EditForm_folder_id').length) && ($('input#Form_EditForm_folder_id').attr('folder_updated') != '1')) {
    206                                 if ($('#TreeDropdownField_Form_EditorToolbarImageForm_FolderID')) {
    207                                     $('#TreeDropdownField_Form_EditorToolbarImageForm_FolderID')[0].setValue($('#Form_EditForm_folder_id').val());
    208                                     $('#TreeDropdownField_Form_EditorToolbarImageForm_FolderID')[0].refresh();
    209                                 }
    210                                 if ($('#TreeDropdownField_Form_EditorToolbarFlashForm_FolderID')) {
    211                                     $('#TreeDropdownField_Form_EditorToolbarFlashForm_FolderID')[0].setValue($('#Form_EditForm_folder_id').val());
    212                                     $('#TreeDropdownField_Form_EditorToolbarFlashForm_FolderID')[0].refresh();
    213                                 }
    214                                 if ($('#TreeDropdownField_Form_EditorToolbarLinkForm_file')) {
    215                                     $('#TreeDropdownField_Form_EditorToolbarLinkForm_file')[0].setValue($('#Form_EditForm_folder_path').val());
    216                                     $('#TreeDropdownField_Form_EditorToolbarLinkForm_file')[0].refresh();
    217                                 }
    218                                 $('input#Form_EditForm_folder_id').attr('folder_updated','1');
    219                             }
    220                         })(jQuery);
    221                     }
    222                 }
    223             });
    224         ");
    225
    226
    227     }
    228
    229     function populateDefaults() {
    230         $this->owner->SiteAgreementText = _t('SiteConfig.default_SiteAgreementText', 'Default Site Agreement Text');
    231     }
    232
    233     function requireDefaultRecords() {
    234         // пробуем создать дефолтный robots.txt
    235         if (!is_file(BASE_PATH . '/robots.txt') && SSViewer::hasTemplate('robots')) {
    236             $baseRobots = $this->owner->renderWith('robots');
    237             $robots = @file_put_contents(BASE_PATH . '/robots.txt', $baseRobots);
    238         }
    239     }
    240
    241     function onBeforeWrite() {
    242         if ($this->owner->isChanged('RobotsFile') && is_file(BASE_PATH . '/robots.txt')) {
    243             @file_put_contents(BASE_PATH . '/robots.txt', $this->owner->RobotsFile);
    244         }
    245     }
    246
    247     /**
    248      * Изменяет режим блокировки админки при превышении объема
    249      *
    250      * @param bool $state - блокировать или нет
    251      */
    252     static function set_block_oversized($state = true) {
    253         self::$block_oversized = $state;
    254     }
    255
    256     /**
    257      * Изменяет режим блокировки админки
    258      *
    259      * @param string $message - сообщение выдаваемое при блокировке
    260      */
    261     static function disable_cms($message) {
    262         self::$cms_disabled = $message;
    263     }
    264
    265     /**
    266      * Запрет создания страниц в корне сайта при превышенной квоте
    267      *
    268      */
    269     function canCreateTopLevel(& $member = null) {
    270         $sizeInfo = LeftAndMainQuota::sizeStatus();
    271         if ($sizeInfo->Blocked) {
    272             return false;
    273         }
    274         return true;
    275     }
    276
    277     /**
    278      * Если в настройках установлен емайл администратора - прописывает его в классе Email
    279      *
    280      */
    281     function setupAdminEmail() {
    282         if ($this->owner->AdminEmail) {
    283             Email::setAdminEmail($this->owner->AdminEmail);
    284         }
    285     }
    286
    287     /**
    288      * Возвращает емайл администратора сайта (из настроек или класса Email)
    289      *
    290      * @return string
    291      */
    292     function AdminEmail() {
    293         return ($this->owner->AdminEmail) ? $this->owner->AdminEmail : Email::getAdminEmail();
    294     }
    295
    296     /**
    297      * Возвращает емайл отправителя для писем с сайта
    298      *
    299      * @return string
    300      */
    301     function SenderEmail() {
    302 //      if ($this->owner->SenderEmail) return $this->owner->SenderEmail;
    303         if ($this->owner->AdminEmail) return $this->owner->AdminEmail;
    304         return (strpos(Email::getAdminEmail(), 'mediaweb.ru') > 0) ? 'noreply@mediaweb.ru' : Email::getAdminEmail();
    305     }
    306
    307     /**
    308      * Возвращает флаг наличия хотя бы одной ссылки на соцсети
    309      * Названия полей ссылок на соц.сети должны начинаться с Link
    310      *
    311      * @return bool
    312      */
    313     function hasLinkFields() {
    314         if ($allConfigFields = DataObject::database_fields('SiteConfig')) {
    315             foreach($allConfigFields as $name=>$type) {
    316                 if ((strpos($name, 'Link') === 0) && ($this->owner->hasValue($name))) {
    317                     return true;
    318                 }
    319             }
    320         }
    321         return false;
    322     }
    323
    324     /**
    325      * Возвращает поле согласия с правилами сайта (в частности с обработкой персональных данных)
    326      *
    327      *
    328      * @return string
    329      */
    330     function SiteAgreementField() {
    331         if (self::$use_site_agreement && $this->owner->SiteAgreementText && $this->owner->SiteAgreementPageID && ($rulesPage = $this->owner->SiteAgreementPage())) {
    332             $title = str_replace('$link', $rulesPage->Link(), $this->owner->SiteAgreementText);
    333             $title = str_replace('$full_link', sprintf(_t("SiteConfig.SiteAgreementFullLink"), $rulesPage->Link(), $rulesPage->MenuTitle), $title);
    334             $field = new CheckboxField(self::$site_agreement_field, $title);
    335             $field->addExtraClass('SiteAgreementField');
    336             return $field;
    337         }
    338     }
    339
    340     /**
    341      * Возвращает перавый номер из поля (полезно для ссылок)
    342      *
    343      * @param string $field - имя поля [Phone]
    344      *
    345      * @return string - первый телефонный номер в поле
    346      */
    347     function FirstPhone($field = 'Phone') {
    348         $phone = $this->owner->$field;
    349         $phone = preg_replace('/^[^\d(]+/s', '', $phone); // обрежем начало если это не телефон (включая "+")
    350         $phone = preg_replace('/(\d)(\s+|\s?[()-]\s?)(\d)/s', '$1$3', $phone); // вырежем разделители  внутри номеров
    351         $phone = preg_replace('/^(\d+).*$/s', '$1', $phone); // вернем первый набор цифр
    352         return $phone;
    353     }
    354
    355     /**
    356      * Превращает все телефоны в поле в кликабельные ссылки
    357      * TODO проверка формата телефона (сейчас просто набор из "+", цифр, "(", ")" и "-")
    358      *
    359      * @param string $field - имя поля [Phone]
    360      *
    361      * @return string
    362      */
    363     function Phone2Links($field = 'Phone') {
    364         $phone = $this->owner->$field;
    365         $phone = preg_replace('/(\+?([\d-]|\s?\(|\)\s?)+)([^\d()-]|$)/', '<a href="tel:$1">$1</a>$3', $phone);
    366         return $phone;
    367     }
    368
    369     /**
    370      * Загружаем скрипт API карт на странице
    371      *
    372      * @param string $url - другой адрес для карт
    373      *
    374      */
    375     function RequireMapApi($url = false) {
    376         Requirements::javascript($this->MapApiUrl($url));
    377     }
    378
    379     function MapApiUrl($url = false) {
    380         if (!$url) {
    381             $url = self::$map_base_url;
    382         }
    383         if ($this->owner->MapApiKey) {
    384             $url .= $this->owner->MapApiKey;
    385         }
    386         return $url;
    387     }
    388
    389     function isNeedMapApiKey() {
    390         return ($this->owner->MapApiKey) ? 1 : 0;
    391     }
    392 }
    393

[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. -