mirror of
https://github.com/silverstripe/silverstripe-userforms.git
synced 2024-10-22 17:05:42 +02:00
ENHANCEMENT: added test coverage for UserDefinedForm.php and placeholders for other sections. API change: processNewFormFields removed
API change: refactored Form() into getFormFields(), getFormActions(), getRequiredFields() ENHANCEMENT: added updateForm* extension hooks to allow customization of userforms BUGFIX: gave custom scripts their own ID to enable it to be blocked.
This commit is contained in:
parent
5f4d4e7d28
commit
3c1d81d014
@ -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() ." <span class='requiredIdentifier'>". UserDefinedForm::$required_identifier . "</span>";
|
||||
$fieldToAdd->setTitle($title);
|
||||
// if this field is required add some
|
||||
if($editableField->Required) {
|
||||
$field->addExtraClass('requiredField');
|
||||
|
||||
if($identifier = UserDefinedForm::$required_identifier) {
|
||||
|
||||
$title = $field->Title() ." <span class='required-identifier'>". $identifier . "</span>";
|
||||
$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(<<<JS
|
||||
(function($) {
|
||||
$(document).ready(function() {
|
||||
$("#Form_Form").validate({
|
||||
errorClass: "required",
|
||||
messages:
|
||||
$messages
|
||||
,
|
||||
rules:
|
||||
$rules
|
||||
});
|
||||
});
|
||||
})(jQuery);
|
||||
JS
|
||||
, 'UserFormsValidation');
|
||||
|
||||
$this->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(<<<JS
|
||||
(function($) {
|
||||
$(document).ready(function() {
|
||||
$defaults
|
||||
$("#$FormName").validate({
|
||||
errorClass: "required",
|
||||
messages:
|
||||
$messages
|
||||
,
|
||||
|
||||
rules:
|
||||
$rules
|
||||
});
|
||||
$customDisplayRules
|
||||
});
|
||||
$rules
|
||||
|
||||
$default
|
||||
})
|
||||
})(jQuery);
|
||||
JS
|
||||
);
|
||||
, 'UserFormsConditional');
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -507,15 +622,15 @@ JS
|
||||
* @param Array array to convert
|
||||
* @return JSON
|
||||
*/
|
||||
protected function array2json($array) {
|
||||
function array2json($array) {
|
||||
foreach($array as $key => $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' => '',
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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 "<input type=\"text\" class=\"text\" title=\"("._t('EditableFormField.ENTERQUESTION', 'Enter Question').")\" value=\"$titleAttr\" name=\"Fields[{$this->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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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'));
|
||||
|
@ -1,36 +1,51 @@
|
||||
<?php
|
||||
/**
|
||||
* Allows CMS user to create forms dynamically.
|
||||
* A form field allowing a user to customize and create form fields.
|
||||
* for saving into a {@link UserDefinedForm}
|
||||
*
|
||||
* @package userforms
|
||||
*/
|
||||
|
||||
class FieldEditor extends FormField {
|
||||
|
||||
protected $hasFormOptions = true;
|
||||
|
||||
/**
|
||||
* Field Editor Template
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
function FieldHolder() {
|
||||
return $this->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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
class SubmittedForm extends DataObject {
|
||||
|
||||
static $has_one = array(
|
||||
"SubmittedBy" => "Member",
|
||||
"Parent" => "UserDefinedForm",
|
||||
|
@ -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;$i<count($csvHeaderNames);$i++) {
|
||||
if(!isset($row[$i]) || !$row[$i]) $csvData .= '"",'; // If there is no data for this column, output it as blank instead
|
||||
else {
|
||||
$tmp = str_replace('"', '""', $row[$i]);
|
||||
$csvData .= '"' . $tmp . '",';
|
||||
}
|
||||
}
|
||||
// Start a new row for each submission (re-check we have 'Submitted' in this entry)
|
||||
if(isset($row['Submitted'])) $csvData .= '"'.$row['Submitted'].'"'."\n";
|
||||
else $csvData .= '\n';
|
||||
}
|
||||
} else {
|
||||
user_error("No submissions to export.", E_USER_ERROR);
|
||||
}
|
||||
|
||||
if(class_exists('SS_HTTPRequest')) {
|
||||
SS_HTTPRequest::send_file($csvData, $fileName)->output();
|
||||
} 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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
|
@ -1,10 +1,10 @@
|
||||
<!-- JS Relys on EditableFormField as a class - and the 3 ids in this order - do not change -->
|
||||
<li class="$ClassName EditableFormField" id="$Name.ATT EditableItem_$Pos $Name">
|
||||
<div class="fieldInfo">
|
||||
<% if isReadonly %>
|
||||
<img class="fieldHandler" src="sapphire/images/drag_readonly.gif" alt="<% _t('LOCKED', 'These fields cannot be modified') %>" />
|
||||
<% else %>
|
||||
<% if canEdit %>
|
||||
<img class="fieldHandler" src="sapphire/images/drag.gif" alt="<% _t('DRAG', 'Drag to rearrange order of fields') %>" />
|
||||
<% else %>
|
||||
<img class="fieldHandler" src="sapphire/images/drag_readonly.gif" alt="<% _t('LOCKED', 'These fields cannot be modified') %>" />
|
||||
<% end_if %>
|
||||
|
||||
<img class="icon" src="$Icon" alt="$ClassName" title="$singular_name" />
|
||||
|
@ -3,9 +3,9 @@
|
||||
<input type="text" name="{$FieldName}[Title]" value="$Title" />
|
||||
<input type="hidden" class="sortOptionHidden hidden" name="{$FieldName}[Sort]" value="$Sort" />
|
||||
|
||||
<% if isReadonly %>
|
||||
<img src="cms/images/locked.gif" alt="<% _t('LOCKED', 'These fields cannot be modified') %>" />
|
||||
<% else %>
|
||||
<% if canEdit %>
|
||||
<a href="$ID" class="deleteOption"><img src="cms/images/delete.gif" alt="<% _t('DELETE', 'Remove this option') %>" /></a>
|
||||
<% else %>
|
||||
<img src="cms/images/locked.gif" alt="<% _t('LOCKED', 'These fields cannot be modified') %>" />
|
||||
<% end_if %>
|
||||
</li>
|
@ -1,4 +1,8 @@
|
||||
<div class="FieldEditor <% if isReadonly %>readonly<% end_if %>" id="Fields">
|
||||
<% require css(userforms/css/FieldEditor.css) %>
|
||||
<% require javascript(sapphire/thirdparty/jquery-ui/jquery-ui-1.8rc3.custom.js) %>
|
||||
<% require javascript(userforms/javascript/UserForm.js) %>
|
||||
|
||||
<div class="FieldEditor <% if canEdit %><% else %>readonly<% end_if %>" id="Fields">
|
||||
|
||||
<div class="FieldListHold">
|
||||
<ul class="FieldList" id="Fields_fields">
|
||||
@ -8,12 +12,19 @@
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<% include AddField %>
|
||||
|
||||
<div class="FormOptions">
|
||||
<h3>Form Options</h3>
|
||||
<% control FormOptions %>
|
||||
$FieldHolder
|
||||
<% end_control %>
|
||||
</div>
|
||||
<% if canEdit %>
|
||||
<div class="MenuHolder">
|
||||
<h2><% _t('ADD', 'Add') %></h2>
|
||||
|
||||
<select name="AddUserFormField" id="AddUserFormField">
|
||||
<option value=""><% _t('SELECTAFIELD', 'Select a Field') %></option>
|
||||
|
||||
<% control CreatableFields %>
|
||||
<option value="$ClassName">$Title</option>
|
||||
<% end_control %>
|
||||
</select>
|
||||
|
||||
<input type="submit" class="action" value="<% _t('ADD', 'Add') %>" />
|
||||
</div>
|
||||
<% end_if %>
|
||||
</div>
|
@ -1,14 +0,0 @@
|
||||
<% if canEdit %>
|
||||
<div class="MenuHolder">
|
||||
<h2><% _t('ADD', 'Add') %></h2>
|
||||
<select name="AddUserFormField" id="AddUserFormField">
|
||||
<option value=""><% _t('SELECTAFIELD', 'Select a Field') %></option>
|
||||
|
||||
<% control CreatableFields %>
|
||||
<option value="$ClassName">$Title</option>
|
||||
<% end_control %>
|
||||
</select>
|
||||
|
||||
<input type="submit" class="action" value="<% _t('ADD', 'Add') %>" />
|
||||
</div>
|
||||
<% end_if %>
|
45
tests/EditableFormFieldTest.php
Normal file
45
tests/EditableFormFieldTest.php
Normal file
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package userforms
|
||||
*/
|
||||
|
||||
class EditableFormFieldTest extends FunctionalTest {
|
||||
|
||||
static $fixture_file = 'userforms/tests/EditableFormFields.yml';
|
||||
|
||||
function testEditableDropdownField() {
|
||||
$dropdown = $this->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);
|
||||
}
|
||||
}
|
62
tests/EditableFormFields.yml
Normal file
62
tests/EditableFormFields.yml
Normal file
@ -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
|
37
tests/FieldEditorTest.php
Normal file
37
tests/FieldEditorTest.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tests covering the form editor / builder and
|
||||
* some of the user interface
|
||||
*
|
||||
* @package userforms
|
||||
*/
|
||||
|
||||
class FieldEditorTest extends FunctionalTest {
|
||||
|
||||
static $fixture_file = 'userforms/tests/UserDefinedFormTest.yml';
|
||||
|
||||
function testPerformReadonlyTransformation() {
|
||||
|
||||
}
|
||||
|
||||
function testSaveInto() {
|
||||
|
||||
}
|
||||
|
||||
function testAddField() {
|
||||
|
||||
}
|
||||
|
||||
function testAddOptionField() {
|
||||
|
||||
}
|
||||
|
||||
function testCreatableFields() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class FieldEditorTest_Controller extends Controller {
|
||||
|
||||
}
|
68
tests/SubmittedFormTest.php
Normal file
68
tests/SubmittedFormTest.php
Normal file
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
class SubmittedFormTest extends FunctionalTest {
|
||||
|
||||
static $fixture_file = 'userforms/tests/SubmittedFormTest.yml';
|
||||
|
||||
function testReportSubmissions() {
|
||||
|
||||
}
|
||||
|
||||
function testCSVExport() {
|
||||
|
||||
}
|
||||
|
||||
function testdeletesubmission() {
|
||||
|
||||
}
|
||||
|
||||
function testdeletesubmissions() {
|
||||
|
||||
}
|
||||
|
||||
function testOnBeforeDeleteOfForm() {
|
||||
$field = $this->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<br />\nTesting until I cannot<br />\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()));
|
||||
}
|
||||
}
|
43
tests/SubmittedFormTest.yml
Normal file
43
tests/SubmittedFormTest.yml
Normal file
@ -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
|
||||
|
||||
|
196
tests/UserDefinedFormControllerTest.php
Normal file
196
tests/UserDefinedFormControllerTest.php
Normal file
@ -0,0 +1,196 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package userforms
|
||||
*/
|
||||
|
||||
class UserDefinedFormControllerTest extends FunctionalTest {
|
||||
|
||||
static $fixture_file = 'userforms/tests/UserDefinedFormTest.yml';
|
||||
|
||||
function testProcess() {
|
||||
$form = $this->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");
|
||||
}
|
||||
}
|
@ -1,102 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tests covering the form editor / builder and
|
||||
* some of the user interface
|
||||
*
|
||||
* @package userforms
|
||||
*/
|
||||
|
||||
class UserDefinedFormEditorTest extends FunctionalTest {
|
||||
|
||||
protected $form;
|
||||
|
||||
function setUp() {
|
||||
parent::setUp();
|
||||
$this->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();
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Various tests for the user defined forms.
|
||||
* Does not test the user interface in the admin.
|
||||
*
|
||||
* @todo Add more comprehensive tests
|
||||
* @package userforms
|
||||
*/
|
||||
|
||||
class UserDefinedFormFieldTest extends SapphireTest {
|
||||
|
||||
/**
|
||||
* Basic Test creating all the editable form fields
|
||||
*/
|
||||
function testCreatingAllFields() {
|
||||
$fields = ClassInfo::subclassesFor('EditableFormField');
|
||||
foreach($fields as $field) {
|
||||
$object = new $field();
|
||||
$object->Name = "$field";
|
||||
$object->Title = "$field";
|
||||
$object->write();
|
||||
|
||||
$this->assertEquals($field, $object->Name);
|
||||
$object->delete();
|
||||
}
|
||||
}
|
||||
}
|
221
tests/UserDefinedFormTest.php
Normal file
221
tests/UserDefinedFormTest.php
Normal file
@ -0,0 +1,221 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package userforms
|
||||
*/
|
||||
|
||||
class UserDefinedFormTest extends FunctionalTest {
|
||||
|
||||
static $fixture_file = 'userforms/tests/UserDefinedFormTest.yml';
|
||||
|
||||
|
||||
function testRollbackToVersion() {
|
||||
// @todo rolling back functionality (eg fields) is not supported yet
|
||||
|
||||
$this->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');
|
||||
}
|
||||
}
|
87
tests/UserDefinedFormTest.yml
Normal file
87
tests/UserDefinedFormTest.yml
Normal file
@ -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
|
||||
|
||||
|
||||
|
||||
|
5
tests/templates/UserDefinedFormControllerTest.ss
Normal file
5
tests/templates/UserDefinedFormControllerTest.ss
Normal file
@ -0,0 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
$Content
|
||||
$Form
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user