Webylon 3.2 API Docs
  • Package
  • Class
  • Tree
  • Deprecated
  • Download
Version: current
  • 3.2
  • 3.1

Packages

  • 1c
    • exchange
      • catalog
  • auth
  • Booking
  • building
    • company
  • cart
    • shipping
    • steppedcheckout
  • Catalog
    • monument
  • cms
    • assets
    • batchaction
    • batchactions
    • bulkloading
    • comments
    • content
    • core
    • export
    • newsletter
    • publishers
    • reports
    • security
    • tasks
  • Dashboard
  • DataObjectManager
  • event
  • faq
  • forms
    • actions
    • core
    • fields-basic
    • fields-dataless
    • fields-datetime
    • fields-files
    • fields-formatted
    • fields-formattedinput
    • fields-relational
    • fields-structural
    • transformations
    • validators
  • googlesitemaps
  • guestbook
  • installer
  • newsletter
  • None
  • photo
    • gallery
  • PHP
  • polls
  • recaptcha
  • sapphire
    • api
    • bulkloading
    • control
    • core
    • cron
    • dev
    • email
    • fields-formattedinput
    • filesystem
    • formatters
    • forms
    • i18n
    • integration
    • misc
    • model
    • parsers
    • search
    • security
    • tasks
    • testing
    • tools
    • validation
    • view
    • widgets
  • seo
    • open
      • graph
  • sfDateTimePlugin
  • spamprotection
  • stealth
    • captha
  • subsites
  • userform
    • pagetypes
  • userforms
  • webylon
  • widgets

Classes

  • SimpleOrderForm_Controller
  • UserDefinedForm_Controller
   1 <?php
   2 
   3 /**
   4  * User Defined Form Page type that lets users build a form in the CMS 
   5  * using the FieldEditor Field. 
   6  * 
   7  * @todo Allow UserDefinedForm instances on Page subclasses (eg via decorator)
   8  *
   9  * @package userforms
  10  */
  11 
  12 class UserDefinedForm extends Page {
  13     
  14     /**
  15      * @var String Required Identifier
  16      */
  17     static $required_identifier = null;
  18 
  19     /**
  20      * @var Array Fields on the user defined form page. 
  21      */
  22     static $db = array(
  23         "SubmitButtonText" => "Varchar",
  24         "OnCompleteMessage" => "HTMLText",
  25         'DisableSaveSubmissions' => 'Boolean'
  26     );
  27     
  28     /**
  29      * @var Array Default values of variables when this page is created
  30      */ 
  31     static $defaults = array(
  32         'Content' => '$UserDefinedForm',
  33         'DisableSaveSubmissions' => 0,
  34     );
  35 
  36     static $extensions = array(
  37         "Versioned('Stage', 'Live')"
  38     );
  39 
  40     /**
  41      * @var Array
  42      */
  43     static $has_many = array( 
  44         "Fields" => "EditableFormField",
  45         "Submissions" => "SubmittedForm",
  46         "EmailRecipients" => "UserDefinedForm_EmailRecipient"
  47     );
  48     
  49 
  50     /**
  51     * Change extended mode
  52     *
  53     */
  54     static function set_extended_mode($mode = false) { return true; }
  55     
  56     /**
  57      * @var Флаг использования js-валидации
  58      */
  59     static $use_js_validation = true;
  60     
  61     public function populateDefaults() {
  62         parent::populateDefaults();
  63         $this->OnCompleteMessage = _t('UserDefinedForm.OnCompleteMessage');        
  64     }
  65     
  66     /**
  67      * Setup the CMS Fields for the User Defined Form
  68      * 
  69      * @return FieldSet
  70      */
  71     public function getCMSFields() {
  72         $fields = parent::getCMSFields();
  73         Requirements::add_i18n_javascript('userforms/javascript/lang');
  74 
  75         // define tabs
  76         $fields->findOrMakeTab('Root.Content.Form', _t('UserDefinedForm.FORM', 'Form'));
  77         $fields->findOrMakeTab('Root.Content.Options', _t('UserDefinedForm.OPTIONS', 'Options'));
  78         $fields->findOrMakeTab('Root.Content.EmailRecipients', _t('UserDefinedForm.EMAILRECIPIENTS', 'Email Recipients'));
  79         $fields->findOrMakeTab('Root.Content.OnComplete', _t('UserDefinedForm.ONCOMPLETE', 'On Complete'));
  80         $fields->findOrMakeTab('Root.Content.Submissions', _t('UserDefinedForm.SUBMISSIONS', 'Submissions'));
  81 
  82         // field editor
  83         $fields->addFieldToTab("Root.Content.Form", new FieldEditor("Fields", 'Fields', "", $this ));
  84         
  85         // view the submissions
  86         $fields->addFieldToTab("Root.Content.Submissions", new CheckboxField('DisableSaveSubmissions',_t('UserDefinedForm.SAVESUBMISSIONS',"Disable Saving Submissions to Server")));
  87         $fields->addFieldToTab("Root.Content.Submissions", new SubmittedFormReportField( "Reports", _t('UserDefinedForm.RECEIVED', 'Received Submissions'), "", $this ) );
  88 
  89         // who do we email on submission
  90         $emailRecipients = new ComplexTableField(
  91             $this,
  92             'EmailRecipients',
  93             'UserDefinedForm_EmailRecipient',
  94             array(
  95                 'EmailAddress' => _t('UserDefinedForm.EMAILADDRESS', 'Email'),
  96                 'EmailSubject' => _t('UserDefinedForm.EMAILSUBJECT', 'Subject'),
  97                 'EmailFrom' => _t('UserDefinedForm.EMAILFROM', 'From')
  98             ),
  99             'getCMSFields_forPopup',
 100             "\"FormID\" = '$this->ID'"
 101         );
 102         $emailRecipients->setAddTitle(_t('UserDefinedForm.AEMAILRECIPIENT', 'A Email Recipient'));
 103         
 104         $fields->addFieldToTab("Root.Content.EmailRecipients", $emailRecipients);
 105     
 106         // text to show on complete
 107         $onCompleteFieldSet = new FieldSet(
 108             new HtmlEditorField( "OnCompleteMessage", _t('UserDefinedForm.ONCOMPLETELABEL', 'Show on completion'),3,"",_t('UserDefinedForm.ONCOMPLETEMESSAGE', $this->OnCompleteMessage), $this )
 109         );
 110         
 111         $fields->addFieldsToTab("Root.Content.OnComplete", $onCompleteFieldSet);
 112         $fields->addFieldsToTab("Root.Content.Options", $this->getFormOptions());
 113         
 114         return $fields;
 115     }
 116     
 117     function onAfterDelete() {
 118         parent::onAfterDelete();
 119         
 120         if ($this->IsDeletedFromStage && !$this->ExistsOnLive) {
 121             if ($this->Submissions()->Count()) {
 122                 foreach($this->Submissions() as $submission) {
 123                     $submission->delete();
 124                 }               
 125             }
 126             if ($this->EmailRecipients()->Count()) {
 127                 foreach($this->EmailRecipients() as $emailRecipient) {
 128                     $emailRecipient->delete();
 129                 }
 130             }
 131             if ($this->Fields()->Count()) {
 132                 foreach($this->Fields() as $field) {
 133                     $field->deleteFromStage('Stage');
 134                     $field->deleteFromStage('Live');
 135                 }               
 136             }
 137         }
 138     }
 139     
 140     /**
 141      * Publishing Versioning support.
 142      *
 143      * When publishing copy the editable form fields to the live database
 144      * Not going to version emails and submissions as they are likely to 
 145      * persist over multiple versions
 146      *
 147      * @return void
 148      */
 149     public function doPublish() {
 150         // remove fields on the live table which could have been orphaned.
 151         $live = Versioned::get_by_stage("EditableFormField", "Live", "\"EditableFormField\".\"ParentID\" = $this->ID");
 152 
 153         if($live) {
 154             foreach($live as $field) {
 155                 $field->doDeleteFromStage('Live');
 156             }
 157         }
 158 
 159         // publish the draft pages
 160         if($this->Fields()) {
 161             foreach($this->Fields() as $field) {
 162                 $field->doPublish('Stage', 'Live');
 163             }
 164         }
 165 
 166         parent::doPublish();
 167     }
 168     
 169     /**
 170      * Unpublishing Versioning support
 171      * 
 172      * When unpublishing the page it has to remove all the fields from 
 173      * the live database table
 174      *
 175      * @return void
 176      */
 177     public function doUnpublish() {
 178         if($this->Fields()) {
 179             foreach($this->Fields() as $field) {
 180                 $field->doDeleteFromStage('Live');
 181             }
 182         }
 183         
 184         parent::doUnpublish();
 185     }
 186     
 187     /**
 188      * Roll back a form to a previous version.
 189      *
 190      * @param String|int Version to roll back to
 191      */
 192     public function doRollbackTo($version) {
 193         parent::doRollbackTo($version);
 194         
 195         /*
 196             Not implemented yet 
 197     
 198         // get the older version
 199         $reverted = Versioned::get_version($this->ClassName, $this->ID, $version);
 200         
 201         if($reverted) {
 202             
 203             // using the lastedited date of the reverted object we can work out which
 204             // form fields to revert back to
 205             if($this->Fields()) {
 206                 foreach($this->Fields() as $field) {
 207                     // query to see when the version of the page was pumped
 208                     $editedDate = DB::query("
 209                         SELECT LastEdited
 210                         FROM \"SiteTree_versions\"
 211                         WHERE \"RecordID\" = '$this->ID' AND \"Version\" = $version
 212                     ")->value(); 
 213                     
 214 
 215                     // find a the latest version which has been edited
 216                     $versionToGet = DB::query("
 217                         SELECT *
 218                         FROM \"EditableFormField_versions\" 
 219                         WHERE \"RecordID\" = '$field->ID' AND \"LastEdited\" <= '$editedDate'
 220                         ORDER BY Version DESC
 221                         LIMIT 1
 222                     ")->record();
 223 
 224                     if($versionToGet) {
 225                         Debug::show('publishing field'. $field->Name);
 226                         Debug::show($versionToGet);
 227                         $field->publish($versionToGet, "Stage", true);
 228                         $field->writeWithoutVersion();
 229                     }
 230                     else {
 231                         Debug::show('deleting field'. $field->Name);
 232                         $this->Fields()->remove($field);
 233                         
 234                         $field->delete();
 235                         $field->destroy();
 236                     }
 237                 }
 238             }
 239             
 240             // @todo Emails
 241         }
 242         */
 243     }
 244     
 245     /**
 246      * Revert the draft site to the current live site
 247      *
 248      * @return void
 249      */
 250     public function doRevertToLive() {
 251         if($this->Fields()) {
 252             foreach($this->Fields() as $field) {
 253                 $field->publish("Live", "Stage", false);
 254                 $field->writeWithoutVersion();
 255             }
 256         }
 257         
 258         parent::doRevertToLive();
 259     }
 260     
 261     /**
 262      * Duplicate this UserDefinedForm page, and its form fields.
 263      * Submissions, on the other hand, won't be duplicated.
 264      *
 265      * @return Page
 266      */
 267     public function duplicate($doWrite = true) {
 268         $page = parent::duplicate($doWrite);
 269         
 270         // the form fields
 271         if($this->Fields()) {
 272             foreach($this->Fields() as $field) {
 273                 $newField = $field->duplicate();
 274                 $newField->ParentID = $page->ID;
 275                 $newField->write();
 276             }
 277         }
 278         
 279         // the emails
 280         if($this->EmailRecipients()) {
 281             foreach($this->EmailRecipients() as $email) {
 282                 $newEmail = $email->duplicate();
 283                 $newEmail->FormID = $page->ID;
 284                 $newEmail->write();
 285             }
 286         }
 287         
 288         return $page;
 289     }
 290     
 291     /**
 292      * Custom options for the form. You can extend the built in options by 
 293      * using {@link updateFormOptions()}
 294      *
 295      * @return FieldSet
 296      */
 297     public function getFormOptions() {
 298         $submit = ($this->SubmitButtonText) ? $this->SubmitButtonText : _t('UserDefinedForm.SUBMITBUTTON', 'Submit');
 299         
 300         $options = new FieldSet(
 301             new TextField("SubmitButtonText", _t('UserDefinedForm.TEXTONSUBMIT', 'Text on submit button:'), $submit)
 302         );
 303         
 304         $this->extend('updateFormOptions', $options);
 305         
 306         return $options;
 307     }
 308     
 309     /**
 310      * Return if this form has been modified on the stage site and not published.
 311      * this is used on the workflow module and for a couple highlighting things
 312      *
 313      * @todo make this a bit smarter - the issue with userforms is that it uses several
 314      *      relationships to form fields which has a undefined amount of options so 
 315      *      for now just say its always modified
 316      */
 317 
 318     public function getIsModifiedOnStage() {
 319         if ($this->RelationshipAggregate('Fields')->Max('LastEdited') > $this->LastEdited) return true;
 320         if ($this->RelationshipAggregate('EmailRecipients')->Max('LastEdited') > $this->LastEdited) return true;
 321         return parent::getIsModifiedOnStage();
 322     }
 323 
 324 }
 325 
 326 /**
 327  * Controller for the {@link UserDefinedForm} page type.
 328  *
 329  * @package userform
 330  * @subpackage pagetypes
 331  */
 332 
 333 class UserDefinedForm_Controller extends Page_Controller {
 334     
 335     // суффикс для ID-формы, чтоб отличать одинаковые формы на одной странице
 336     protected $suffix;
 337     
 338     /**
 339      * Load all the custom jquery needed to run the custom 
 340      * validation 
 341      */
 342     public function init() {
 343         parent::init();
 344         
 345         $this->formInit();
 346     }
 347     
 348     /**
 349      * Выносим подгрузку скриптов в функцию, чтоб ее можно было вызвать отдельно (напр. в виджете)
 350      * 
 351      */
 352     function formInit() {
 353         // block prototype validation
 354         Validator::set_javascript_validation_handler('none');
 355         
 356         // load the jquery
 357         if (UserDefinedForm::$use_js_validation) {
 358             Requirements::javascript(JQUERY_PATH);
 359             Requirements::javascript('site/js/vendor/jquery.validate.js');
 360             // !!!! узнать у Саши и заменить - взял новые с https://github.com/jquery-validation/jquery-validation/tree/master/src/localization
 361             Requirements::javascript('userforms/thirdparty/jquery-validate/localization/messages_'.i18n::get_lang_from_locale(i18n::get_locale()).'.js');
 362         }
 363     }
 364     
 365     /**
 366      * Using $UserDefinedForm in the Content area of the page shows
 367      * where the form should be rendered into. If it does not exist
 368      * then default back to $Form
 369      *
 370      * @return Array
 371      */
 372     public function index() {
 373         $form = $this->Form();
 374         $customScripts = '';
 375         if ($this->isAjax()) {
 376             $this->suffix = 'ajax';
 377             $form->setHtmlID($this->generateFormID());
 378             $form->loadDataFrom(array('HtmlIDSuffix' => $this->suffix));
 379             $form->addExtraClass('form__ajax');
 380             $customScripts = $this->generateConditionalJavascript(true);
 381         }
 382         if($this->Content && $form) {
 383             $hasLocation = stristr($this->Content, '$UserDefinedForm');
 384             if($hasLocation) {
 385                 $content = str_ireplace('$UserDefinedForm', $form->forTemplate(), $this->Content);
 386                 return array(
 387                     'Content' => DBField::create('HTMLText', $content),
 388                     'Form' => "",
 389                     'customScripts' => $customScripts,
 390                 );
 391             }
 392         }
 393 
 394         return array(
 395             'Content' => DBField::create('HTMLText', $this->Content),
 396             'Form' => $form,
 397             'customScripts' => $customScripts,
 398         );
 399     }
 400 
 401     /**
 402      * Get the form for the page. Form can be modified by calling {@link updateForm()}
 403      * on a UserDefinedForm extension
 404      *
 405      * @return Form|false
 406      */
 407     function Form() {
 408         $fields = $this->getFormFields();
 409         if(!$fields) return false;
 410                 
 411         if (isset($_REQUEST['HtmlIDSuffix']) && trim($_REQUEST['HtmlIDSuffix'])) {
 412             $this->suffix = trim($_REQUEST['HtmlIDSuffix']);
 413         }
 414         $actions = $this->getFormActions();
 415         
 416         // get the required fields including the validation
 417         $required = $this->getRequiredFields();
 418 
 419         // generate the conditional logic 
 420         $this->generateConditionalJavascript();
 421 
 422         $form = new Form($this, "Form", $fields, $actions, $required);
 423         
 424         $form->setHtmlID($this->generateFormID());
 425         $form->addExtraClass('UserForm');
 426         
 427         // дополнительно формируем ошибки после указания правильного HtmlID
 428         $form->setupFormErrors();
 429         
 430         $data = Session::get("FormInfo.{$form->FormName()}.data");
 431         
 432         if(is_array($data)) $form->loadDataFrom($data);
 433         
 434         $this->extend('updateForm', $form);
 435 
 436         return $form;
 437     }
 438 
 439     function generateFormID() {
 440 //      return 'Form_Form';
 441         return 'UserForm'.$this->ID.($this->suffix ? "_{$this->suffix}" : "");
 442     }
 443     
 444     /**
 445      * Get the form fields for the form on this page. Can modify this FieldSet
 446      * by using {@link updateFormFields()} on an {@link Extension} subclass which
 447      * is applied to this controller
 448      *
 449      * @return FieldSet
 450      */
 451     function getFormFields() {
 452         $fields = new FieldSet();
 453 
 454         if($this->Fields()) {
 455             foreach($this->Fields() as $editableField) {
 456                 // get the raw form field from the editable version
 457                 $field = $editableField->getFormField();
 458                 if(!$field) break;
 459                 
 460                 // set the error / formatting messages
 461                 $field->setCustomValidationMessage($editableField->getErrorMessage());
 462 
 463                 // set the right title on this field
 464                 if($right = $editableField->getSetting('RightTitle')) {
 465                     $field->setRightTitle($right);
 466                 }
 467                 
 468                 // if this field is required add some
 469                 if($editableField->Required) {
 470                     $field->addExtraClass('requiredField');
 471                     
 472                     if($identifier = UserDefinedForm::$required_identifier) {
 473                         
 474                         $title = $field->Title() ." <span class='required-identifier'>". $identifier . "</span>";
 475                         $field->setTitle($title);
 476                     }
 477                 }
 478                 // if this field has an extra class
 479                 if($editableField->getSetting('ExtraClass')) {
 480                     $extraClasses = explode(' ', $editableField->getSetting('ExtraClass'));
 481                     foreach($extraClasses as $extraClass) {
 482                         if (trim($extraClass)) {
 483                             $field->addExtraClass(Convert::raw2att(trim($extraClass)));
 484                         }
 485                     }
 486                 }
 487                 
 488                 //добавляем placeholder
 489                 if($editableField->getSetting('Placeholder')) {
 490                     $field->addExtraAttribute('placeholder', Convert::raw2att($editableField->getSetting('Placeholder')));
 491                 }               
 492                 
 493                 // set the values passed by the url to the field
 494                 $request = $this->getRequest();
 495                 if($request && $var = $request->getVar($field->name)) {
 496                     $field->value = Convert::raw2att($var);
 497                 }
 498                 
 499                 $fields->push($field);
 500             }
 501         }
 502         $fields->push(new HiddenField('HtmlIDSuffix'));
 503         $this->extend('updateFormFields', $fields);
 504 
 505         return $fields;
 506     }
 507     
 508     /**
 509      * Generate the form actions for the UserDefinedForm. You 
 510      * can manipulate these by using {@link updateFormActions()} on
 511      * a decorator.
 512      *
 513      * @todo Make form actions editable via their own field editor.
 514      *
 515      * @return FieldSet
 516      */
 517     function getFormActions() {
 518         $submitText = ($this->SubmitButtonText) ? $this->SubmitButtonText : _t('UserDefinedForm.SUBMITBUTTON', 'Submit');
 519         
 520         $actions = new FieldSet(
 521             new FormAction("process", $submitText)
 522         );
 523         
 524         $this->extend('updateFormActions', $actions);
 525         
 526         return $actions;
 527     }
 528     
 529     /**
 530      * Get the required form fields for this form. Includes building the jQuery
 531      * validate structure
 532      *
 533      * @return RequiredFields
 534      */
 535     function getRequiredFields() {
 536         $required = new RequiredFields();
 537         
 538         $rules = array();
 539         $validation = array();
 540         $messages = array();
 541         
 542         if($this->Fields()) {
 543             foreach($this->Fields() as $field) {
 544                 $messages[$field->Name] = $field->getErrorMessage()->HTML();
 545     
 546                 if ($field->CustomRules()->Count() == 0) {
 547                     $rules[$field->Name] = $field->getValidation();
 548                     if ($field->Required) {
 549                         $required->addRequiredField($field->Name);
 550                     }
 551                 }
 552             }
 553         }
 554         
 555         if (UserDefinedForm::$use_js_validation) {
 556             // Set the Form Name
 557             $rules = $this->array2json($rules);
 558             $messages = $this->array2json($messages);
 559         
 560             // set the custom script for this form
 561             Requirements::customScript(<<<JS
 562 (function($) {
 563     $(document).ready(function() {      
 564         //настраиваем валидацию
 565         var validateOptions = {
 566             ignore: [':hidden'],
 567             errorElement: "span",
 568             validClass: "is-valid",
 569             errorClass: "required",
 570             errorPlacement: function(error, element) {
 571                 if (element.is(":radio")) {
 572                     error.insertAfter(element.closest("ul"));
 573                 } else if (element.is(":checkbox")) {
 574                     console.log(element)
 575                     var wrapper = element.closest('.middlecolumn');
 576                     if(wrapper) {
 577                         error.insertAfter(wrapper);
 578                     } else {
 579                         error.insertAfter(element);
 580                     };
 581                 } else {
 582                     error.insertAfter(element);
 583                 }
 584             },
 585             messages:
 586                 $messages
 587             ,
 588             rules: 
 589                 $rules
 590         };
 591         $("#{$this->generateFormID()}").validate(validateOptions);
 592     });
 593 })(jQuery);
 594 JS
 595                 , 'Validation' . $this->generateFormID());
 596         }
 597         
 598         $this->extend('updateRequiredFields', $required);
 599         
 600         return $required;
 601     }
 602     
 603     /**
 604      * Generate the javascript for the conditional field show / hiding logic.
 605      * Allows complex rules to be created 
 606      * @return void
 607      */
 608     function generateConditionalJavascript($asText=false) {
 609         $default = "";
 610         $rules = "";
 611         
 612         if($this->Fields()) {
 613             foreach($this->Fields() as $field) {
 614                 $fieldId = $field->Name;
 615                 
 616                 //if($field->ClassName == 'EditableFormHeading') { 
 617                     $fieldId = $this->generateFormID().'_'.$field->Name;
 618                 //}
 619                 
 620                 // Is this Field Show by Default
 621                 if(!$field->getShowOnLoad()) {
 622                     $default .= "$(\"#" . $fieldId . "\").hide();\n";
 623                 }
 624 
 625                 // Check for field dependencies / default
 626                 if($field->Dependencies()) {
 627                     foreach($field->Dependencies() as $dependency) {
 628                         if(is_array($dependency) && isset($dependency['ConditionField']) && $dependency['ConditionField'] != "") {
 629                             // get the field which is effected
 630                             $formName = Convert::raw2sql($dependency['ConditionField']);
 631                             $formFieldWatch = DataObject::get_one("EditableFormField", "\"Name\" = '$formName'");
 632                             $fieldWatchId = $this->generateFormID().'_'.$formFieldWatch->Name;
 633                             
 634                             if(!$formFieldWatch) break;
 635                             
 636                             // watch out for multiselect options - radios and check boxes
 637                             if(is_a($formFieldWatch, 'EditableDropdown')) {
 638                                 $fieldToWatch = "$(\"select#{$fieldWatchId}\")";    
 639                             }
 640                             
 641                             // watch out for checkboxs as the inputs don't have values but are 'checked
 642                             else if(is_a($formFieldWatch, 'EditableCheckboxGroupField')) {
 643                                 $fieldToWatch = "$(\"input#{$fieldWatchId}[".$dependency['Value']."]']\")";
 644                             }
 645                             else {
 646                                 $fieldToWatch = "$(\"input#{$fieldWatchId}\")";
 647                             }
 648                             
 649                             // show or hide?
 650                             $view = (isset($dependency['Display']) && $dependency['Display'] == "Hide") ? "hide" : "show";
 651                             $opposite = ($view == "show") ? "hide" : "show";
 652                             
 653                             // what action do we need to keep track of. Something nicer here maybe?
 654                             // @todo encapulsation
 655                             $action = "change";
 656                             
 657                             if($formFieldWatch->ClassName == "EditableTextField" || $formFieldWatch->ClassName == "EditableDateField") {
 658                                 $action = "keyup";
 659                             }
 660                             
 661                             // is this field a special option field
 662                             $checkboxField = false;
 663                             if(in_array($formFieldWatch->ClassName, array('EditableCheckboxGroupField', 'EditableCheckbox'))) {
 664                                 $action = "click";
 665                                 $checkboxField = true;
 666                             }
 667                             
 668                             // and what should we evaluate
 669                             switch($dependency['ConditionOption']) {
 670                                 case 'IsNotBlank':
 671                                     $expression = ($checkboxField) ? '$(this).attr("checked")' :'$(this).val() != ""';
 672 
 673                                     break;
 674                                 case 'IsBlank':
 675                                     $expression = ($checkboxField) ? '!($(this).attr("checked"))' : '$(this).val() == ""';
 676                                     
 677                                     break;
 678                                 case 'HasValue':
 679                                     $expression = ($checkboxField) ? '$(this).attr("checked")' : '$(this).val() == "'. $dependency['Value'] .'"';
 680 
 681                                     break;
 682                                 case 'ValueLessThan':
 683                                     $expression = '$(this).val() < parseFloat("'. $dependency['Value'] .'")';
 684                                     
 685                                     break;
 686                                 case 'ValueLessThanEqual':
 687                                     $expression = '$(this).val() <= parseFloat("'. $dependency['Value'] .'")';
 688                                     
 689                                     break;
 690                                 case 'ValueGreaterThan':
 691                                     $expression = '$(this).val() > parseFloat("'. $dependency['Value'] .'")';
 692 
 693                                     break;
 694                                 case 'ValueGreaterThanEqual':
 695                                     $expression = '$(this).val() >= parseFloat("'. $dependency['Value'] .'")';
 696 
 697                                     break;  
 698                                 default:
 699                                     $expression = ($checkboxField) ? '!($(this).attr("checked"))' : '$(this).val() != "'. $dependency['Value'] .'"';
 700                                 
 701                                     break;
 702                             }
 703                             // put it all together
 704                             $rules .= $fieldToWatch.".$action(function() {
 705                                 if(". $expression ." ) {
 706                                     $(\"#". $fieldId ."_wrapper\").".$view."();
 707                                 }
 708                                 else {
 709                                     $(\"#". $fieldId ."_wrapper\").".$opposite."();
 710                                 }
 711                             });";
 712                         }
 713                     }
 714                 }
 715             }
 716         }
 717         
 718         if ($rules || $default) {
 719             $script = 
 720 <<<JS
 721             (function($) {
 722                 $(document).ready(function() {
 723                     $rules
 724                     
 725                     $default
 726                 })
 727             })(jQuery);
 728 JS;
 729             if ($asText) {
 730                 return $script;
 731             } else {
 732                 Requirements::customScript($script, 'Conditional' . $this->generateFormID());
 733             }
 734             
 735 
 736         }
 737 
 738     }
 739     
 740     /**
 741      * Convert a PHP array to a JSON string. We cannot use {@link Convert::array2json}
 742      * as it escapes our values with "" which appears to break the validate plugin
 743      *
 744      * @param Array array to convert
 745      * @return JSON 
 746      */
 747     function array2json($array) {
 748         foreach($array as $key => $value)
 749             if(is_array( $value )) {
 750                 $result[] = "$key:" . $this->array2json($value);
 751             } else {
 752                 $value = (is_bool($value)) ? $value : "\"$value\"";
 753                 $result[] = "$key:$value";
 754             }
 755         return (isset($result)) ? "{\n".implode( ', ', $result ) ."\n}\n": '{}';
 756     }
 757     
 758     /**
 759      * Process the form that is submitted through the site
 760      * 
 761      * @param Array Data
 762      * @param Form Form 
 763      * @return Redirection
 764      */
 765     function process($data, $form) {
 766         if (isset($data['HtmlIDSuffix']) && trim($data['HtmlIDSuffix'])) {
 767             $this->suffix = trim($data['HtmlIDSuffix']);
 768             $form->setHtmlID($this->generateFormID());
 769         }
 770         Session::set("FormInfo.{$form->FormName()}.data",$data);    
 771         Session::clear("FormInfo.{$form->FormName()}.errors");
 772         
 773         foreach($this->Fields() as $field) {
 774             $messages[$field->Name] = $field->getErrorMessage()->HTML();
 775             if($field->Required && $field->CustomRules()->Count() == 0 && $field->ClassName != 'EditableSpamProtectionField') {
 776                 // EditableSpamProtectionField - можно проверить всего 1 раз и это делает $this->validator
 777                 if( !isset($data[$field->Name]) ||
 778                     !$data[$field->Name] ||
 779                     !$field->getFormField()->validate($this->validator)
 780                 ){
 781                     $form->addErrorMessage($field->Name,$field->getErrorMessage()->HTML(),'bad');
 782                 }
 783             }
 784         }
 785 
 786         if(Session::get("FormInfo.{$form->FormName()}.errors")){
 787             if (Director::is_ajax()) {
 788                 return $this->index();
 789             }
 790             Director::redirectBack();
 791             return;
 792         }
 793         
 794         $submittedForm = SS_Object::create('SubmittedForm');
 795         $submittedForm->SubmittedByID = ($id = Member::currentUserID()) ? $id : 0;
 796         $submittedForm->ParentID = $this->ID;
 797 
 798         // if saving is not disabled save now to generate the ID
 799         if(!$this->DisableSaveSubmissions) $submittedForm->write();
 800         
 801         $values = array();
 802         $attachments = array();
 803 
 804         $submittedFields = new DataObjectSet();
 805         
 806         foreach($this->Fields() as $field) {
 807             
 808             if(!$field->showInReports()) continue;
 809             
 810             $submittedField = $field->getSubmittedFormField();
 811             $submittedField->ParentID = $submittedForm->ID;
 812             $submittedField->Name = $field->Name;
 813             $submittedField->Title = $field->getField('Title');
 814             
 815             // save the value from the data
 816             if($field->hasMethod('getValueFromData')) {
 817                 $submittedField->Value = $field->getValueFromData($data);
 818             }
 819             else {
 820                 if(isset($data[$field->Name])) $submittedField->Value = $data[$field->Name];
 821             }
 822 
 823             if(!empty($data[$field->Name])){
 824                 if(in_array("EditableFileField", $field->getClassAncestry())) {
 825                     if(isset($_FILES[$field->Name])) {
 826                         
 827                         // create the file from post data
 828                         $upload = new Upload();
 829                         $file = new File();
 830                         $file->ShowInSearch = 0;
 831                         
 832                         $upload->loadIntoFile($_FILES[$field->Name], $file);
 833 
 834                         // write file to form field
 835                         $submittedField->UploadedFileID = $file->ID;
 836                         
 837                         // attach a file only if lower than 1MB
 838                         if($file->getAbsoluteSize() < 1024*1024*1){
 839                             $attachments[] = $file;
 840                         }
 841                     }                                   
 842                 }
 843             }
 844             
 845             if(!$this->DisableSaveSubmissions) $submittedField->write();
 846     
 847             $submittedFields->push($submittedField);
 848         }
 849         
 850         $emailData = array(
 851             "Sender" => Member::currentUser(),
 852             "Fields" => $submittedFields,
 853             'SenderIP' => $_SERVER{'REMOTE_ADDR'},
 854         );
 855 
 856         $this->extend('onBeforeSend', $submittedForm, $emailData);
 857 
 858         // email users on submit.
 859         if($this->EmailRecipients()) {
 860             
 861             $email = new UserDefinedForm_SubmittedFormEmail($submittedFields);                     
 862             $email->populateTemplate($emailData);
 863             
 864             if($attachments){
 865                 foreach($attachments as $file){
 866                     if($file->ID != 0) {
 867                         $email->attachFile($file->Filename,$file->Filename, HTTP::getMimeType($file->Filename));
 868                     }
 869                 }
 870             }
 871 
 872             foreach($this->EmailRecipients() as $recipient) {
 873                 $email->populateTemplate($recipient);
 874                 $email->populateTemplate($emailData);
 875                 $email->setFrom($recipient->EmailFrom);
 876                 $email->setBody($recipient->EmailBody);
 877                 $email->setSubject($recipient->EmailSubject);
 878                 $email->setTo($recipient->EmailAddress);
 879                 
 880                 // check to see if they are a dynamic sender. eg based on a email field a user selected
 881                 if($recipient->SendEmailFromField()) {
 882                     $submittedFormField = $submittedFields->find('Name', $recipient->SendEmailFromField()->Name);
 883                     if($submittedFormField) {
 884                         $email->setFrom($submittedFormField->Value);    
 885                     }
 886                 }
 887                 // check to see if they are a dynamic reciever eg based on a dropdown field a user selected
 888                 if($recipient->SendEmailToField()) {
 889                     $submittedFormField = $submittedFields->find('Name', $recipient->SendEmailToField()->Name);
 890                     
 891                     if($submittedFormField) {
 892                         $email->setTo($submittedFormField->Value);  
 893                     }
 894                 }
 895                 
 896                 if (!trim($email->To())) {
 897                     continue; // получатель не указан
 898                 }
 899                 if (!$plainBody = $email->renderWith('SubmittedFormEmail_plain')) {
 900                     $plainBody = strip_tags($recipient->EmailBody) . "\n\n";                
 901                     if (isset($emailData['Fields']) && !$recipient->HideFormData) {
 902                         foreach($emailData['Fields'] as $Field) {
 903                             $plainBody .= ($Field->Title ? $Field->Title : $Field->Name) .': '. $Field->Value ."\n";
 904                         }
 905                     }
 906                 }
 907 
 908                 $email->setPlainBody($plainBody);
 909 
 910                 if($recipient->SendPlain) {
 911                     $email->sendPlain();
 912                 }
 913                 else {
 914                     $email->send();
 915                 }
 916             }
 917         }
 918         
 919         Session::clear("FormInfo.{$form->FormName()}.errors");
 920         Session::clear("FormInfo.{$form->FormName()}.data");
 921 
 922         $this->extend('onAfterProccess', $submittedForm, $emailData);
 923 
 924         if (Director::is_ajax()) return $this->OnCompleteMessage;
 925         /*
 926         if ($this->isAjax()) {
 927             if ($request = $this->getRequest()) {
 928                 if ($acceptType = $request->getHeader('Accept')) {
 929                     if(strpos($acceptType, 'application/json') !== FALSE) {
 930                         return json_encode(array(array(
 931                             'type' => 'good',
 932                             'message' => $this->OnCompleteMessage
 933                         )));
 934                     }
 935                 }
 936             }
 937             return $this->OnCompleteMessage;
 938         }
 939         */
 940         $referrer = (isset($data['Referrer'])) ? '?referrer=' . urlencode($data['Referrer']) : "";
 941         return Director::redirect($this->Link() . 'finished' . $referrer);
 942     }
 943 
 944     /**
 945      * This action handles rendering the "finished" message,
 946      * which is customisable by editing the ReceivedFormSubmission.ss
 947      * template.
 948      *
 949      * @return ViewableData
 950      */
 951     function finished() {
 952         $referrer = isset($_GET['referrer']) ? urldecode($_GET['referrer']) : null;
 953         
 954         return $this->customise(array(
 955             'Content' => $this->customise(
 956                 array(
 957                     'Link' => $referrer
 958                 ))->renderWith('ReceivedFormSubmission'),
 959             'Form' => '',
 960         ));
 961     }
 962 }
 963 
 964 /**
 965  * A Form can have multiply members / emails to email the submission 
 966  * to and custom subjects
 967  * 
 968  * @package userforms
 969  */
 970 class UserDefinedForm_EmailRecipient extends DataObject {
 971     
 972     static $db = array(
 973         'EmailAddress' => 'Varchar(200)',
 974         'EmailSubject' => 'Varchar(200)',
 975         'EmailFrom' => 'Varchar(200)',
 976         'EmailBody' => 'Text',
 977         'SendPlain' => 'Boolean',
 978         'HideFormData' => 'Boolean'
 979     );
 980     
 981     static $has_one = array(
 982         'Form' => 'UserDefinedForm',
 983         'SendEmailFromField' => 'EditableFormField',
 984         'SendEmailToField' => 'EditableFormField'
 985     );
 986     
 987     /**
 988      * Return the fields to edit this email. 
 989      * @return FieldSet
 990      */
 991     public function getCMSFields_forPopup() {
 992         
 993         $fields = new FieldSet(
 994             new TextField('EmailSubject', _t('UserDefinedForm.EMAILSUBJECT', 'Email Subject')),
 995             new TextField('EmailFrom', _t('UserDefinedForm.FROMADDRESS','Send Email From')),
 996             new TextField('EmailAddress', _t('UserDefinedForm.SENDEMAILTO','Send Email To')),
 997             new CheckboxField('HideFormData', _t('UserDefinedForm.HIDEFORMDATA', 'Hide Form Data from Email')),
 998             new CheckboxField('SendPlain', _t('UserDefinedForm.SENDPLAIN', 'Send Email as Plain Text (HTML will be stripped)')),
 999             new TextareaField('EmailBody', _t('UserDefinedForm.EMAILBODY','Body'))
1000         );
1001         
1002         if($this->Form()) {
1003             $validEmailFields = DataObject::get("EditableEmailField", "\"ParentID\" = '" . (int)$this->FormID . "'");
1004             $multiOptionFields = DataObject::get("EditableMultipleOptionField", "\"ParentID\" = '" . (int)$this->FormID . "'");
1005             
1006             // if they have email fields then we could send from it
1007             if($validEmailFields) {
1008                 $fields->insertAfter(new DropdownField('SendEmailFromFieldID', _t('UserDefinedForm.ORSELECTAFIELDTOUSEASFROM', '.. or Select a Form Field to use as the From Address'), $validEmailFields->toDropdownMap('ID', 'Title'), '', null,""), 'EmailFrom');
1009             }
1010             
1011             // if they have multiple options
1012             if($multiOptionFields || $validEmailFields) {
1013 
1014                 if($multiOptionFields && $validEmailFields) {
1015                     $multiOptionFields->merge($validEmailFields);
1016                     
1017                 }
1018                 elseif(!$multiOptionFields) {
1019                     $multiOptionFields = $validEmailFields; 
1020                 }
1021                 
1022                 $multiOptionFields = $multiOptionFields->toDropdownMap('ID', 'Title');
1023                 $fields->insertAfter(new DropdownField('SendEmailToFieldID', _t('UserDefinedForm.ORSELECTAFIELDTOUSEASTO', '.. or Select a Field to use as the To Address'), $multiOptionFields, '', null, ""), 'EmailAddress');
1024             }
1025         }
1026 
1027         return $fields;
1028     }
1029     
1030     function canEdit($member = NULL) {
1031         return $this->Form()->canEdit();
1032     }
1033     
1034     function canDelete($member = NULL) {
1035         return $this->Form()->canEdit();
1036     }
1037 }
1038 
1039 /**
1040  * Email that gets sent to the people listed in the Email Recipients 
1041  * when a submission is made
1042  *
1043  * @package userforms
1044  */
1045 
1046 class UserDefinedForm_SubmittedFormEmail extends Email {
1047     protected $ss_template = "SubmittedFormEmail";
1048     protected $data;
1049 
1050     function __construct() {
1051         parent::__construct();
1052     }
1053 }
1054 
[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. -
Webylon 3.2 API Docs API documentation generated by ApiGen 2.8.0