Version: current

      1 <?php
      2 /**
      3  * Guestbook
      4  * @author Marc Aschmann <marc (at) aschmann.org>
      5  * @author dvp
      6  * @author menedem
      7  * @package guestbook
      8  */
      9
     10 /**
     11  * Guestbook model
     12  * @author Marc Aschmann <marc (at) aschmann.org>
     13  */
     14 class Guestbook extends Page {
     15
     16     static $icon = "/guestbook/img/icons/guestbook";
     17     static $singular_name = 'Guestbook';
     18     static $plural_name = 'Guestbooks';
     19     static $allowed_children = 'none';
     20
     21     static $db = array(
     22         'NeedsActivation'       => 'Boolean',
     23         'ShowPagination'        => 'Boolean',
     24         'PaginationLimit'       => 'Int(3)',
     25         'EnableSpamBlock'       => 'Boolean',
     26         'NeedsAuth'             => 'Boolean',
     27         'ShowEmail'             => 'Boolean',
     28         'ShowHomepage'          => 'Boolean',
     29         'ShowPhone'             => 'Boolean',
     30         'ReceiverMailAddress'   => 'Varchar(255)'
     31     );
     32
     33     static $defaults = array(
     34         'NeedsActivation'       => true,
     35         'ShowPagination'        => true,
     36         'PaginationLimit'       => 20,
     37         'EnableSpamBlock'       => true,
     38         'NeedsAuth'             => false,
     39         'ShowEmail'             => false,
     40         'ShowHomepage'          => false,
     41         'ShowPhone'             => false,
     42     );
     43
     44     /**
     45      * 1:n database relation
     46      * @var array
     47      */
     48     static $has_many = array(
     49         'GuestbookEntries'  => 'GuestbookEntry',
     50     );
     51
     52
     53     /**
     54      * retrieve the entries for current category
     55      * @param void
     56      * @return object Fieldset
     57      */
     58     public function getCMSFields() {
     59         $fields = parent::getCMSFields();
     60         $arrTabFields = array();
     61
     62         $needsActivationField = new CheckboxField(
     63             'NeedsActivation',
     64             _t( 'Guestbook.NEEDSACTIVATION', 'New entries need activation' )
     65         );
     66
     67         $enableSpamBlockField = new CheckboxField(
     68             'EnableSpamBlock',
     69             _t( 'Guestbook.SPAMBLOCK', 'Enables Spam blocking by host and links in GB text' )
     70         );
     71
     72         $showPaginationField = new CheckboxField(
     73             'ShowPagination',
     74             _t( 'Guestbook.SHOWPAGINATION', 'Show Pagination for entries' )
     75         );
     76
     77
     78         $showEmailField = new CheckboxField(
     79             'ShowEmail',
     80             _t( 'Guestbook.SHOWEMAIL', 'Show "email" field in guestbook form' )
     81         );
     82
     83         $showHomepageField = new CheckboxField(
     84             'ShowHomepage',
     85             _t( 'Guestbook.SHOWHOMEPAGE', 'Show "homepage" field in guestbook form' )
     86         );
     87
     88         $showPhoneField = new CheckboxField(
     89             'ShowPhone',
     90             _t( 'Guestbook.SHOWPHONE', 'Show "phone" field in guestbook form' )
     91         );
     92
     93
     94         $needsAuthField = new CheckboxField(
     95             'NeedsAuth',
     96             _t( 'Guestbook.NEEDSAUTH', 'Needs auth to add entry' )
     97         );
     98
     99         $receiverMailAddress = new EmailField(
    100             'ReceiverMailAddress',
    101             _t( 'Guestbook.RECEIVERMAILADDRESS', 'Email address to send enties' )
    102         );
    103
    104         $arrTabFields = array(
    105             $needsActivationField,
    106             $showPaginationField,
    107             $showEmailField,
    108             $showHomepageField,
    109             $showPhoneField,
    110             $enableSpamBlockField,
    111             $receiverMailAddress
    112
    113         );
    114         if (class_exists('RegistrationPage')) { // есть модуль регистрации
    115             $arrTabFields[] = $needsAuthField;
    116         }
    117
    118         // if pagination is enabled, show limits
    119         if( 1 == (int)$this->ShowPagination )
    120         {
    121             $paginationLimitField = new DropdownField(
    122                 'PaginationLimit',
    123                 _t( 'Guestbook.PAGNATIONLIMIT', 'Entries per page' ),
    124                 array(
    125                     null => '-',
    126                     15 => '15',
    127                     20 => '20',
    128                     25 => '25',
    129                     30 => '30',
    130                 )
    131             );
    132
    133             $arrTabFields[] = $paginationLimitField;
    134         }
    135
    136         $fields->insertBefore(new Tab('Config', _t( 'Guestbook.TABNAMECONFIG', 'Config' )), 'Metadata');
    137
    138         $fields->addFieldsToTab( 'Root.Content.Config' , $arrTabFields );
    139
    140         $entriesTable = new DataObjectManager(
    141             $this,              // controller object
    142             'GuestbookEntries', // fieldname
    143             'GuestbookEntry',   // dataObject class
    144             array(              // fields for overview
    145                 'Comment'   => _t( 'GuestbookEntry.db_Comment', 'Comment' ),
    146                 'Name'  => _t( 'GuestbookEntry.db_Name', 'Name' ),
    147                 'Email'     => _t( 'GuestbookEntry.db_Email', 'Email' ),
    148                 'Phone'     => _t( 'GuestbookEntry.db_Phone', 'Phone' ),
    149                 'Url'   => _t( 'GuestbookEntry.db_Url', 'Url' ),
    150                 'StatusTitle'   => _t( 'GuestbookEntry.db_Status', 'Status' ),
    151                 'AuthorTitle'   => _t( 'GuestbookEntry.Author', 'Author' )
    152             ),
    153
    154             'getCMSFields',     // fields for popup
    155             '',
    156             'ID DESC'
    157         );
    158         $fields->insertBefore(new Tab('Entries', _t( 'Guestbook.TABNAME', 'Entries' )), 'Metadata');
    159         $fields->addFieldsToTab( 'Root.Content.Entries', array( $entriesTable ) );
    160
    161         return $fields;
    162     }
    163
    164     function onAfterDelete() {
    165         if ($this->IsDeletedFromStage && !$this->ExistsOnLive) {
    166             if ($this->GuestbookEntries()) {
    167                 foreach ($this->GuestbookEntries() as $entry) {
    168                     $entry->delete();
    169                 }
    170             }
    171         }
    172         parent::onAfterDelete();
    173     }
    174 }
    175
    176 /**
    177  * page controller
    178  * @author Marc Aschmann <marc (at) aschmann.org>
    179  */
    180 class Guestbook_Controller extends Page_Controller implements PermissionProvider {
    181
    182
    183     /**
    184      * provides permissions for the adminstration of the guestbook
    185      * @return array
    186      */
    187     function providePermissions() {
    188         return array(
    189             "GUESTBOOK_DELETEENTRY" => _t('Guestbook.ROLE_DELETEENTRY', "User is allowed to delete comments"),
    190             "GUESTBOOK_CHANGECOMMENTSTATE" => _t('Guestbook.ROLE_CHANGECOMMENTSTATE', "User is allowed to mark items as spam or activate items"),
    191         );
    192     }
    193
    194     /**
    195      * creates a new entry form
    196      * @return object form
    197      */
    198     public function Form() {
    199         $fields = singleton( 'GuestbookEntry' )->getFrontendFields();
    200         if( is_object( $fields ) ) {
    201             if( false == $this->ShowEmail ) {
    202                 $fields->removeByName( 'Email' );
    203             }
    204
    205             if( false == $this->ShowHomepage ) {
    206                 $fields->removeByName( 'Url' );
    207             }
    208
    209             if( false == $this->ShowPhone  ) {
    210                 $fields->removeByName( 'Phone' );
    211             }
    212         }
    213
    214         if ($member = Member::currentUser()) {
    215              if ($member->FirstName || $member->Surname) {
    216                 $name = trim($member->FirstName . ' ' . $member->Surname);
    217                 $nameField = $fields->dataFieldByName('Name');
    218                 $nameField->setValue($name);
    219                 $nameField = $nameField->performReadonlyTransformation();
    220                 $nameField->setName('NameTitle');
    221                 $realNameField = new HiddenField('Name', '', $name);
    222                 $fields->replaceField('Name', $nameField);
    223                 $fields->push($realNameField);
    224             }
    225         }
    226
    227         $actions = new FieldSet(
    228             new FormAction( 'doSubmitEntry', _t( 'Guestbook.ENTER', 'Enter' ) )
    229         );
    230
    231         $validator = new RequiredFields(singleton( 'GuestbookEntry' )->getRequiredFields());
    232         $form = new Form(
    233             $this,
    234             'Form',
    235             $fields,
    236             new FieldSet(new FormAction( 'doSubmitEntry', _t( 'Guestbook.ENTER', 'Enter' ))),
    237             $validator
    238         );
    239
    240         if ($this->EnableSpamBlock && class_exists('SpamProtectorManager')) {
    241             SpamProtectorManager::update_form($form, null, array(), _t('Guestbook.Captcha', 'Captcha')); //
    242         }
    243         return $form;
    244     }
    245
    246
    247     /**
    248      * submit form data
    249      * @param $data form data array
    250      * @param $form form object
    251      * @return void
    252      */
    253     public function doSubmitEntry( $data, $form ) {
    254         $entry = new GuestbookEntry();
    255
    256         $form->saveInto($entry);
    257
    258          // entered values validation
    259         if(!$this->isValidMail($entry->Email)) {
    260             $entry->Email = null;
    261         }
    262
    263         $entry->Url = $this->checkUrl($entry->Url);
    264
    265         // override some values
    266
    267         $entry->GuestbookID = $this->ID;
    268         $entry->AuthorID = Member::currentUserID();
    269         $entry->SenderIP = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : 'unknown';
    270         $entry->write();
    271         $from = Email::getAdminEmail();
    272         $to = ($this->ReceiverMailAddress) ? $this->ReceiverMailAddress : $from;
    273         if( $to) {
    274             $entry->SiteAddress = Director::absoluteBaseURL();
    275             $email= new Email($from, $to, _t('GuestbookEntry.MAILSUBJECT', 'New guestbook entry'));
    276             $email->setTemplate('AdminNotify');
    277             $email->populateTemplate( $entry );
    278             $email->send();
    279
    280         }
    281         $form->sessionMessage(_t( 'Guestbook.ENTRYADDED', 'Entry succesfully created!' ), 'good');
    282         Director::redirectBack();
    283     }
    284
    285     /**
    286      * generate a list of guestbook entries for the page
    287      * @return dataObject
    288      */
    289     public function EntryList() {
    290         // now get the entries and comments
    291         $arrParam = array();
    292         $arrParam['filter'] = (!$this->NeedsActivation || $this->isAdmin()) ? "(Status = 'published' OR Status = 'new')" : "Status = 'published'";
    293         $arrParam['filter'] .= ' AND GuestbookID=' . $this->ID;
    294         $arrParam['sort'] = 'ID DESC';
    295
    296         $arrParam['limit_start'] = '';
    297         $arrParam['limit_end'] = '';
    298         if ($this->ShowPagination) {
    299             $arrParam['limit_start'] = (isset($_GET[ 'start' ]) && intval($_GET['start']) > 0) ? intval($_GET['start']) : 0;
    300             $arrParam['limit_end'] = (intval($this->PaginationLimit) > 0) ? intval($this->PaginationLimit) : Guestbook::$defaults['PaginationLimit']; // !!! TODO get from defaults
    301         }
    302         $rs = GuestbookEntry::get_entry_list($arrParam);
    303         if ($this->hasMethod('setSEOVars')) {
    304             $this->setSEOVars($rs); //Выставляем SEO-переменные (ф-я setSEOVars находится в Webylon Page_Controller)
    305         }
    306         return $rs;
    307     }
    308
    309     /**
    310      * request handler, reacts on url params
    311      * @return void
    312      */
    313     public function doAction() {
    314         $strType = $this->requestParams[ 'do' ];
    315         $retVal = '';
    316
    317         switch ( $strType ) {
    318             case 'deleteEntry':
    319                 if (Permission::check('GUESTBOOK_DELETEENTRY') != false) {
    320                     DataObject::delete_by_id( 'GuestbookEntry', Controller::curr()->urlParams['ID'] );
    321                 }
    322                 break;
    323             case 'activate':
    324                 if (Permission::check('GUESTBOOK_CHANGECOMMENTSTATE') != false) {
    325                     $entry = DataObject::get_by_id( 'GuestbookEntry', Controller::curr()->urlParams['ID'] );
    326                     if( $entry )
    327                     {
    328                         $entry->Status = 'published';
    329                         $entry->write();
    330                     }
    331                 }
    332                 break;
    333             case 'hide':
    334                 if (Permission::check('GUESTBOOK_CHANGECOMMENTSTATE') != false) {
    335                     $entry = DataObject::get_by_id( 'GuestbookEntry', Controller::curr()->urlParams['ID'] );
    336                     if( $entry )
    337                     {
    338                         $entry->Status = 'hidden';
    339                         $entry->write();
    340                     }
    341                 }
    342                 break;
    343         }
    344         if (Director::is_ajax()) {
    345             return $retVal;
    346         }
    347         else {
    348             Controller::curr()->redirectBack();
    349         }
    350     }
    351
    352
    353
    354     /**
    355      * sanity check for eMail adresses
    356      *
    357      * @param string $strEmail
    358      * @return bool
    359      */
    360     private function isValidMail($strEmail) {
    361         $retVal = false;
    362         if (preg_match("/^([a-zA-Z0-9])+([a-zA-Z0-9\._-])*@([a-zA-Z0-9_-])+([a-zA-Z0-9\._-]+)+$/", $strEmail)) {
    363             list( $username, $strDomain ) = split( '@' , $strEmail );
    364             return checkdnsrr($strDomain,'MX');
    365         }
    366
    367         return $retVal;
    368     }
    369
    370
    371
    372     /**
    373      * simple url check
    374      *
    375      * @param string $strUrl
    376      * @return string $strUrl
    377      */
    378     private function checkUrl($strUrl) {
    379         /**
    380          * check given URL for http/https
    381          */
    382         $pattern = "/^((https?|ftp)\:\/\/)?"; // scheme
    383         $pattern .= "([a-z0-9-.]*)\.([a-z]{2,3})"; // host or ip
    384         $pattern .= "(\/([a-z0-9+\$_-]\.?)+)*\/?"; // path
    385         $pattern .= "(#[a-z_.-][a-z0-9+\$_.-]*)?$/"; // domain
    386
    387         $validUrl = preg_match( $pattern, $strUrl, $matches );
    388
    389         if ( isset( $matches[ 1 ] )
    390             && '' == $matches[ 1 ]
    391             && '' != $matches[ 3 ] // path
    392             && '' != $matches[ 4 ] // domain
    393             )
    394         {
    395             $strUrl = 'http://' . $strUrl;
    396         }
    397         elseif( false == isset( $matches[ 1 ] ) ) //skip invalid url
    398         {
    399             $strUrl = null;
    400         }
    401
    402         return $strUrl;
    403     }
    404
    405
    406     /*
    407      * rights management
    408      *
    409      **********************************************************/
    410
    411     /**
    412      * check if current logged in user is an admin
    413      *
    414      * @return boolean
    415      */
    416     public function isAdmin() {
    417         $member = Member::currentUser();
    418         return ($member) ? Permission::checkMember($member, 'ADMIN') : false;
    419     }
    420
    421     /**
    422      * wraps logged in user check
    423      * don't know why this does not work...
    424      *
    425      * @return boolean
    426      */
    427     public function CurrentUser() {
    428         return Member::currentUser();
    429     }
    430
    431 }
    432

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