diff --git a/code/UserDefinedForm.php b/code/UserDefinedForm.php index 2b43137..07d5c93 100755 --- a/code/UserDefinedForm.php +++ b/code/UserDefinedForm.php @@ -19,7 +19,7 @@ class UserDefinedForm extends Page { /** * @var String What level permission is needed to edit / add */ - static $need_permission = 'ADMIN'; + static $need_permission = array('ADMIN'); /** * @var String Required Identifier @@ -68,10 +68,11 @@ class UserDefinedForm extends Page { // define tabs $fields->findOrMakeTab('Root.Content.Form', _t('UserDefinedForm.FORM', 'Form')); + $fields->findOrMakeTab('Root.Content.Options', _t('UserDefinedForm.OPTIONS', 'Options')); $fields->findOrMakeTab('Root.Content.EmailRecipients', _t('UserDefinedForm.EMAILRECIPIENTS', 'Email Recipients')); $fields->findOrMakeTab('Root.Content.OnComplete', _t('UserDefinedForm.ONCOMPLETE', 'On Complete')); $fields->findOrMakeTab('Root.Content.Submissions', _t('UserDefinedForm.SUBMISSIONS', 'Submissions')); - + // field editor $fields->addFieldToTab("Root.Content.Form", new FieldEditor("Fields", 'Fields', "", $this )); @@ -102,6 +103,7 @@ class UserDefinedForm extends Page { ); $fields->addFieldsToTab("Root.Content.OnComplete", $onCompleteFieldSet); + $fields->addFieldsToTab("Root.Content.Options", $this->getFormOptions()); return $fields; } @@ -155,19 +157,61 @@ class UserDefinedForm extends Page { } /** - * Roll back a form to a previous version + * Roll back a form to a previous version. * * @param String|int Version to roll back to */ public function doRollbackTo($version) { - if($this->Fields()) { - foreach($this->Fields() as $field) { - $field->publish($version, "Stage", true); - $field->writeWithoutVersion(); - } - } - parent::doRollbackTo($version); + + /* + Not implemented yet + + // get the older version + $reverted = Versioned::get_version($this->ClassName, $this->ID, $version); + + if($reverted) { + + // using the lastedited date of the reverted object we can work out which + // form fields to revert back to + if($this->Fields()) { + foreach($this->Fields() as $field) { + // query to see when the version of the page was pumped + $editedDate = DB::query(" + SELECT LastEdited + FROM \"SiteTree_versions\" + WHERE \"RecordID\" = '$this->ID' AND \"Version\" = $version + ")->value(); + + + // find a the latest version which has been edited + $versionToGet = DB::query(" + SELECT * + FROM \"EditableFormField_versions\" + WHERE \"RecordID\" = '$field->ID' AND \"LastEdited\" <= '$editedDate' + ORDER BY Version DESC + LIMIT 1 + ")->record(); + + if($versionToGet) { + Debug::show('publishing field'. $field->Name); + Debug::show($versionToGet); + $field->publish($versionToGet, "Stage", true); + $field->writeWithoutVersion(); + } + else { + Debug::show('deleting field'. $field->Name); + $this->Fields()->remove($field); + + $field->delete(); + $field->destroy(); + } + } + } + + // @todo Emails + } + */ } /** @@ -178,7 +222,8 @@ class UserDefinedForm extends Page { public function doRevertToLive() { if($this->Fields()) { foreach($this->Fields() as $field) { - $field->writeToStage('Live', 'Stage'); + $field->publish("Live", "Stage", false); + $field->writeWithoutVersion(); } } @@ -216,16 +261,22 @@ class UserDefinedForm extends Page { } /** - * Custom Form Actions for the form + * Custom options for the form. You can extend the built in options by + * using {@link updateFormOptions()} * - * @param bool Is the Form readonly * @return FieldSet */ - public function customFormActions($isReadonly = false) { - return new FieldSet( - new TextField("SubmitButtonText", _t('UserDefinedForm.TEXTONSUBMIT', 'Text on submit button:'), $this->SubmitButtonText), + public function getFormOptions() { + $submit = ($this->SubmitButtonText) ? $this->SubmitButtonText : _t('UserDefinedForm.SUBMITBUTTON', 'Submit'); + + $options = new FieldSet( + new TextField("SubmitButtonText", _t('UserDefinedForm.TEXTONSUBMIT', 'Text on submit button:'), $submit), new CheckboxField("ShowClearButton", _t('UserDefinedForm.SHOWCLEARFORM', 'Show Clear Form Button'), $this->ShowClearButton) ); + + $this->extend('updateFormOptions', $options); + + return $options; } /** @@ -283,72 +334,171 @@ class UserDefinedForm_Controller extends Page_Controller { ); } } - + return array( 'Content' => DBField::create('HTMLText', $this->Content), - 'Form' => $this->Form + 'Form' => $this->Form() ); } /** - * User Defined Form. Feature of the user defined form is if you want the - * form to appear in a custom location on the page you can use $UserDefinedForm - * in the content area to describe where you want the form + * Get the form for the page. Form can be modified by calling {@link updateForm()} + * on a UserDefinedForm extension * - * @todo Abstract the Conditional Logic from the Form. This should be tied - * to the EditableFormField class so that fields (eg checkboxes) - * can define their own logic - * * @return Form */ - public function Form() { - $fields = new FieldSet(); - $fieldValidation = array(); - $fieldValidationRules = array(); - $customDisplayRules = ""; - $defaults = ""; - $this->SubmitButtonText = ($this->SubmitButtonText) ? $this->SubmitButtonText : _t('UserDefinedForm.SUBMITBUTTON', 'Submit'); + function Form() { + $fields = $this->getFormFields(); + $actions = $this->getFormActions(); + // get the required fields including the validation + $required = $this->getRequiredFields(); + + // generate the conditional logic + $this->generateConditionalJavascript(); + + $form = new Form($this, "Form", $fields, $actions, $required); + + $this->extend('updateForm', $form); + + return $form; + } + + /** + * Get the form fields for the form on this page. Can modify this FieldSet + * by using {@link updateFormFields()} on an {@link Extension} subclass which + * is applied to this controller + * + * @return FieldSet + */ + function getFormFields() { + $fields = new FieldSet(); + if($this->Fields()) { - foreach($this->Fields() as $field) { - - $fieldToAdd = $field->getFormField(); + foreach($this->Fields() as $editableField) { + // get the raw form field from the editable version + $field = $editableField->getFormField(); + if(!$field) break; - if(!$fieldToAdd) break; + // set the error / formatting messages + $title = strip_tags("'". ($editableField->Title ? $editableField->Title : $editableField->Name) . "'"); - $fieldValidationOptions = array(); + $errorMessage = sprintf(_t('Form.FIELDISREQUIRED', '%s is required').'.', $title); + $errorMessage = ($editableField->CustomErrorMessage) ? $editableField->CustomErrorMessage : $errorMessage; - // Set the Error Messages - $errorMessage = sprintf(_t('Form.FIELDISREQUIRED', '%s is required').'.', strip_tags("'". ($field->Title ? $field->Title : $field->Name) . "'")); - $errorMessage = ($field->CustomErrorMessage) ? $field->CustomErrorMessage : $errorMessage; - $fieldToAdd->setCustomValidationMessage($errorMessage); + $field->setCustomValidationMessage($errorMessage); - // Set the right title on this field - if($right = $field->getSetting('RightTitle')) { - $fieldToAdd->setRightTitle($right); + // set the right title on this field + if($right = $editableField->getSetting('RightTitle')) { + $field->setRightTitle($right); } - // Is this field required - if($field->Required) { - $fieldValidation[$field->Name] = $errorMessage; - $fieldValidationOptions['required'] = true; - $fieldToAdd->addExtraClass('requiredField'); - if(UserDefinedForm::$required_identifier) { - $title = $fieldToAdd->Title() ." ". UserDefinedForm::$required_identifier . ""; - $fieldToAdd->setTitle($title); + // if this field is required add some + if($editableField->Required) { + $field->addExtraClass('requiredField'); + + if($identifier = UserDefinedForm::$required_identifier) { + + $title = $field->Title() ." ". $identifier . ""; + $field->setTitle($title); } } - // Add field to the form - $fields->push($fieldToAdd); - - // Ask our form field for some more information on hour it should be validated - $fieldValidationOptions = array_merge($fieldValidationOptions, $field->getValidation()); - - // Check if we have need to update the global validation - if($fieldValidationOptions) { - $fieldValidationRules[$field->Name] = $fieldValidationOptions; + $fields->push($field); + } + } + + $this->extend('updateFormFields', $fields); + + return $fields; + } + + /** + * Generate the form actions for the UserDefinedForm. You + * can manipulate these by using {@link updateFormActions()} on + * a decorator. + * + * @todo Make form actions editable via their own field editor. + * + * @return FieldSet + */ + function getFormActions() { + $submitText = ($this->SubmitButtonText) ? $this->SubmitButtonText : _t('UserDefinedForm.SUBMITBUTTON', 'Submit'); + + $actions = new FieldSet( + new FormAction("process", $submitText) + ); + + if($this->ShowClearButton) { + $actions->push(new ResetFormAction("clearForm")); + } + + $this->extend('updateFormActions', $actions); + + return $actions; + } + + /** + * Get the required form fields for this form. Includes building the jQuery + * validate structure + * + * @return RequiredFields + */ + function getRequiredFields() { + $required = new RequiredFields(); + + $rules = array(); + $validation = array(); + + if($this->Fields()) { + foreach($this->Fields() as $field) { + if($field->Required) { + + $validation[$field->Name] = $field->getFormField()->getCustomValidationMessage(); + $rules[$field->Name] = array_merge(array('required'), $field->getValidation()); + + $required->addRequiredField($field->Name); } + } + } + + // Set the Form Name + $rules = $this->array2json($rules); + $messages = $this->array2json($validation); + + // set the custom script for this form + Requirements::customScript(<<extend('updateRequiredFields', $required); + + return $required; + } + + /** + * Generate the javascript for the conditional field show / hiding logic. + * Allows complex rules to be created + * @return void + */ + function generateConditionalJavascript() { + $default = ""; + $rules = ""; + + if($this->Fields()) { + foreach($this->Fields() as $field) { $fieldId = $field->Name; if($field->ClassName == 'EditableFormHeading') { @@ -356,8 +506,8 @@ class UserDefinedForm_Controller extends Page_Controller { } // Is this Field Show by Default - if(!$field->ShowOnLoad) { - $defaults .= "$(\"#" . $fieldId . "\").hide();\n"; + if(!$field->getShowOnLoad()) { + $default .= "$(\"#" . $fieldId . "\").hide();\n"; } // Check for field dependencies / default @@ -438,7 +588,7 @@ class UserDefinedForm_Controller extends Page_Controller { break; } // put it all together - $customDisplayRules .= $fieldToWatch.".$action(function() { + $rules .= $fieldToWatch.".$action(function() { if(". $expression ." ) { $(\"#". $fieldId ."\").".$view."(); } @@ -451,53 +601,18 @@ class UserDefinedForm_Controller extends Page_Controller { } } } - $referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ''; - // Keep track of the referer - $fields->push( new HiddenField( "Referrer", "", $referer ) ); - - // Build actions - $actions = new FieldSet( - new FormAction("process", $this->SubmitButtonText) - ); - - // Do we want to add a clear form. - if($this->ShowClearButton) { - $actions->push(new ResetFormAction("clearForm")); - } - - // return the form - $form = new Form($this, "Form", $fields, $actions, new RequiredFields(array_keys($fieldValidation))); - $form->loadDataFrom($this->failover); - - $FormName = $form->FormName(); - - // Set the Form Name - $rules = $this->array2json($fieldValidationRules); - $messages = $this->array2json($fieldValidation); - - - // set the custom script for this form Requirements::customScript(<< $value) if(is_array( $value )) { $result[] = "$key:" . $this->array2json($value); } else { $value = (is_bool($value)) ? $value : "\"$value\""; - $result[] = "$key:$value \n"; + $result[] = "$key:$value"; } - return (isset($result)) ? "{\n".implode( ', ', $result ) ."} \n": '{}'; + return (isset($result)) ? "{\n".implode( ', ', $result ) ."\n}\n": '{}'; } /** @@ -526,30 +641,30 @@ JS * @return Redirection */ function process($data, $form) { - // submitted form object - $submittedForm = new SubmittedForm(); + + $submittedForm = Object::create('SubmittedForm'); $submittedForm->SubmittedByID = ($id = Member::currentUserID()) ? $id : 0; $submittedForm->ParentID = $this->ID; - $submittedForm->Recipient = $this->EmailTo; + + // if saving is not disabled save now to generate the ID if(!$this->DisableSaveSubmissions) $submittedForm->write(); - // email values $values = array(); - $recipientAddresses = array(); - $sendCopy = false; $attachments = array(); $submittedFields = new DataObjectSet(); foreach($this->Fields() as $field) { - // don't show fields that shouldn't be shown + if(!$field->showInReports()) continue; + // create a new submitted form field. $submittedField = $field->getSubmittedFormField(); $submittedField->ParentID = $submittedForm->ID; $submittedField->Name = $field->Name; $submittedField->Title = $field->Title; - + + // save the value from the data if($field->hasMethod('getValueFromData')) { $submittedField->Value = $field->getValueFromData($data); } @@ -564,34 +679,38 @@ JS // create the file from post data $upload = new Upload(); $file = new File(); + $upload->loadIntoFile($_FILES[$field->Name], $file); // write file to form field $submittedField->UploadedFileID = $file->ID; - // Attach the file if its less than 1MB, provide a link if its over. + // attach a file only if lower than 1MB if($file->getAbsoluteSize() < 1024*1024*1){ $attachments[] = $file; } } } } + if(!$this->DisableSaveSubmissions) $submittedField->write(); $submittedFields->push($submittedField); - } + } + $emailData = array( "Sender" => Member::currentUser(), "Fields" => $submittedFields ); - // email users on submit. All have their own custom options. + // email users on submit. if($this->EmailRecipients()) { + $email = new UserDefinedForm_SubmittedFormEmail($submittedFields); $email->populateTemplate($emailData); + if($attachments){ foreach($attachments as $file){ - // bug with double decorated fields, valid ones should have an ID. if($file->ID != 0) { $email->attachFile($file->Filename,$file->Filename, $file->getFileType()); } @@ -637,8 +756,10 @@ JS } } } - - return Director::redirect($this->Link() . 'finished?referrer=' . urlencode($data['Referrer'])); + + $referrer = (isset($data['Referrer'])) ? '?referrer=' . urlencode($data['Referrer']) : ""; + + return Director::redirect($this->Link() . 'finished' . $referrer); } /** @@ -656,7 +777,7 @@ JS array( 'Link' => $referrer ))->renderWith('ReceivedFormSubmission'), - 'Form' => ' ', + 'Form' => '', )); } } diff --git a/code/editor/EditableDropdown.php b/code/editor/EditableDropdown.php index 33a406f..b0b0cb8 100755 --- a/code/editor/EditableDropdown.php +++ b/code/editor/EditableDropdown.php @@ -2,7 +2,7 @@ /** * EditableDropdown * - * Represents a modifiable dropdown box on a form + * Represents a modifiable dropdown (select) box on a form * * @package userforms */ @@ -12,17 +12,21 @@ class EditableDropdown extends EditableMultipleOptionField { static $singular_name = 'Dropdown Field'; static $plural_name = 'Dropdowns'; - - function getFormField($asFilter = false) { + /** + * @return DropdownField + */ + function getFormField() { + $optionSet = $this->Options(); $options = array(); + if($optionSet) { - foreach( $optionSet as $option ) { + foreach($optionSet as $option) { $options[$option->Title] = $option->Title; } } - return new DropdownField( $this->Name, $this->Title, $options); + + return new DropdownField($this->Name, $this->Title, $options); } - } \ No newline at end of file diff --git a/code/editor/EditableFormField.php b/code/editor/EditableFormField.php index 4c3c8df..9d9acfd 100755 --- a/code/editor/EditableFormField.php +++ b/code/editor/EditableFormField.php @@ -29,34 +29,39 @@ class EditableFormField extends DataObject { static $extensions = array( "Versioned('Stage', 'Live')" ); - + + /** + * @var bool + */ protected $readonly; - /** - * Set this formfield to readonly - */ - public function setReadonly() { - $this->readonly = true; + * Set the visibility of an individual form field + * + * @param bool + */ + public function setReadonly($readonly = true) { + $this->readonly = $readonly; } /** - * Is this field readonly to the user - * + * Returns whether this field is readonly + * * @return bool */ - public function isReadonly() { + private function isReadonly() { return $this->readonly; } + /** + * Template to render the form field into + * + * @return String + */ function EditSegment() { return $this->renderWith('EditableFormField'); } - function ClassName() { - return $this->class; - } - /** * Return whether a user can delete this form field * based on whether they can edit the page @@ -64,7 +69,7 @@ class EditableFormField extends DataObject { * @return bool */ public function canDelete() { - return $this->Parent()->canEdit(); + return ($this->Parent()->canEdit() && !$this->isReadonly()); } /** @@ -74,7 +79,7 @@ class EditableFormField extends DataObject { * @return bool */ public function canEdit() { - return $this->Parent()->canEdit(); + return ($this->Parent()->canEdit() && !$this->isReadonly()); } /** @@ -125,6 +130,20 @@ class EditableFormField extends DataObject { $this->CustomSettings = serialize($settings); } + /** + * Set a given field setting. Appends the option to the settings or overrides + * the existing value + * + * @param String key + * @param String value + */ + public function setFieldSetting($key, $value) { + $settings = $this->getFieldSettings(); + $settings[$key] = $value; + + $this->setFieldSettings($settings); + } + /** * Return just one custom setting or empty string if it does * not exist @@ -147,7 +166,7 @@ class EditableFormField extends DataObject { * * @return string */ - public function Icon() { + public function getIcon() { return 'userforms/images/' . strtolower($this->class) . '.png'; } @@ -217,11 +236,21 @@ class EditableFormField extends DataObject { return $output; } + /** + * Title field of the field in the backend of the page + * + * @return TextField + */ function TitleField() { $titleAttr = Convert::raw2att($this->Title); $readOnlyAttr = (!$this->canEdit()) ? ' disabled="disabled"' : ''; - return "ID}][Title]\"$readOnlyAttr />"; + $field = new TextField('Title', _t('EditableFormField.ENTERQUESTION', 'Enter Question'), $this->Title); + $field->setName($this->getFieldName('Title')); + + if(!$this->canEdit()) $field->setReadonly(true); + + return $field; } /** diff --git a/code/editor/EditableTextField.php b/code/editor/EditableTextField.php index f33b88b..91bf652 100755 --- a/code/editor/EditableTextField.php +++ b/code/editor/EditableTextField.php @@ -35,6 +35,9 @@ class EditableTextField extends EditableFormField { return $fields; } + /** + * @return TextareaField|TextField + */ function getFormField() { if($this->getSetting('Rows') && $this->getSetting('Rows') > 1) { return new TextareaField($this->Name, $this->Title, $this->getSetting('Rows')); diff --git a/code/editor/FieldEditor.php b/code/editor/FieldEditor.php index 45eb8d6..8f1fa0d 100755 --- a/code/editor/FieldEditor.php +++ b/code/editor/FieldEditor.php @@ -1,36 +1,51 @@ renderWith("FieldEditor"); } /** - * Can a user edit this field? + * Returns whether a user can edit the form + * * @return boolean */ public function canEdit() { if($this->readonly) return false; + return $this->form->getRecord()->canEdit(); } /** - * Can a user delete this field? + * Returns whether a user delete a field in the form. The {@link EditableFormField}s + * check if they can delete themselves but this counts as an {@link self::canEdit()} + * function rather than a delete + * * @return boolean */ public function canDelete() { if($this->readonly) return false; - return $this->form->getRecord()->canDelete(); + + return $this->form->getRecord()->canEdit(); } + /** + * Transform this form field to a readonly version. + * + * @return ViewableData_Customised + */ function performReadonlyTransformation() { $clone = clone $this; $clone->readonly = true; @@ -43,15 +58,11 @@ class FieldEditor extends FormField { } /** - * Return the Form Fields for the user forms + * Return the fields for the user forms * * @return DataObjectSet */ function Fields() { - Requirements::css("userforms/css/FieldEditor.css"); - Requirements::javascript(SAPPHIRE_DIR ."/thirdparty/jquery-ui/jquery-ui-1.8rc3.custom.js"); - Requirements::javascript("userforms/javascript/UserForm.js"); - // Don't return any fields unless we actually have the dependent parameters set on the form field if($this->form && $this->form->getRecord() && $this->name) { $relationName = $this->name; @@ -67,6 +78,7 @@ class FieldEditor extends FormField { } } } + return $fields; } } @@ -160,10 +172,6 @@ class FieldEditor extends FormField { if($record->hasMethod('customFormSave')) { $record->customFormSave($_REQUEST[$name], $record); - } - - if($record->hasMethod('processNewFormFields')) { - $record->processNewFormFields(); } } @@ -230,28 +238,4 @@ class FieldEditor extends FormField { } return false; } - - function setHasFormOptions($bool){ - $this->hasFormOptions = $bool; - } - - function hasFormOptions(){ - return $this->hasFormOptions; - } - - function FormOptions() { - if($this->hasFormOptions()){ - if($this->form->getRecord()->hasMethod('customFormActions')) { - $newFields = $this->form->getRecord()->customFormActions($this->readonly); - - foreach($newFields as $newField) { - $newField->setName("{$this->name}[{$newField->Name()}]" ); - } - if($this->readonly) { - $newFields = $newFields->makeReadonly(); - } - return $newFields; - } - } - } } \ No newline at end of file diff --git a/code/submissions/SubmittedForm.php b/code/submissions/SubmittedForm.php index 069d0aa..9454192 100755 --- a/code/submissions/SubmittedForm.php +++ b/code/submissions/SubmittedForm.php @@ -6,6 +6,7 @@ */ class SubmittedForm extends DataObject { + static $has_one = array( "SubmittedBy" => "Member", "Parent" => "UserDefinedForm", diff --git a/code/submissions/SubmittedFormReportField.php b/code/submissions/SubmittedFormReportField.php index 730f66d..73b1e0b 100755 --- a/code/submissions/SubmittedFormReportField.php +++ b/code/submissions/SubmittedFormReportField.php @@ -69,93 +69,7 @@ class SubmittedFormReportField extends FormField { // Get the UserDefinedForm to export data from the URL $SQL_ID = (isset($_REQUEST['id'])) ? Convert::raw2sql($_REQUEST['id']) : false; - if($SQL_ID) { - $udf = DataObject::get_by_id("UserDefinedForm", $SQL_ID); - if($udf) { - $submissions = $udf->Submissions(); - if($submissions && $submissions->Count() > 0) { - - // Get all the submission IDs (so we know what names/titles to get - helps for sites with many UDF's) - $inClause = array(); - foreach($submissions as $submission) { - $inClause[] = $submission->ID; - } - - // Get the CSV header rows from the database - - $tmp = DB::query("SELECT DISTINCT \"SubmittedFormField\".\"ID\", \"Name\", \"Title\" - FROM \"SubmittedFormField\" - LEFT JOIN \"SubmittedForm\" ON \"SubmittedForm\".\"ID\" = \"SubmittedFormField\".\"ParentID\" - WHERE \"SubmittedFormField\".\"ParentID\" IN (" . implode(',', $inClause) . ") - GROUP BY \"Name\" - ORDER BY \"SubmittedFormField\".\"ID\""); - - // Sort the Names and Titles from the database query into separate keyed arrays - foreach($tmp as $array) { - $csvHeaderNames[] = $array['Name']; - $csvHeaderTitle[] = $array['Title']; - - } - - // For every submission... - $i = 0; - foreach($submissions as $submission) { - - // Get the rows for this submission (One row = one form field) - $dataRow = $submission->FieldValues(); - $rows[$i] = array(); - - // For every row/field, get all the columns - foreach($dataRow as $column) { - - // If the Name of this field is in the $csvHeaderNames array, get an array of all the places it exists - if($index = array_keys($csvHeaderNames, $column->Name)) { - if(is_array($index)) { - - // Set the final output array for each index that we want to insert this value into - foreach($index as $idx) { - $rows[$i][$idx] = $column->Value; - } - $rows[$i]['Submitted'] = $submission->Created; - } - } - } - - $i++; - } - // CSV header row - $csvData = '"' . implode('","', $csvHeaderTitle) . '"' . ',"Submitted"'."\n"; - - // For every row of data (one form submission = one row) - foreach($rows as $row) { - // Loop over all the names we can use - for($i=0;$ioutput(); - } else { - HTTPRequest::send_file($csvData, $fileName)->output(); - } - - } else { - user_error("'$SQL_ID' is a valid type, but we can't find a UserDefinedForm in the database that matches the ID.", E_USER_ERROR); - } - } else { - user_error("'$SQL_ID' is not a valid UserDefinedForm ID.", E_USER_ERROR); - } + return $this->generateExport($SQL_ID); } /** diff --git a/javascript/UserForm.js b/javascript/UserForm.js index 8eea6ca..24734d5 100644 --- a/javascript/UserForm.js +++ b/javascript/UserForm.js @@ -6,6 +6,10 @@ (function($) { $(document).ready(function() { + /** + * Update the Field sortable + */ + update_sortable(); /** * Update the sortable properties of the form as a function @@ -75,11 +79,6 @@ /*-------------------- FIELD EDITOR ----------------------- */ - /** - * Update the Field sortable - */ - update_sortable(); - /** * Create a new instance of a field in the current form * area. the type information should all be on this object diff --git a/templates/EditableFormField.ss b/templates/EditableFormField.ss index d70cdf7..1172cfd 100755 --- a/templates/EditableFormField.ss +++ b/templates/EditableFormField.ss @@ -1,10 +1,10 @@
  • - <% if isReadonly %> - <% _t('LOCKED', 'These fields cannot be modified') %> - <% else %> + <% if canEdit %> <% _t('DRAG', 'Drag to rearrange order of fields') %> + <% else %> + <% _t('LOCKED', 'These fields cannot be modified') %> <% end_if %> $ClassName diff --git a/templates/EditableOption.ss b/templates/EditableOption.ss index 0e00e33..6496179 100644 --- a/templates/EditableOption.ss +++ b/templates/EditableOption.ss @@ -3,9 +3,9 @@ - <% if isReadonly %> - <% _t('LOCKED', 'These fields cannot be modified') %> - <% else %> + <% if canEdit %> <% _t('DELETE', 'Remove this option') %> + <% else %> + <% _t('LOCKED', 'These fields cannot be modified') %> <% end_if %>
  • \ No newline at end of file diff --git a/templates/FieldEditor.ss b/templates/FieldEditor.ss index b3a6b68..633fe18 100755 --- a/templates/FieldEditor.ss +++ b/templates/FieldEditor.ss @@ -1,4 +1,8 @@ -
    +<% require css(userforms/css/FieldEditor.css) %> +<% require javascript(sapphire/thirdparty/jquery-ui/jquery-ui-1.8rc3.custom.js) %> +<% require javascript(userforms/javascript/UserForm.js) %> + +
      @@ -8,12 +12,19 @@
    - <% include AddField %> - -
    -

    Form Options

    - <% control FormOptions %> - $FieldHolder - <% end_control %> -
    + <% if canEdit %> + + <% end_if %>
    \ No newline at end of file diff --git a/templates/Includes/AddField.ss b/templates/Includes/AddField.ss deleted file mode 100644 index 63efc95..0000000 --- a/templates/Includes/AddField.ss +++ /dev/null @@ -1,14 +0,0 @@ -<% if canEdit %> - -<% end_if %> \ No newline at end of file diff --git a/tests/EditableFormFieldTest.php b/tests/EditableFormFieldTest.php new file mode 100644 index 0000000..b088e81 --- /dev/null +++ b/tests/EditableFormFieldTest.php @@ -0,0 +1,45 @@ +objFromFixture('EditableDropdown', 'basic-dropdown'); + + $option1 = $this->objFromFixture('EditableOption', 'option-1'); + $option2 = $this->objFromFixture('EditableOption', 'option-2'); + + $dropdown->Options()->add($option1); + $dropdown->Options()->add($option2); + + $field = $dropdown->getFormField(); + + + $this->assertThat($field, $this->isInstanceOf('DropdownField')); + $values = $field->getSource(); + + $this->assertEquals(array('Option 1' => 'Option 1', 'Option 2' => 'Option 2'), $values); + } + + function testEditableRadioField() { + $radio = $this->objFromFixture('EditableRadioField', 'radio-field'); + + $option1 = $this->objFromFixture('EditableOption', 'option-1'); + $option2 = $this->objFromFixture('EditableOption', 'option-2'); + + $radio->Options()->add($option1); + $radio->Options()->add($option2); + + $field = $radio->getFormField(); + + $this->assertThat($field, $this->isInstanceOf('OptionsetField')); + $values = $field->getSource(); + + $this->assertEquals(array('Option 1' => 'Option 1', 'Option 2' => 'Option 2'), $values); + } +} \ No newline at end of file diff --git a/tests/EditableFormFields.yml b/tests/EditableFormFields.yml new file mode 100644 index 0000000..3c2ce44 --- /dev/null +++ b/tests/EditableFormFields.yml @@ -0,0 +1,62 @@ +EditableOption: + option-1: + Name: Option1 + Title: Option 1 + Sort: 1 + + option-2: + Name: Option2 + Title: Option 2 + Sort: 2 + + department-1: + Name: dept1 + Title: sales@example.com + + department-2: + Name: dept2 + Title: accounts@example.com + +EditableTextField: + basic-text: + Name: basic-text-name + Title: Basic Text Field + + required-text: + Name: required-text-field + Title: Required Text Field + CustomErrorMessage: Custom Error Message + RightTitle: Right Title + Required: true + +EditableRadioField: + radio-field: + Name: radio-option + Title: Radio Option + +EditableDropdown: + basic-dropdown: + Name: basic-dropdown + Title: Basic Dropdown Field + Options: =>EditableOption.option-1, =>EditableOption.option-2 + + department-dropdown: + Name: department + Title: Department + Options: =>EditableOption.department-1, =>EditableOption.department-2 + +EditableCheckbox: + checkbox-1: + Name: checkbox-1 + Title: Checkbox 1 + +EditableEmailField: + email-field: + Name: email-field + Title: Email + +EditableCheckboxGroupField: + checkbox-group: + Name: check-box-group + Title: Check box group + Options: =>EditableOption.option-1, =>EditableOption.option-2 \ No newline at end of file diff --git a/tests/FieldEditorTest.php b/tests/FieldEditorTest.php new file mode 100644 index 0000000..515650e --- /dev/null +++ b/tests/FieldEditorTest.php @@ -0,0 +1,37 @@ +objFromFixture('SubmittedFormField', 'submitted-form-field-1'); + $form = $field->Parent(); + + $this->assertEquals($form->FieldValues()->Count(), 2); + $form->delete(); + + $fields = DataObject::get('SubmittedFormField', "ParentID = '$form->ID'"); + + $this->assertNull($fields); + } + + function testGetFormattedValue() { + $field = $this->objFromFixture('SubmittedFormField', 'submitted-form-field-1'); + + $this->assertEquals('1', $field->getFormattedValue()); + + $textarea = $this->objFromFixture('SubmittedFormField', 'submitted-textarea-1'); + + $text = "I am here testing
    \nTesting until I cannot
    \nI love my testing"; + + $this->assertEquals($text, $textarea->getFormattedValue()); + } + + function testFileGetLink() { + $field = $this->objFromFixture('SubmittedFileField', 'submitted-file-1'); + + // @todo add checks for if no file can be downloaded + $this->assertContains('my-file.jpg', $field->getLink()); + + } + function testFileGetFormattedValue() { + $field = $this->objFromFixture('SubmittedFileField', 'submitted-file-1'); + + // @todo add checks for if no file can be downloaded + $this->assertContains('Download File', $field->getFormattedValue()); + } +} + + +class SubmittedFormTest_Controller extends Controller { + + function ReportField() { + return new Form($this, 'ReportField', new FieldSet(new SubmittedFormReportField('Report'), new FieldSet())); + } +} diff --git a/tests/SubmittedFormTest.yml b/tests/SubmittedFormTest.yml new file mode 100644 index 0000000..8bcd3df --- /dev/null +++ b/tests/SubmittedFormTest.yml @@ -0,0 +1,43 @@ +UserDefinedForm: + form-page: + Title: Form + + form-page-2: + Title: Second Form + +File: + uploaded-file: + Name: My File + Filename: my-file.jpg + +SubmittedForm: + submitted-form-1: + Parent: =>UserDefinedForm.form-page + + submitted-form-2: + Parent: =>UserDefinedForm.form-page-2 + +SubmittedFormField: + submitted-form-field-1: + Parent: =>SubmittedForm.submitted-form-1 + Name: field-1 + Title: Field 1 + Value: 1 + + submitted-textarea-1: + Parent: =>SubmittedForm.submitted-form-2 + Name: field 2 + Title: Field 2 + Value: | + I am here testing + Testing until I cannot + I love my testing + +SubmittedFileField: + submitted-file-1: + Name: File Field + Title: File + Parent: =>SubmittedForm.submitted-form-1 + UploadedFile: =>File.uploaded-file + + \ No newline at end of file diff --git a/tests/UserDefinedFormControllerTest.php b/tests/UserDefinedFormControllerTest.php new file mode 100644 index 0000000..ccb96e1 --- /dev/null +++ b/tests/UserDefinedFormControllerTest.php @@ -0,0 +1,196 @@ +setupFormFrontend(); + + $controller = new UserDefinedForm_Controller($form); + + $this->autoFollowRedirection = false; + $this->clearEmails(); + + // load the form + $this->get($form->URLSegment); + $response = $this->submitForm('Form_Form', null, array('basic-text-name' => 'Basic Value')); + + // should have a submitted form field now + $submitted = DataObject::get('SubmittedFormField', "\"Name\" = 'basic-text-name'"); + $this->assertDOSAllMatch(array('Name' => 'basic-text-name', 'Value' => 'Basic Value', 'Title' => 'Basic Text Field'), $submitted); + + // check emails + $this->assertEmailSent('test@example.com', 'no-reply@example.com', 'Email Subject'); + $email = $this->findEmail('test@example.com', 'no-reply@example.com', 'Email Subject'); + + // assert that the email has the field title and the value html email + $parser = new CSSContentParser($email['content']); + $title = $parser->getBySelector('strong'); + + $this->assertEquals('Basic Text Field', (string) $title[0], 'Email contains the field name'); + + $value = $parser->getBySelector('dd'); + $this->assertEquals('Basic Value', (string) $value[0], 'Email contains the value'); + + // no html + $this->assertEmailSent('nohtml@example.com', 'no-reply@example.com', 'Email Subject'); + $nohtml = $this->findEmail('nohtml@example.com', 'no-reply@example.com', 'Email Subject'); + + $this->assertContains('Basic Text Field - Basic Value', $nohtml['content'], 'Email contains no html'); + + // no data + $this->assertEmailSent('nodata@example.com', 'no-reply@example.com', 'Email Subject'); + $nodata = $this->findEmail('nodata@example.com', 'no-reply@example.com', 'Email Subject'); + + $parser = new CSSContentParser($nodata['content']); + $list = $parser->getBySelector('dl'); + + $this->assertFalse(isset($list[0]), 'Email contains no fields'); + + // check to see if the user was redirected (301) + $this->assertEquals($response->getStatusCode(), 302); + $this->assertStringEndsWith('finished', $response->getHeader('Location')); + } + + function testFinished() { + $form = $this->setupFormFrontend(); + $response = $this->get($form->URLSegment.'/finished'); + + $this->assertContains($form->OnCompleteMessage ,$response->getBody()); + } + + function testForm() { + $form = $this->objFromFixture('UserDefinedForm', 'basic-form-page'); + + $controller = new UserDefinedForm_Controller($form); + + // test form + $this->assertEquals($controller->Form()->Name(), 'Form', 'The form is referenced as Form'); + + $this->assertEquals($controller->Form()->Fields()->Count(), 2); + $this->assertEquals($controller->Form()->Actions()->Count(), 1); + $this->assertEquals(count($controller->Form()->getValidator()->getRequired()), 0); + + $requiredForm = $this->objFromFixture('UserDefinedForm', 'validation-form'); + $controller = new UserDefinedForm_Controller($requiredForm); + + $this->assertEquals($controller->Form()->Fields()->Count(), 2); + $this->assertEquals($controller->Form()->Actions()->Count(), 1); + $this->assertEquals(count($controller->Form()->getValidator()->getRequired()), 1); + } + + function testgetFormFields() { + // generating the fieldset of fields + $form = $this->objFromFixture('UserDefinedForm', 'basic-form-page'); + + $controller = new UserDefinedForm_Controller($form); + + $fields = $controller->getFormFields(); + + $this->assertEquals($fields->Count(), 1); + + // custom error message on a form field + $requiredForm = $this->objFromFixture('UserDefinedForm', 'validation-form'); + $controller = new UserDefinedForm_Controller($requiredForm); + + UserDefinedForm::$required_identifier = "*"; + + $fields = $controller->getFormFields(); + + $this->assertEquals($fields->First()->getCustomValidationMessage(), 'Custom Error Message'); + } + + function testGetFormActions() { + // generating the fieldset of actions + $form = $this->objFromFixture('UserDefinedForm', 'basic-form-page'); + + $controller = new UserDefinedForm_Controller($form); + $actions = $controller->getFormActions(); + + // by default will have 1 submit button which links to process + $expected = new FieldSet(new FormAction('process', 'Submit')); + + $this->assertEquals($actions, $expected); + + // the custom popup should have a reset button and a custom text + $custom = $this->objFromFixture('UserDefinedForm', 'form-with-reset-and-custom-action'); + $controller = new UserDefinedForm_Controller($custom); + + $actions = $controller->getFormActions(); + + $expected = new FieldSet(new FormAction('process', 'Custom Button')); + $expected->push(new ResetFormAction("clearForm")); + + $this->assertEquals($actions, $expected); + } + + function testArrayToJson() { + $array = array('1' => 'one', '2' => 'two'); + $string = "{\n1:\"one\", 2:\"two\"\n}\n"; + $this->assertEquals(UserDefinedForm_Controller::array2json($array), $string); + } + + + function testRenderingIntoFormTemplate() { + $form = $this->setupFormFrontend(); + + $form->Content = 'This is some content without a form nested between it'; + $form->doPublish(); + + $controller = new UserDefinedForm_Controller($form); + + // check to see if $Form is replaced to inside the content + $index = new ArrayData($controller->index()); + $parser = new CSSContentParser($index->renderWith(array('UserDefinedFormControllerTest'))); + + $this->checkTemplateIsCorrect($parser); + } + + function testRenderingIntoTemplateWithSubstringReplacement() { + $form = $this->setupFormFrontend(); + + $controller = new UserDefinedForm_Controller($form); + + // check to see if $Form is replaced to inside the content + $index = new ArrayData($controller->index()); + $parser = new CSSContentParser($index->renderWith(array('UserDefinedFormControllerTest'))); + + $this->checkTemplateIsCorrect($parser); + } + + function setupFormFrontend() { + $form = $this->objFromFixture('UserDefinedForm', 'basic-form-page'); + $this->logInWithPermission('ADMIN'); + + $form->doPublish(); + + $member = Member::currentUser(); + $member->logOut(); + + return $form; + } + + function checkTemplateIsCorrect($parser) { + $this->assertArrayHasKey(0, $parser->getBySelector('form#Form_Form')); + + // check for the input + $this->assertArrayHasKey(0, $parser->getBySelector('input.text')); + + // check for the label and the text + $label = $parser->getBySelector('label.left'); + $this->assertArrayHasKey(0, $label); + + $this->assertEquals((string) $label[0][0], "Basic Text Field", "Label contains correct field name"); + + // check for the action + $action = $parser->getBySelector('input.action'); + $this->assertArrayHasKey(0, $action); + + $this->assertEquals((string) $action[0]['value'], "Submit", "Submit button has default text"); + } +} \ No newline at end of file diff --git a/tests/UserDefinedFormEditorTest.php b/tests/UserDefinedFormEditorTest.php deleted file mode 100644 index aabf5ef..0000000 --- a/tests/UserDefinedFormEditorTest.php +++ /dev/null @@ -1,102 +0,0 @@ -logInWithPermission('ADMIN'); - - $this->form = new UserDefinedForm(); - $this->form->write(); - } - - function testPublishingNormalField() { - $id = $this->form->ID; - - // test a normal field - $field = new EditableFormField(); - $field->write(); - - $this->form->Fields()->add($field); - - // upon adding it, it shouldn't be on the live site - $live = Versioned::get_one_by_stage("UserDefinedForm", "Live", "\"UserDefinedForm_Live\".\"ID\" = $id"); - $this->assertFalse($live); - - // upon publishing the field should exist - $this->form->doPublish(); - $live = Versioned::get_one_by_stage("UserDefinedForm", "Live", "\"UserDefinedForm_Live\".\"ID\" = $id"); - $this->assertEquals($live->Fields()->Count(), 1); - } - - function testPublishingMultipleOptions() { - $id = $this->form->ID; - $this->form->Fields()->removeAll(); - - // test a editable option field - $dropdown = new EditableDropdown(); - $dropdown->write(); - - $checkbox = new EditableCheckboxGroupField(); - $checkbox->write(); - - $option = new EditableOption(); - $option->write(); - - $option2 = new EditableOption(); - $option2->write(); - - $dropdown->Options()->add($option); - $checkbox->Options()->add($option2); - - $this->form->Fields()->add($dropdown); - $this->form->Fields()->add($checkbox); - - // upon adding it, it shouldn't be on the live site - $live = Versioned::get_one_by_stage("UserDefinedForm", "Live", "\"UserDefinedForm_Live\".\"ID\" = $id"); - $this->assertFalse($live); - - // and when published it should exist and the option - $this->form->doPublish(); - $live = Versioned::get_one_by_stage("UserDefinedForm", "Live", "\"UserDefinedForm_Live\".\"ID\" = $id"); - $this->assertEquals($live->Fields()->Count(), 2); - - // check they have options attached - foreach($live->Fields() as $field) { - $this->assertEquals($field->Options()->Count(), 1); - } - } - - function testUnpublishing() { - $id = $this->form->ID; - $this->form->Fields()->removeAll(); - $this->form->Fields()->add(new EditableFormField()); - $this->form->doUnPublish(); - $live = Versioned::get_one_by_stage("UserDefinedForm", "Live", "\"UserDefinedForm_Live\".\"ID\" = $id"); - $stage = Versioned::get_one_by_stage("UserDefinedForm", "Stage", "\"UserDefinedForm\".\"ID\" = $id"); - $this->assertEquals($live, false); - $this->assertEquals($stage->Fields()->Count(), 1); - } - - function testDuplicatingPage() { - $this->form->Fields()->add(new EditableFormField()); - $form_copy = $this->form->duplicate(); - - $this->assertEquals($this->form->Fields()->Count(), $form_copy->Fields()->Count()); - } - - function tearDown() { - $this->form->delete(); - - parent::tearDown(); - } -} \ No newline at end of file diff --git a/tests/UserDefinedFormFieldTest.php b/tests/UserDefinedFormFieldTest.php deleted file mode 100644 index 7cb7c35..0000000 --- a/tests/UserDefinedFormFieldTest.php +++ /dev/null @@ -1,28 +0,0 @@ -Name = "$field"; - $object->Title = "$field"; - $object->write(); - - $this->assertEquals($field, $object->Name); - $object->delete(); - } - } -} \ No newline at end of file diff --git a/tests/UserDefinedFormTest.php b/tests/UserDefinedFormTest.php new file mode 100644 index 0000000..f0d3055 --- /dev/null +++ b/tests/UserDefinedFormTest.php @@ -0,0 +1,221 @@ +logInWithPermission('ADMIN'); + $form = $this->objFromFixture('UserDefinedForm', 'basic-form-page'); + + $form->SubmitButtonText = 'Button Text'; + $form->write(); + $form->doPublish(); + $origVersion = $form->Version; + + $form->SubmitButtonText = 'Updated Button Text'; + $form->write(); + $form->doPublish(); + + // check published site + $updated = Versioned::get_one_by_stage("UserDefinedForm", "Stage", "\"UserDefinedForm\".\"ID\" = $form->ID"); + $this->assertEquals($updated->SubmitButtonText, 'Updated Button Text'); + + $form->doRollbackTo($origVersion); + + $orignal = Versioned::get_one_by_stage("UserDefinedForm", "Stage", "\"UserDefinedForm\".\"ID\" = $form->ID"); + $this->assertEquals($orignal->SubmitButtonText, 'Button Text'); + } + + function testGetCMSFields() { + // ensure all the tabs are present. + // @todo a common bug with this is translations messing up the tabs. + // @todo only logic we should check for is that the tablelistfield filter + $this->logInWithPermission('ADMIN'); + $form = $this->objFromFixture('UserDefinedForm', 'basic-form-page'); + + $fields = $form->getCMSFields(); + + $this->assertTrue($fields->dataFieldByName('Fields') !== null); + $this->assertTrue($fields->dataFieldByName('EmailRecipients') != null); + $this->assertTrue($fields->dataFieldByName('Reports') != null); + $this->assertTrue($fields->dataFieldByName('OnCompleteMessage') != null); + } + + function testEmailRecipientPopup() { + $this->logInWithPermission('ADMIN'); + + $form = $this->objFromFixture('UserDefinedForm', 'basic-form-page'); + + $popup = new UserDefinedForm_EmailRecipient(); + + $fields = $popup->getCMSFields_forPopup(); + + $this->assertTrue($fields->dataFieldByName('EmailSubject') !== null); + $this->assertTrue($fields->dataFieldByName('EmailFrom') !== null); + $this->assertTrue($fields->dataFieldByName('EmailAddress') !== null); + $this->assertTrue($fields->dataFieldByName('HideFormData') !== null); + $this->assertTrue($fields->dataFieldByName('SendPlain') !== null); + $this->assertTrue($fields->dataFieldByName('EmailBody') !== null); + + // add an email field, it should now add a or from X address picker + $email = $this->objFromFixture('EditableEmailField','email-field'); + $form->Fields()->add($email); + + $popup->Form = $form; + $popup->write(); + + $fields = $popup->getCMSFields_forPopup(); + $this->assertThat($fields->fieldByName('SendEmailToFieldID'), $this->isInstanceOf('DropdownField')); + + // if the front end has checkboxs or dropdown they can select from that can also be used to send things + $dropdown = $this->objFromFixture('EditableDropdown', 'department-dropdown'); + $form->Fields()->add($dropdown); + + $fields = $popup->getCMSFields_forPopup(); + $this->assertTrue($fields->dataFieldByName('SendEmailToFieldID') !== null); + + $popup->delete(); + } + + function testPublishing() { + $this->logInWithPermission('ADMIN'); + + $form = $this->objFromFixture('UserDefinedForm', 'basic-form-page'); + $form->write(); + + $form->doPublish(); + + $live = Versioned::get_one_by_stage("UserDefinedForm", "Live", "\"UserDefinedForm_Live\".\"ID\" = $form->ID"); + + $this->assertNotNull($live); + $this->assertEquals($live->Fields()->Count(), 1); + + $dropdown = $this->objFromFixture('EditableDropdown', 'basic-dropdown'); + $form->Fields()->add($dropdown); + + $stage = Versioned::get_one_by_stage("UserDefinedForm", "Stage", "\"UserDefinedForm\".\"ID\" = $form->ID"); + $this->assertEquals($stage->Fields()->Count(), 2); + + // should not have published the dropdown + $liveDropdown = Versioned::get_one_by_stage("EditableFormField", "Live", "\"EditableFormField_Live\".\"ID\" = $dropdown->ID"); + $this->assertFalse($liveDropdown); + + // when publishing it should have added it + $form->doPublish(); + + $live = Versioned::get_one_by_stage("UserDefinedForm", "Live", "\"UserDefinedForm_Live\".\"ID\" = $form->ID"); + $this->assertEquals($live->Fields()->Count(), 2); + + // edit the title + $text = $form->Fields()->First(); + + $text->Title = 'Edited title'; + $text->write(); + + $liveText = Versioned::get_one_by_stage("EditableFormField", "Live", "\"EditableFormField_Live\".\"ID\" = $text->ID"); + $this->assertFalse($liveText->Title == $text->Title); + + $form->doPublish(); + + $liveText = Versioned::get_one_by_stage("EditableFormField", "Live", "\"EditableFormField_Live\".\"ID\" = $text->ID"); + $this->assertTrue($liveText->Title == $text->Title); + } + + function testUnpublishing() { + $this->logInWithPermission('ADMIN'); + $form = $this->objFromFixture('UserDefinedForm', 'basic-form-page'); + $form->write(); + + $form->doPublish(); + + // assert that it exists and has a field + $live = Versioned::get_one_by_stage("UserDefinedForm", "Live", "\"UserDefinedForm_Live\".\"ID\" = $form->ID"); + + $this->assertTrue(isset($live)); + $this->assertEquals(DB::query("SELECT COUNT(*) FROM \"EditableFormField_Live\"")->value(), 1); + + // unpublish + $form->doUnpublish(); + + $this->assertFalse(Versioned::get_one_by_stage("UserDefinedForm", "Live", "\"UserDefinedForm_Live\".\"ID\" = $form->ID")); + $this->assertEquals(DB::query("SELECT COUNT(*) FROM \"EditableFormField_Live\"")->value(), 0); + + } + + function testDoRevertToLive() { + $this->logInWithPermission('ADMIN'); + $form = $this->objFromFixture('UserDefinedForm', 'basic-form-page'); + $form->SubmitButtonText = 'Button Text'; + $form->doPublish(); + $text = $form->Fields()->First(); + + $form->SubmitButtonText = 'Edited Button Text'; + $form->write(); + + $text->Title = 'Edited title'; + $text->write(); + + // check that the published version is not updated + $liveText = Versioned::get_one_by_stage("EditableFormField", "Live", "\"EditableFormField_Live\".\"ID\" = $text->ID"); + + $revertTo = $liveText->Title; + + $this->assertFalse($revertTo == $text->Title); + + // revert back to the live data + $form->doRevertToLive(); + + $check = Versioned::get_one_by_stage("EditableFormField", "Stage", "\"EditableFormField\".\"ID\" = $text->ID"); + + $this->assertEquals($check->Title, $revertTo); + + // check the edited buttoned + $liveForm = Versioned::get_one_by_stage("UserDefinedForm", "Live", "\"UserDefinedForm_Live\".\"ID\" = $form->ID"); + $revertedForm = Versioned::get_one_by_stage("UserDefinedForm", "Stage", "\"UserDefinedForm\".\"ID\" = $form->ID"); + + $this->assertEquals($liveForm->SubmitButtonText, $revertedForm->SubmitButtonText); + } + + function testDuplicatingForm() { + $this->logInWithPermission('ADMIN'); + $form = $this->objFromFixture('UserDefinedForm', 'basic-form-page'); + + $duplicate = $form->duplicate(); + + $this->assertEquals($form->Fields()->Count(), $duplicate->Fields()->Count()); + $this->assertEquals($form->EmailRecipients()->Count(), $form->EmailRecipients()->Count()); + + // can't compare object since the dates/ids change + $this->assertEquals($form->Fields()->First()->Title, $duplicate->Fields()->First()->Title); + } + + /** + * @todo once getIsModifiedOnStage is implemented will need to implement this + */ + function testGetIsModifiedOnStage() { + $this->logInWithPermission('ADMIN'); + $form = $this->objFromFixture('UserDefinedForm', 'basic-form-page'); + + $this->assertTrue($form->getIsModifiedOnStage()); + } + + function testFormOptions() { + $this->logInWithPermission('ADMIN'); + $form = $this->objFromFixture('UserDefinedForm', 'basic-form-page'); + + $fields = $form->getFormOptions(); + $submit = $fields->fieldByName('SubmitButtonText'); + $reset = $fields->fieldByName('ShowClearButton'); + + $this->assertEquals($submit->Title(), 'Text on submit button:'); + $this->assertEquals($reset->Title(), 'Show Clear Form Button'); + } +} \ No newline at end of file diff --git a/tests/UserDefinedFormTest.yml b/tests/UserDefinedFormTest.yml new file mode 100644 index 0000000..43d5a42 --- /dev/null +++ b/tests/UserDefinedFormTest.yml @@ -0,0 +1,87 @@ +EditableOption: + option-1: + Name: Option1 + Title: Option 1 + Sort: 1 + + option-2: + Name: Option2 + Title: Option 2 + Sort: 2 + department-1: + Name: dept1 + Title: sales@example.com + + department-2: + Name: dept2 + Title: accounts@example.com + +UserDefinedForm_EmailRecipient: + recipient-1: + EmailAddress: test@example.com + EmailSubject: Email Subject + EmailFrom: no-reply@example.com + + no-html: + EmailAddress: nohtml@example.com + EmailSubject: Email Subject + EmailFrom: no-reply@example.com + SendPlain: true + + no-data: + EmailAddress: nodata@example.com + EmailSubject: Email Subject + EmailFrom: no-reply@example.com + HideFormData: true + +EditableTextField: + basic-text: + Name: basic-text-name + Title: Basic Text Field + + required-text: + Name: required-text-field + Title: Required Text Field + CustomErrorMessage: Custom Error Message + RightTitle: Right Title + Required: true + +EditableDropdown: + basic-dropdown: + Name: basic-dropdown + Title: Basic Dropdown Field + Options: =>EditableOption.option-1, =>EditableOption.option-2 + + department-dropdown: + Name: department + Title: Department + Options: =>EditableOption.department-1, =>EditableOption.department-2 + +EditableCheckbox: + checkbox-1: + Name: checkbox-1 + Title: Checkbox 1 + +EditableEmailField: + email-field: + Name: email-field + Title: Email + +UserDefinedForm: + basic-form-page: + Title: User Defined Form + Fields: =>EditableTextField.basic-text + EmailRecipients: =>UserDefinedForm_EmailRecipient.recipient-1, =>UserDefinedForm_EmailRecipient.no-html, =>UserDefinedForm_EmailRecipient.no-data + + form-with-reset-and-custom-action: + Title: Form with Reset Action + SubmitButtonText: Custom Button + ShowClearButton: true + + validation-form: + Title: Validation Form + Fields: =>EditableTextField.required-text + + + + \ No newline at end of file diff --git a/tests/templates/UserDefinedFormControllerTest.ss b/tests/templates/UserDefinedFormControllerTest.ss new file mode 100644 index 0000000..0779827 --- /dev/null +++ b/tests/templates/UserDefinedFormControllerTest.ss @@ -0,0 +1,5 @@ + + +$Content +$Form + \ No newline at end of file