Advertisement
Guest User

Untitled

a guest
Nov 5th, 2014
173
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.52 KB | None | 0 0
  1. <?php
  2. /**
  3. * Represents the base class of a editable form field
  4. * object like {@link EditableTextField}.
  5. *
  6. * @package userforms
  7. */
  8.  
  9. class EditableFormField extends DataObject {
  10.  
  11. private static $default_sort = "Sort";
  12.  
  13. /**
  14. * A list of CSS classes that can be added
  15. *
  16. * @var array
  17. */
  18. public static $allowed_css = array();
  19.  
  20. private static $db = array(
  21. "Name" => "Varchar",
  22. "Title" => "Varchar(255)",
  23. "Default" => "Varchar",
  24. "Sort" => "Int",
  25. "Required" => "Boolean",
  26. "CustomErrorMessage" => "Varchar(255)",
  27. "CustomRules" => "Text",
  28. "CustomSettings" => "Text",
  29. "CustomParameter" => "Varchar(200)"
  30. );
  31.  
  32. private static $has_one = array(
  33. "Parent" => "UserDefinedForm",
  34. "ContainerField" => "EditableCompositeField"
  35. );
  36.  
  37. private static $extensions = array(
  38. "Versioned('Stage', 'Live')"
  39. );
  40.  
  41. /**
  42. * @var bool
  43. */
  44. protected $readonly;
  45.  
  46. /**
  47. * Set the visibility of an individual form field
  48. *
  49. * @param bool
  50. */
  51. public function setReadonly($readonly = true) {
  52. $this->readonly = $readonly;
  53. }
  54.  
  55. /**
  56. * Returns whether this field is readonly
  57. *
  58. * @return bool
  59. */
  60. private function isReadonly() {
  61. return $this->readonly;
  62. }
  63.  
  64. /**
  65. * Template to render the form field into
  66. *
  67. * @return String
  68. */
  69. public function EditSegment() {
  70. return $this->renderWith('EditableFormField');
  71. }
  72.  
  73. /**
  74. * Flag indicating that this field will set its own error message via data-msg='' attributes
  75. *
  76. * @return bool
  77. */
  78. public function getSetsOwnError() {
  79. return false;
  80. }
  81.  
  82. /**
  83. * Return whether a user can delete this form field
  84. * based on whether they can edit the page
  85. *
  86. * @return bool
  87. */
  88. public function canDelete($member = null) {
  89. return ($this->Parent()->canEdit($member = null) && !$this->isReadonly());
  90. }
  91.  
  92. /**
  93. * Return whether a user can edit this form field
  94. * based on whether they can edit the page
  95. *
  96. * @return bool
  97. */
  98. public function canEdit($member = null) {
  99. return ($this->Parent()->canEdit($member = null) && !$this->isReadonly());
  100. }
  101.  
  102. /**
  103. * Publish this Form Field to the live site
  104. *
  105. * Wrapper for the {@link Versioned} publish function
  106. */
  107. public function doPublish($fromStage, $toStage, $createNewVersion = false) {
  108. $this->publish($fromStage, $toStage, $createNewVersion);
  109. }
  110.  
  111. /**
  112. * Delete this form from a given stage
  113. *
  114. * Wrapper for the {@link Versioned} deleteFromStage function
  115. */
  116. public function doDeleteFromStage($stage) {
  117. $this->deleteFromStage($stage);
  118. }
  119.  
  120. /**
  121. * checks wether record is new, copied from Sitetree
  122. */
  123. function isNew() {
  124. if(empty($this->ID)) return true;
  125.  
  126. if(is_numeric($this->ID)) return false;
  127.  
  128. return stripos($this->ID, 'new') === 0;
  129. }
  130.  
  131. /**
  132. * checks if records is changed on stage
  133. * @return boolean
  134. */
  135. public function getIsModifiedOnStage() {
  136. // new unsaved fields could be never be published
  137. if($this->isNew()) return false;
  138.  
  139. $stageVersion = Versioned::get_versionnumber_by_stage('EditableFormField', 'Stage', $this->ID);
  140. $liveVersion = Versioned::get_versionnumber_by_stage('EditableFormField', 'Live', $this->ID);
  141.  
  142. return ($stageVersion && $stageVersion != $liveVersion);
  143. }
  144.  
  145.  
  146. /**
  147. * Show this form on load or not
  148. *
  149. * @return bool
  150. */
  151. public function getShowOnLoad() {
  152. return ($this->getSetting('ShowOnLoad') == "Show" || $this->getSetting('ShowOnLoad') == '') ? true : false;
  153. }
  154.  
  155. /**
  156. * To prevent having tables for each fields minor settings we store it as
  157. * a serialized array in the database.
  158. *
  159. * @return Array Return all the Settings
  160. */
  161. public function getSettings() {
  162. return (!empty($this->CustomSettings)) ? unserialize($this->CustomSettings) : array();
  163. }
  164.  
  165. /**
  166. * Set the custom settings for this field as we store the minor details in
  167. * a serialized array in the database
  168. *
  169. * @param Array the custom settings
  170. */
  171. public function setSettings($settings = array()) {
  172. $this->CustomSettings = serialize($settings);
  173. }
  174.  
  175. /**
  176. * Set a given field setting. Appends the option to the settings or overrides
  177. * the existing value
  178. *
  179. * @param String key
  180. * @param String value
  181. */
  182. public function setSetting($key, $value) {
  183. $settings = $this->getSettings();
  184. $settings[$key] = $value;
  185.  
  186. $this->setSettings($settings);
  187. }
  188.  
  189. /**
  190. * Set the allowed css classes for the extraClass custom setting
  191. *
  192. * @param array The permissible CSS classes to add
  193. */
  194. public function setAllowedCss(array $allowed) {
  195. if (is_array($allowed)) {
  196. foreach ($allowed as $k => $v) {
  197. self::$allowed_css[$k] = (!is_null($v)) ? $v : $k;
  198. }
  199. }
  200. }
  201.  
  202. /**
  203. * Return just one custom setting or empty string if it does
  204. * not exist
  205. *
  206. * @param String Value to use as key
  207. * @return String
  208. */
  209. public function getSetting($setting) {
  210. $settings = $this->getSettings();
  211. if(isset($settings) && count($settings) > 0) {
  212. if(isset($settings[$setting])) {
  213. return $settings[$setting];
  214. }
  215. }
  216. return '';
  217. }
  218.  
  219. /**
  220. * Get the path to the icon for this field type, relative to the site root.
  221. *
  222. * @return string
  223. */
  224. public function getIcon() {
  225. return USERFORMS_DIR . '/images/' . strtolower($this->class) . '.png';
  226. }
  227.  
  228. /**
  229. * Return whether or not this field has addable options
  230. * such as a dropdown field or radio set
  231. *
  232. * @return bool
  233. */
  234. public function getHasAddableOptions() {
  235. return false;
  236. }
  237.  
  238. /**
  239. * Return whether or not this field needs to show the extra
  240. * options dropdown list
  241. *
  242. * @return bool
  243. */
  244. public function showExtraOptions() {
  245. return true;
  246. }
  247.  
  248. /**
  249. * Return the custom validation fields for this field for the CMS
  250. *
  251. * @return array
  252. */
  253. public function Dependencies() {
  254. return ($this->CustomRules) ? unserialize($this->CustomRules) : array();
  255. }
  256.  
  257. /**
  258. * Return the custom validation fields for the field
  259. *
  260. * @return DataObjectSet
  261. */
  262. public function CustomRules() {
  263. $output = new ArrayList();
  264. $fields = $this->Parent()->Fields();
  265.  
  266. // check for existing ones
  267. if($rules = $this->Dependencies()) {
  268. foreach($rules as $rule => $data) {
  269. // recreate all the field object to prevent caching
  270. $outputFields = new ArrayList();
  271.  
  272. foreach($fields as $field) {
  273. $new = clone $field;
  274.  
  275. $new->isSelected = ($new->Name == $data['ConditionField']) ? true : false;
  276. $outputFields->push($new);
  277. }
  278.  
  279. $output->push(new ArrayData(array(
  280. 'FieldName' => $this->getFieldName(),
  281. 'Display' => $data['Display'],
  282. 'Fields' => $outputFields,
  283. 'ConditionField' => $data['ConditionField'],
  284. 'ConditionOption' => $data['ConditionOption'],
  285. 'Value' => $data['Value']
  286. )));
  287. }
  288. }
  289.  
  290. return $output;
  291. }
  292.  
  293. /**
  294. * Title field of the field in the backend of the page
  295. *
  296. * @return TextField
  297. */
  298. public function TitleField() {
  299. $label = _t('EditableFormField.ENTERQUESTION', 'Enter Question');
  300.  
  301. $field = new TextField('Title', $label, $this->getField('Title'));
  302. $field->setName($this->getFieldName('Title'));
  303.  
  304. if(!$this->canEdit()) {
  305. return $field->performReadonlyTransformation();
  306. }
  307.  
  308. return $field;
  309. }
  310.  
  311. /** Returns the Title for rendering in the front-end (with XML values escaped) */
  312. public function getTitle() {
  313. return Convert::raw2att($this->getField('Title'));
  314. }
  315.  
  316. /**
  317. * Return the base name for this form field in the
  318. * form builder. Optionally returns the name with the given field
  319. *
  320. * @param String Field Name
  321. *
  322. * @return String
  323. */
  324. public function getFieldName($field = false) {
  325. return ($field) ? "Fields[".$this->ID."][".$field."]" : "Fields[".$this->ID."]";
  326. }
  327.  
  328. /**
  329. * Generate a name for the Setting field
  330. *
  331. * @param String name of the setting
  332. * @return String
  333. */
  334. public function getSettingName($field) {
  335. $name = $this->getFieldName('CustomSettings');
  336.  
  337. return $name . '[' . $field .']';
  338. }
  339.  
  340. /**
  341. * How to save the data submitted in this field into the database object
  342. * which this field represents.
  343. *
  344. * Any class's which call this should also call
  345. * {@link parent::populateFromPostData()} to ensure that this method is
  346. * called
  347. *
  348. * @access public
  349. *
  350. * @param array $data
  351. */
  352. public function populateFromPostData($data) {
  353. $this->Title = (isset($data['Title'])) ? $data['Title']: "";
  354. $this->Default = (isset($data['Default'])) ? $data['Default'] : "";
  355. $this->Sort = (isset($data['Sort'])) ? $data['Sort'] : null;
  356. $this->ContainerFieldID = (isset($data['ContainerFieldID'])) ? $data['ContainerFieldID'] : null;
  357. $this->Required = !empty($data['Required']) ? 1 : 0;
  358. $this->Name = $this->class.$this->ID;
  359. $this->CustomRules = "";
  360. $this->CustomErrorMessage = (isset($data['CustomErrorMessage'])) ? $data['CustomErrorMessage'] : "";
  361. $this->CustomSettings = "";
  362.  
  363. // custom settings
  364. if(isset($data['CustomSettings'])) {
  365. $this->setSettings($data['CustomSettings']);
  366. }
  367.  
  368. // custom validation
  369. if(isset($data['CustomRules'])) {
  370. $rules = array();
  371.  
  372. foreach($data['CustomRules'] as $key => $value) {
  373.  
  374. if(is_array($value)) {
  375. $fieldValue = (isset($value['Value'])) ? $value['Value'] : '';
  376.  
  377. if(isset($value['ConditionOption']) && $value['ConditionOption'] == "Blank" || $value['ConditionOption'] == "NotBlank") {
  378. $fieldValue = "";
  379. }
  380.  
  381. $rules[] = array(
  382. 'Display' => (isset($value['Display'])) ? $value['Display'] : "",
  383. 'ConditionField' => (isset($value['ConditionField'])) ? $value['ConditionField'] : "",
  384. 'ConditionOption' => (isset($value['ConditionOption'])) ? $value['ConditionOption'] : "",
  385. 'Value' => $fieldValue
  386. );
  387. }
  388. }
  389.  
  390. $this->CustomRules = serialize($rules);
  391. }
  392.  
  393. $this->extend('onPopulateFromPostData', $data);
  394. $this->write();
  395. }
  396.  
  397. /**
  398. * Implement custom field Configuration on this field. Includes such things as
  399. * settings and options of a given editable form field
  400. *
  401. * @return FieldSet
  402. */
  403. public function getFieldConfiguration() {
  404. $extraClass = ($this->getSetting('ExtraClass')) ? $this->getSetting('ExtraClass') : '';
  405.  
  406. if (is_array(self::$allowed_css) && !empty(self::$allowed_css)) {
  407. foreach(self::$allowed_css as $k => $v) {
  408. if (!is_array($v)) $cssList[$k]=$v;
  409. elseif ($k == $this->ClassName()) $cssList = array_merge($cssList, $v);
  410. }
  411.  
  412. $ec = new DropdownField(
  413. $this->getSettingName('ExtraClass'),
  414. _t('EditableFormField.EXTRACLASSA', 'Extra Styling/Layout'),
  415. $cssList, $extraClass
  416. );
  417.  
  418. }
  419. else {
  420. $ec = new TextField(
  421. $this->getSettingName('ExtraClass'),
  422. _t('EditableFormField.EXTRACLASSB', 'Extra css Class - separate multiples with a space'),
  423. $extraClass
  424. );
  425. }
  426.  
  427. $right = new TextField(
  428. $this->getSettingName('RightTitle'),
  429. _t('EditableFormField.RIGHTTITLE', 'Right Title'),
  430. $this->getSetting('RightTitle')
  431. );
  432.  
  433. $fields = FieldList::create(
  434. $ec,
  435. $right
  436. );
  437. $this->extend('updateFieldConfiguration', $fields);
  438.  
  439. return $fields;
  440. }
  441.  
  442. /**
  443. * Append custom validation fields to the default 'Validation'
  444. * section in the editable options view
  445. *
  446. * @return FieldSet
  447. */
  448. public function getFieldValidationOptions() {
  449. $fields = new FieldList(
  450. new CheckboxField($this->getFieldName('Required'), _t('EditableFormField.REQUIRED', 'Is this field Required?'), $this->Required),
  451. new TextField($this->getFieldName('CustomErrorMessage'), _t('EditableFormField.CUSTOMERROR','Custom Error Message'), $this->CustomErrorMessage)
  452. );
  453.  
  454. if(!$this->canEdit()) {
  455. foreach($fields as $field) {
  456. $field->performReadonlyTransformation();
  457. }
  458. }
  459.  
  460. $this->extend('updateFieldValidationOptions', $fields);
  461.  
  462. return $fields;
  463. }
  464.  
  465. /**
  466. * Return a FormField to appear on the front end. Implement on
  467. * your subclass
  468. *
  469. * @return FormField
  470. */
  471. public function getFormField() {
  472. user_error("Please implement a getFormField() on your EditableFormClass ". $this->ClassName, E_USER_ERROR);
  473. }
  474.  
  475. /**
  476. * Return the instance of the submission field class
  477. *
  478. * @return SubmittedFormField
  479. */
  480. public function getSubmittedFormField() {
  481. return new SubmittedFormField();
  482. }
  483.  
  484.  
  485. /**
  486. * Show this form field (and its related value) in the reports and in emails.
  487. *
  488. * @return bool
  489. */
  490. public function showInReports() {
  491. return true;
  492. }
  493.  
  494. /**
  495. * Return the validation information related to this field. This is
  496. * interrupted as a JSON object for validate plugin and used in the
  497. * PHP.
  498. *
  499. * @see http://docs.jquery.com/Plugins/Validation/Methods
  500. * @return Array
  501. */
  502. public function getValidation() {
  503. return $this->Required
  504. ? array('required' => true)
  505. : array();
  506. }
  507.  
  508. public function getValidationJSON() {
  509. return Convert::raw2json($this->getValidation());
  510. }
  511.  
  512. /**
  513. * Return the error message for this field. Either uses the custom
  514. * one (if provided) or the default SilverStripe message
  515. *
  516. * @return Varchar
  517. */
  518. public function getErrorMessage() {
  519. $title = strip_tags("'". ($this->Title ? $this->Title : $this->Name) . "'");
  520. $standard = sprintf(_t('Form.FIELDISREQUIRED', '%s is required').'.', $title);
  521.  
  522. // only use CustomErrorMessage if it has a non empty value
  523. $errorMessage = (!empty($this->CustomErrorMessage)) ? $this->CustomErrorMessage : $standard;
  524.  
  525. return DBField::create_field('Varchar', $errorMessage);
  526. }
  527. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement