"Varchar", "Title" => "Varchar(255)", "Default" => "Varchar", "Sort" => "Int", "Required" => "Boolean", "CanDelete" => "Boolean", "CustomParameter" => "Varchar", "CustomErrorMessage" => "Varchar(255)", "CustomRules" => "Text", "ShowOnLoad" => "Boolean", "CustomSettings" => "Text" ); static $defaults = array( "CanDelete" => "1", "ShowOnLoad" => "1" ); static $has_one = array( "Parent" => "SiteTree", ); /** * @var bool Is this field readonly to the user */ protected $readonly; /** * @var FieldEditor The current editor */ protected $editor; /** * Construct a new EditableFormField Object. * * @param array|null $record This will be null for a new database record. * @param boolean $isSingleton This this to true if this is a singleton() object, a stub for calling methods. */ public function __construct($record = null, $isSingleton = false) { $this->setField('Default', -1); parent::__construct( $record, $isSingleton ); } /** * Set the FieldEditor object for this field. * * @param FieldEditor The Editor window you wish to use */ protected function setEditor($editor) { $this->editor = $editor; } function EditSegment() { return $this->renderWith('EditableFormField'); } function isReadonly() { return $this->readonly; } function ClassName() { return $this->class; } /** * To prevent having tables for each fields minor settings we store it as * a serialized array in the database. * * @return Array Return all the Settings */ protected function getFieldSettings() { return (isset($this->CustomSettings)) ? unserialize($this->CustomSettings) : array(); } /** * Set the custom settings for this field as we store the minor details in * a serialized array in the database * * @param Array the custom settings */ protected function setFieldSettings($settings = array()) { $this->CustomSettings = serialize($settings); } /** * Return just one custom setting or empty string if it does * not exist * * @param String Value to use as key * @return String */ public function getSetting($setting) { $settings = $this->getFieldSettings(); if(isset($settings) && count($settings) > 0) { if(isset($settings[$setting])) { return $settings[$setting]; } } return ''; } /** * Get the path to the icon for this field type, relative to the site root. * * @return string */ public function Icon() { return 'userforms/images/' . strtolower($this->class) . '.png'; } /** * Return whether or not this field has addable options * such as a dropdown field or radio set * * @return bool */ public function hasAddableOptions() { return false; } /** * Return whether or not this field needs to show the extra * options dropdown list * * @return bool */ public function showExtraOptions() { return true; } /** * Return the Custom Validation fields for this * field for the CMS * * @return array */ public function Dependencies() { return ($this->CustomRules) ? unserialize($this->CustomRules) : array(); } /** * Return the custom validation fields for the field * * @return DataObjectSet */ public function CustomRules() { $output = new DataObjectSet(); $fields = $this->Parent()->Fields(); // add the default add $output->push(new ArrayData(array( 'Name' => $this->Name(), 'AddableOption' => true, 'Fields' => $fields ))); // check for existing ones if($this->CustomRules) { $rules = unserialize($this->CustomRules); if($rules) { foreach($rules as $rule => $data) { // recreate all the field object to prevent caching $outputFields = new DataObjectSet(); foreach($fields as $field) { $new = clone $field; $new->isSelected = ($new->Name == $data['ConditionField']) ? true : false; $outputFields->push($new); } $output->push(new ArrayData(array( 'Name' => $this->Name(), 'Display' => $data['Display'], 'Fields' => $outputFields, 'ConditionField' => $data['ConditionField'], 'ConditionOption' => $data['ConditionOption'], 'Value' => $data['Value'] ))); } } } return $output; } function makeReadonly() { $this->readonly = true; return $this; } function ReadonlyEditSegment() { $this->readonly = true; return $this->EditSegment(); } function TitleField() { $titleAttr = Convert::raw2att($this->Title); $readOnlyAttr = ($this->readonly) ? ' disabled="disabled"' : ''; return "ID}][Title]\"$readOnlyAttr />"; } /** * Return the base name for this form field in the * form builder * * @return String */ public function Name() { return "Fields[".$this->ID."]"; } /** * @todo Fix this - shouldn't name be returning name?!? */ public function BaseName() { return $this->Name; } /** * How to save the data submitted in this field into * the database object which this field represents. * * Any class's which call this should also call * {@link parent::populateFromPostData()} to ensure * that this method is called * * @access public */ public function populateFromPostData($data) { $this->Title = (isset($data['Title'])) ? $data['Title']: ""; $this->Default = (isset($data['Default'])) ? $data['Default'] : ""; $this->Sort = isset($data['Sort']) ? $data['Sort'] : null; $this->CustomParameter = isset($data['CustomParameter']) ? $data['CustomParameter'] : null; $this->Required = !empty($data['Required']) ? 1 : 0; $this->CanDelete = (isset($data['CanDelete']) && !$data['CanDelete']) ? 0 : 1; $this->Name = $this->class.$this->ID; $this->CustomErrorMessage = (isset($data['CustomErrorMessage'])) ? $data['CustomErrorMessage'] : ""; $this->CustomRules = ""; $this->CustomSettings = ""; $this->ShowOnLoad = (isset($data['ShowOnLoad']) && $data['ShowOnLoad'] == "Show") ? 1 : 0; // custom settings if(isset($data['CustomSettings'])) { $this->setFieldSettings($data['CustomSettings']); } // custom validation if(isset($data['CustomRules'])) { $rules = array(); foreach($data['CustomRules'] as $key => $value) { if(is_array($value)) { $fieldValue = (isset($value['Value'])) ? $value['Value'] : ''; if(isset($value['ConditionOption']) && $value['ConditionOption'] == "Blank" || $value['ConditionOption'] == "NotBlank") { $fieldValue = ""; } $rules[] = array( 'Display' => (isset($value['Display'])) ? $value['Display'] : "", 'ConditionField' => (isset($value['ConditionField'])) ? $value['ConditionField'] : "", 'ConditionOption' => (isset($value['ConditionOption'])) ? $value['ConditionOption'] : "", 'Value' => $fieldValue ); } } $this->CustomRules = serialize($rules); } $this->write(); } function ExtraOptions() { $baseName = "Fields[$this->ID]"; $extraOptions = new FieldSet(); // Is this field required if(!$this->Parent()->hasMethod('hideExtraOption')){ $extraOptions->push(new CheckboxField($baseName . "[Required]", _t('EditableFormField.REQUIRED', 'Required?'), $this->Required)); } elseif(!$this->Parent()->hideExtraOption('Required')){ $extraOptions->push(new CheckboxField($baseName . "[Required]", _t('EditableFormField.REQUIRED', 'Required?'), $this->Required)); } if($this->Parent()->hasMethod('getExtraOptionsForField')) { $extraFields = $this->Parent()->getExtraOptionsForField($this); foreach($extraFields as $extraField) { $extraOptions->push($extraField); } } if($this->readonly) { $extraOptions = $extraOptions->makeReadonly(); } // custom error messaging $extraOptions->push(new TextField($baseName.'[CustomErrorMessage]', _t('EditableFormField.CUSTOMERROR','Custom Error Message'), $this->CustomErrorMessage)); return $extraOptions; } /** * Return a FormField to appear on the front end. Implement on * your subclass * * @return FormField */ public function getFormField() { user_error("Please implement a getFormField() on your EditableFormClass ". $this->ClassName, E_USER_ERROR); } function showInReports() { return true; } function prepopulate( $value ) { $this->prepopulateFromMap( $this->parsePrepopulateValue( $value ) ); } protected function parsePrepopulateValue( $value ) { $paramList = explode( ',', $value ); $paramMap = array(); foreach( $paramList as $param ) { if( preg_match( '/([^=]+)=(.+)/', $param, $match ) ) { if( isset( $paramMap[$match[1]] ) && is_array( $paramMap[$match[1]] ) ) { $paramMap[$match[1]][] = $match[2]; } else if( isset( $paramMap[$match[1]] ) ) { $paramMap[$match[1]] = array( $paramMap[$match[1]] ); $paramMap[$match[1]][] = $match[2]; } else { $paramMap[$match[1]] = $match[2]; } } } return $paramMap; } protected function prepopulateFromMap( $paramMap ) { foreach($paramMap as $field => $fieldValue) { if(!is_array($fieldValue)) { $this->$field = $fieldValue; } } } function Type() { return $this->class; } function CustomParameter() { return $this->CustomParameter; } /** * Return the validation information related to this field. This is * interrupted as a JSON object for validate plugin and used in the * PHP. * * @see http://docs.jquery.com/Plugins/Validation/Methods * @return Array */ public function getValidation() { return array(); } } ?>