From 85f47e3623c41565770ce014f978238e53b587c9 Mon Sep 17 00:00:00 2001 From: Christopher Pitt Date: Wed, 12 Aug 2015 08:57:19 +1200 Subject: [PATCH] Added segment field --- code/model/UserDefinedForm.php | 6 +- .../EditableCheckboxGroupField.php | 1 + .../editableformfields/EditableFormField.php | 94 +++++++++++-------- .../DisambiguationSegmentFieldModifier.php | 54 +++++++++++ .../UnderscoreSegmentFieldModifier.php | 27 ++++++ composer.json | 3 +- templates/forms/CheckboxField_holder.ss | 6 ++ templates/forms/CheckboxSetField.ss | 12 +++ templates/forms/FormField_holder.ss | 9 ++ tests/UserDefinedFormControllerTest.php | 9 +- 10 files changed, 173 insertions(+), 48 deletions(-) create mode 100644 code/modifiers/DisambiguationSegmentFieldModifier.php create mode 100644 code/modifiers/UnderscoreSegmentFieldModifier.php create mode 100644 templates/forms/CheckboxField_holder.ss create mode 100644 templates/forms/CheckboxSetField.ss create mode 100644 templates/forms/FormField_holder.ss diff --git a/code/model/UserDefinedForm.php b/code/model/UserDefinedForm.php index 4c6e30b..8f79f54 100755 --- a/code/model/UserDefinedForm.php +++ b/code/model/UserDefinedForm.php @@ -484,7 +484,7 @@ class UserDefinedForm_Controller extends Page_Controller { $watch[$fieldToWatch] = array(); } - $watch[$fieldToWatch][] = array( + $watch[$fieldToWatch][] = array( 'expression' => $expression, 'holder_selector' => $holderSelector, 'view' => $view, @@ -505,7 +505,7 @@ class UserDefinedForm_Controller extends Page_Controller { foreach($values as $rule) { // Register conditional behaviour with an element, so it can be triggered from many places. $logic[] = sprintf( - 'if(%s) { %s.%s(); } else { %2$s.%s(); }', + 'if(%s) { %s.%s(); } else { %2$s.%s(); }', $rule['expression'], $rule['holder_selector'], $rule['view'], @@ -574,7 +574,7 @@ JS } if( - !isset($data[$field->Name]) || + !isset($data[$field->Name]) || !$data[$field->Name] || !$formField->validate($form->getValidator()) ) { diff --git a/code/model/editableformfields/EditableCheckboxGroupField.php b/code/model/editableformfields/EditableCheckboxGroupField.php index bac39f7..4e5bdd2 100755 --- a/code/model/editableformfields/EditableCheckboxGroupField.php +++ b/code/model/editableformfields/EditableCheckboxGroupField.php @@ -15,6 +15,7 @@ class EditableCheckboxGroupField extends EditableMultipleOptionField { public function getFormField() { $field = new UserFormsCheckboxSetField($this->Name, $this->EscapedTitle, $this->getOptionsMap()); + $field->setTemplate('forms/UserFormsCheckboxSetField'); // Set the default checked items $defaultCheckedItems = $this->getDefaultOptions(); diff --git a/code/model/editableformfields/EditableFormField.php b/code/model/editableformfields/EditableFormField.php index e41bf48..b02906c 100755 --- a/code/model/editableformfields/EditableFormField.php +++ b/code/model/editableformfields/EditableFormField.php @@ -1,9 +1,17 @@ readonly = $readonly; } /** - * Returns whether this field is readonly - * + * Returns whether this field is readonly + * * @return bool */ private function isReadonly() { @@ -154,7 +162,11 @@ class EditableFormField extends DataObject { ), TextField::create('Title'), TextField::create('Default', _t('EditableFormField.DEFAULT', 'Default value')), - TextField::create('RightTitle', _t('EditableFormField.RIGHTTITLE', 'Right title')) + TextField::create('RightTitle', _t('EditableFormField.RIGHTTITLE', 'Right title')), + SegmentField::create('Name')->setModifiers(array( + UnderscoreSegmentFieldModifier::create()->setDefault('Field'), + DisambiguationSegmentFieldModifier::create(), + ))->setPreview($this->Name) ) ); @@ -281,20 +293,20 @@ class EditableFormField extends DataObject { // Set a field name. if(!$this->Name) { - $this->Name = $this->RecordClassName . $this->ID; + $this->Name = get_class($this) . '_' . $this->ID; $this->write(); } } - + /** * Flag indicating that this field will set its own error message via data-msg='' attributes - * + * * @return bool */ public function getSetsOwnError() { return false; } - + /** * Return whether a user can delete this form field * based on whether they can edit the page @@ -308,7 +320,7 @@ class EditableFormField extends DataObject { return true; } - + /** * Return whether a user can edit this form field * based on whether they can edit the page @@ -322,10 +334,10 @@ class EditableFormField extends DataObject { return true; } - + /** * Publish this Form Field to the live site - * + * * Wrapper for the {@link Versioned} publish function */ public function doPublish($fromStage, $toStage, $createNewVersion = false) { @@ -336,7 +348,7 @@ class EditableFormField extends DataObject { $rule->doPublish($fromStage, $toStage, $createNewVersion); } } - + /** * Delete this form from a given stage * @@ -350,7 +362,7 @@ class EditableFormField extends DataObject { $rule->deleteFromStage($stage); } } - + /** * checks wether record is new, copied from Sitetree */ @@ -375,7 +387,7 @@ class EditableFormField extends DataObject { return ($stageVersion && $stageVersion != $liveVersion); } - + /** * @deprecated since version 4.0 */ @@ -383,7 +395,7 @@ class EditableFormField extends DataObject { Deprecation::notice('4.0', 'getSettings is deprecated'); return (!empty($this->CustomSettings)) ? unserialize($this->CustomSettings) : array(); } - + /** * @deprecated since version 4.0 */ @@ -391,7 +403,7 @@ class EditableFormField extends DataObject { Deprecation::notice('4.0', 'setSettings is deprecated'); $this->CustomSettings = serialize($settings); } - + /** * @deprecated since version 4.0 */ @@ -399,13 +411,13 @@ class EditableFormField extends DataObject { Deprecation::notice('4.0', "setSetting({$key}) is deprecated"); $settings = $this->getSettings(); $settings[$key] = $value; - + $this->setSettings($settings); } /** * Set the allowed css classes for the extraClass custom setting - * + * * @param array The permissible CSS classes to add */ public function setAllowedCss(array $allowed) { @@ -430,7 +442,7 @@ class EditableFormField extends DataObject { } return ''; } - + /** * Get the path to the icon for this field type, relative to the site root. * @@ -439,7 +451,7 @@ class EditableFormField extends DataObject { public function getIcon() { return USERFORMS_DIR . '/images/' . strtolower($this->class) . '.png'; } - + /** * Return whether or not this field has addable options * such as a dropdown field or radio set @@ -449,11 +461,11 @@ class EditableFormField extends DataObject { public function getHasAddableOptions() { return false; } - + /** * Return whether or not this field needs to show the extra * options dropdown list - * + * * @return bool */ public function showExtraOptions() { @@ -519,21 +531,21 @@ class EditableFormField extends DataObject { Deprecation::notice('4.0', "getFieldName({$field}) is deprecated"); return ($field) ? "Fields[".$this->ID."][".$field."]" : "Fields[".$this->ID."]"; } - + /** * @deprecated since version 4.0 */ public function getSettingName($field) { Deprecation::notice('4.0', "getSettingName({$field}) is deprecated"); $name = $this->getFieldName('CustomSettings'); - + return $name . '[' . $field .']'; } - + /** - * Append custom validation fields to the default 'Validation' + * Append custom validation fields to the default 'Validation' * section in the editable options view - * + * * @return FieldList */ public function getFieldValidationOptions() { @@ -543,12 +555,12 @@ class EditableFormField extends DataObject { ); $this->extend('updateFieldValidationOptions', $fields); - + return $fields; } - + /** - * Return a FormField to appear on the front end. Implement on + * Return a FormField to appear on the front end. Implement on * your subclass. * * @return FormField @@ -596,13 +608,13 @@ class EditableFormField extends DataObject { $field->setTitle($title); } } - + // if this field has an extra class if($this->ExtraClass) { $field->addExtraClass($this->ExtraClass); } } - + /** * Return the instance of the submission field class * @@ -611,8 +623,8 @@ class EditableFormField extends DataObject { public function getSubmittedFormField() { return new SubmittedFormField(); } - - + + /** * Show this form field (and its related value) in the reports and in emails. * @@ -631,10 +643,10 @@ class EditableFormField extends DataObject { public function getErrorMessage() { $title = strip_tags("'". ($this->Title ? $this->Title : $this->Name) . "'"); $standard = sprintf(_t('Form.FIELDISREQUIRED', '%s is required').'.', $title); - + // only use CustomErrorMessage if it has a non empty value $errorMessage = (!empty($this->CustomErrorMessage)) ? $this->CustomErrorMessage : $standard; - + return DBField::create_field('Varchar', $errorMessage); } @@ -655,7 +667,7 @@ class EditableFormField extends DataObject { } if( - !isset($data[$this->Name]) || + !isset($data[$this->Name]) || !$data[$this->Name] || !$formField->validate($form->getValidator()) ) { @@ -678,7 +690,7 @@ class EditableFormField extends DataObject { $this->ShowOnLoad = $data['ShowOnLoad'] === '' || ($data['ShowOnLoad'] && $data['ShowOnLoad'] !== 'Hide'); unset($data['ShowOnLoad']); } - + // Migrate all other settings foreach($data as $key => $value) { if($this->hasField($key)) { diff --git a/code/modifiers/DisambiguationSegmentFieldModifier.php b/code/modifiers/DisambiguationSegmentFieldModifier.php new file mode 100644 index 0000000..862f629 --- /dev/null +++ b/code/modifiers/DisambiguationSegmentFieldModifier.php @@ -0,0 +1,54 @@ +form instanceof Form && $record = $this->form->getRecord()) { + $parent = $record->Parent(); + + $try = $value; + + $sibling = EditableformField::get() + ->filter('ParentID', $parent->ID) + ->filter('Name', $try) + ->where('"ID" != ' . $record->ID) + ->first(); + + $counter = 1; + + while($sibling !== null) { + $try = $value . '_' . $counter++; + + $sibling = EditableformField::get() + ->filter('ParentID', $parent->ID) + ->filter('Name', $try) + ->first(); + } + + if ($try !== $value) { + return $try; + } + } + + return $value; + } + + /** + * @inheritdoc + * + * @param string $value + * + * @return string + */ + public function getSuggestion($value) { + return $this->getPreview($value); + } +} diff --git a/code/modifiers/UnderscoreSegmentFieldModifier.php b/code/modifiers/UnderscoreSegmentFieldModifier.php new file mode 100644 index 0000000..cbdae2d --- /dev/null +++ b/code/modifiers/UnderscoreSegmentFieldModifier.php @@ -0,0 +1,27 @@ +=3.1.0", "silverstripe/cms": ">=3.1.0", - "silverstripe-australia/gridfieldextensions": "1.1.0" + "silverstripe-australia/gridfieldextensions": "1.1.0", + "silverstripe/segment-field": "^1.0" }, "suggest": { "colymba/gridfield-bulk-editing-tools": "Allows for bulk management of form submissions" diff --git a/templates/forms/CheckboxField_holder.ss b/templates/forms/CheckboxField_holder.ss new file mode 100644 index 0000000..021a6b5 --- /dev/null +++ b/templates/forms/CheckboxField_holder.ss @@ -0,0 +1,6 @@ +
+ $Field + + <% if $Message %>$Message<% end_if %> + <% if $Description %>$Description<% end_if %> +
diff --git a/templates/forms/CheckboxSetField.ss b/templates/forms/CheckboxSetField.ss new file mode 100644 index 0000000..f9fb8e8 --- /dev/null +++ b/templates/forms/CheckboxSetField.ss @@ -0,0 +1,12 @@ + diff --git a/templates/forms/FormField_holder.ss b/templates/forms/FormField_holder.ss new file mode 100644 index 0000000..811c16c --- /dev/null +++ b/templates/forms/FormField_holder.ss @@ -0,0 +1,9 @@ +
+ <% if $Title %><% end_if %> +
+ $Field +
+ <% if $RightTitle %><% end_if %> + <% if $Message %>$Message<% end_if %> + <% if $Description %>$Description<% end_if %> +
diff --git a/tests/UserDefinedFormControllerTest.php b/tests/UserDefinedFormControllerTest.php index 02bdc51..33f53dc 100644 --- a/tests/UserDefinedFormControllerTest.php +++ b/tests/UserDefinedFormControllerTest.php @@ -15,10 +15,13 @@ class UserDefinedFormControllerTest extends FunctionalTest { $this->autoFollowRedirection = false; $this->clearEmails(); - + // load the form - $this->get($form->URLSegment); - $response = $this->submitForm('UserForm_Form', null, array('basic-text-name' => 'Basic Value')); + $this->get($form->URLSegment); + + $field = $this->objFromFixture('EditableTextField', 'basic-text'); + + $response = $this->submitForm('UserForm_Form', null, array($field->Name => 'Basic Value')); // should have a submitted form field now $submitted = DataObject::get('SubmittedFormField', "\"Name\" = 'basic-text-name'");