mirror of
https://github.com/silverstripe/silverstripe-userforms.git
synced 2024-10-22 17:05:42 +02:00
Convert to psr-2
This commit is contained in:
parent
e620576e97
commit
57048fd901
@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
if(!defined('USERFORMS_DIR')) {
|
if (!defined('USERFORMS_DIR')) {
|
||||||
define('USERFORMS_DIR', basename(__DIR__));
|
define('USERFORMS_DIR', basename(__DIR__));
|
||||||
}
|
}
|
||||||
|
|
||||||
Deprecation::notification_version('3.0', 'userforms');
|
Deprecation::notification_version('3.0', 'userforms');
|
||||||
|
@ -7,113 +7,118 @@
|
|||||||
*
|
*
|
||||||
* @package userforms
|
* @package userforms
|
||||||
*/
|
*/
|
||||||
class UserFormsGridFieldFilterHeader extends GridFieldFilterHeader {
|
class UserFormsGridFieldFilterHeader extends GridFieldFilterHeader
|
||||||
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A map of name => value of columns from all submissions
|
* A map of name => value of columns from all submissions
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $columns;
|
protected $columns;
|
||||||
|
|
||||||
public function setColumns($columns) {
|
public function setColumns($columns)
|
||||||
$this->columns = $columns;
|
{
|
||||||
}
|
$this->columns = $columns;
|
||||||
|
}
|
||||||
|
|
||||||
public function handleAction(GridField $gridField, $actionName, $arguments, $data) {
|
public function handleAction(GridField $gridField, $actionName, $arguments, $data)
|
||||||
if(!$this->checkDataType($gridField->getList())) {
|
{
|
||||||
return;
|
if (!$this->checkDataType($gridField->getList())) {
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if($actionName === 'filter') {
|
if ($actionName === 'filter') {
|
||||||
$gridField->State->UserFormsGridField = array(
|
$gridField->State->UserFormsGridField = array(
|
||||||
'filter' => isset($data['FieldNameFilter']) ? $data['FieldNameFilter'] : null,
|
'filter' => isset($data['FieldNameFilter']) ? $data['FieldNameFilter'] : null,
|
||||||
'value' => isset($data['FieldValue']) ? $data['FieldValue'] : null,
|
'value' => isset($data['FieldValue']) ? $data['FieldValue'] : null,
|
||||||
'start' => isset($data['StartFilter']) ? $data['StartFilter'] : null,
|
'start' => isset($data['StartFilter']) ? $data['StartFilter'] : null,
|
||||||
'end' => isset($data['EndFilter']) ? $data['EndFilter'] : null
|
'end' => isset($data['EndFilter']) ? $data['EndFilter'] : null
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function getHTMLFragments($gridField) {
|
public function getHTMLFragments($gridField)
|
||||||
$fields = new ArrayList();
|
{
|
||||||
$state = $gridField->State->UserFormsGridField;
|
$fields = new ArrayList();
|
||||||
|
$state = $gridField->State->UserFormsGridField;
|
||||||
|
|
||||||
$selectedField = $state->filter;
|
$selectedField = $state->filter;
|
||||||
$selectedValue = $state->value;
|
$selectedValue = $state->value;
|
||||||
|
|
||||||
// show dropdown of all the fields available from the submitted form fields
|
// show dropdown of all the fields available from the submitted form fields
|
||||||
// that have been saved. Takes the titles from the currently live form.
|
// that have been saved. Takes the titles from the currently live form.
|
||||||
$columnField = new DropdownField('FieldNameFilter', '');
|
$columnField = new DropdownField('FieldNameFilter', '');
|
||||||
$columnField->setSource($this->columns);
|
$columnField->setSource($this->columns);
|
||||||
$columnField->setEmptyString(_t('UserFormsGridFieldFilterHeader.FILTERSUBMISSIONS', 'Filter Submissions..'));
|
$columnField->setEmptyString(_t('UserFormsGridFieldFilterHeader.FILTERSUBMISSIONS', 'Filter Submissions..'));
|
||||||
$columnField->setHasEmptyDefault(true);
|
$columnField->setHasEmptyDefault(true);
|
||||||
$columnField->setValue($selectedField);
|
$columnField->setValue($selectedField);
|
||||||
|
|
||||||
$valueField = new TextField('FieldValue', '', $selectedValue);
|
$valueField = new TextField('FieldValue', '', $selectedValue);
|
||||||
|
|
||||||
$columnField->addExtraClass('ss-gridfield-sort');
|
$columnField->addExtraClass('ss-gridfield-sort');
|
||||||
$columnField->addExtraClass('no-change-track');
|
$columnField->addExtraClass('no-change-track');
|
||||||
|
|
||||||
$valueField->addExtraClass('ss-gridfield-sort');
|
$valueField->addExtraClass('ss-gridfield-sort');
|
||||||
$valueField->addExtraClass('no-change-track');
|
$valueField->addExtraClass('no-change-track');
|
||||||
$valueField->setAttribute(
|
$valueField->setAttribute(
|
||||||
'placeholder',
|
'placeholder',
|
||||||
_t('UserFormsGridFieldFilterHeader.WHEREVALUEIS', 'where value is..'
|
_t('UserFormsGridFieldFilterHeader.WHEREVALUEIS', 'where value is..'
|
||||||
));
|
));
|
||||||
|
|
||||||
$fields->push(new FieldGroup(new CompositeField(
|
$fields->push(new FieldGroup(new CompositeField(
|
||||||
$columnField,
|
$columnField,
|
||||||
$valueField
|
$valueField
|
||||||
)));
|
)));
|
||||||
|
|
||||||
$fields->push(new FieldGroup(new CompositeField(
|
$fields->push(new FieldGroup(new CompositeField(
|
||||||
$start = new DateField('StartFilter', _t('UserFormsGridFieldFilterHeader.FROM', 'From')),
|
$start = new DateField('StartFilter', _t('UserFormsGridFieldFilterHeader.FROM', 'From')),
|
||||||
$end = new DateField('EndFilter', _t('UserFormsGridFieldFilterHeader.TILL', 'Till'))
|
$end = new DateField('EndFilter', _t('UserFormsGridFieldFilterHeader.TILL', 'Till'))
|
||||||
)));
|
)));
|
||||||
|
|
||||||
foreach(array($start, $end) as $date) {
|
foreach (array($start, $end) as $date) {
|
||||||
$date->setConfig('showcalendar', true);
|
$date->setConfig('showcalendar', true);
|
||||||
$date->setConfig('dateformat', 'y-mm-dd');
|
$date->setConfig('dateformat', 'y-mm-dd');
|
||||||
$date->setConfig('datavalueformat', 'y-mm-dd');
|
$date->setConfig('datavalueformat', 'y-mm-dd');
|
||||||
$date->addExtraClass('no-change-track');
|
$date->addExtraClass('no-change-track');
|
||||||
}
|
}
|
||||||
|
|
||||||
$end->setValue($state->end);
|
$end->setValue($state->end);
|
||||||
$start->setValue($state->start);
|
$start->setValue($state->start);
|
||||||
|
|
||||||
|
|
||||||
$fields->push($actions = new FieldGroup(
|
$fields->push($actions = new FieldGroup(
|
||||||
GridField_FormAction::create($gridField, 'filter', false, 'filter', null)
|
GridField_FormAction::create($gridField, 'filter', false, 'filter', null)
|
||||||
->addExtraClass('ss-gridfield-button-filter')
|
->addExtraClass('ss-gridfield-button-filter')
|
||||||
->setAttribute('title', _t('GridField.Filter', "Filter"))
|
->setAttribute('title', _t('GridField.Filter', "Filter"))
|
||||||
->setAttribute('id', 'action_filter_' . $gridField->getModelClass() . '_' . $columnField),
|
->setAttribute('id', 'action_filter_' . $gridField->getModelClass() . '_' . $columnField),
|
||||||
GridField_FormAction::create($gridField, 'reset', false, 'reset', null)
|
GridField_FormAction::create($gridField, 'reset', false, 'reset', null)
|
||||||
->addExtraClass('ss-gridfield-button-close')
|
->addExtraClass('ss-gridfield-button-close')
|
||||||
->setAttribute('title', _t('GridField.ResetFilter', "Reset"))
|
->setAttribute('title', _t('GridField.ResetFilter', "Reset"))
|
||||||
->setAttribute('id', 'action_reset_' . $gridField->getModelClass() . '_' . $columnField)
|
->setAttribute('id', 'action_reset_' . $gridField->getModelClass() . '_' . $columnField)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
$actions->addExtraClass('filter-buttons');
|
$actions->addExtraClass('filter-buttons');
|
||||||
$actions->addExtraClass('no-change-track');
|
$actions->addExtraClass('no-change-track');
|
||||||
|
|
||||||
$forTemplate = new ArrayData(array(
|
$forTemplate = new ArrayData(array(
|
||||||
'Fields' => $fields
|
'Fields' => $fields
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
'header' => $forTemplate->renderWith('GridFieldFilterHeader_Row')
|
'header' => $forTemplate->renderWith('GridFieldFilterHeader_Row')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getManipulatedData(GridField $gridField, SS_List $dataList) {
|
public function getManipulatedData(GridField $gridField, SS_List $dataList)
|
||||||
$state = $gridField->State;
|
{
|
||||||
|
$state = $gridField->State;
|
||||||
|
|
||||||
if($filter = $state->UserFormsGridField->toArray()) {
|
if ($filter = $state->UserFormsGridField->toArray()) {
|
||||||
if(isset($filter['filter']) && $filter['filter'] && isset($filter['value']) && $filter['value']) {
|
if (isset($filter['filter']) && $filter['filter'] && isset($filter['value']) && $filter['value']) {
|
||||||
$dataList = $dataList->where(sprintf("
|
$dataList = $dataList->where(sprintf("
|
||||||
SELECT COUNT(*) FROM SubmittedFormField
|
SELECT COUNT(*) FROM SubmittedFormField
|
||||||
WHERE (
|
WHERE (
|
||||||
ParentID = SubmittedForm.ID AND
|
ParentID = SubmittedForm.ID AND
|
||||||
@ -121,24 +126,24 @@ class UserFormsGridFieldFilterHeader extends GridFieldFilterHeader {
|
|||||||
Value LIKE '%s'
|
Value LIKE '%s'
|
||||||
) > 0",
|
) > 0",
|
||||||
|
|
||||||
Convert::raw2sql($filter['filter']),
|
Convert::raw2sql($filter['filter']),
|
||||||
Convert::raw2sql($filter['value'])
|
Convert::raw2sql($filter['value'])
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isset($filter['start']) && $filter['start']) {
|
if (isset($filter['start']) && $filter['start']) {
|
||||||
$dataList = $dataList->filter(array(
|
$dataList = $dataList->filter(array(
|
||||||
'Created:GreaterThan' => $filter['start']
|
'Created:GreaterThan' => $filter['start']
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isset($filter['end']) && $filter['end']) {
|
if (isset($filter['end']) && $filter['end']) {
|
||||||
$dataList = $dataList->filter(array(
|
$dataList = $dataList->filter(array(
|
||||||
'Created:LessThan' => $filter['end']
|
'Created:LessThan' => $filter['end']
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $dataList;
|
return $dataList;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,140 +5,147 @@
|
|||||||
*
|
*
|
||||||
* {@see EditableFileField}
|
* {@see EditableFileField}
|
||||||
*/
|
*/
|
||||||
class SecureEditableFileField extends DataExtension {
|
class SecureEditableFileField extends DataExtension
|
||||||
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Path to secure files location under assets
|
* Path to secure files location under assets
|
||||||
*
|
*
|
||||||
* @config
|
* @config
|
||||||
* @var type
|
* @var type
|
||||||
*/
|
*/
|
||||||
private static $secure_folder_name = 'SecureUploads';
|
private static $secure_folder_name = 'SecureUploads';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disable file security if a user-defined mechanism is in place
|
* Disable file security if a user-defined mechanism is in place
|
||||||
*
|
*
|
||||||
* @config
|
* @config
|
||||||
* @var bool
|
* @var bool
|
||||||
*/
|
*/
|
||||||
private static $disable_security = false;
|
private static $disable_security = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if file security is enabled
|
* Check if file security is enabled
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function getIsSecurityEnabled() {
|
public function getIsSecurityEnabled()
|
||||||
// Skip if requested
|
{
|
||||||
if($this->owner->config()->disable_security) {
|
// Skip if requested
|
||||||
return false;
|
if ($this->owner->config()->disable_security) {
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Check for necessary security module
|
// Check for necessary security module
|
||||||
if(!class_exists('SecureFileExtension')) {
|
if (!class_exists('SecureFileExtension')) {
|
||||||
trigger_error('SecureEditableFileField requires secureassets module', E_USER_WARNING);
|
trigger_error('SecureEditableFileField requires secureassets module', E_USER_WARNING);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function requireDefaultRecords() {
|
public function requireDefaultRecords()
|
||||||
// Skip if disabled
|
{
|
||||||
if(!$this->getIsSecurityEnabled()) {
|
// Skip if disabled
|
||||||
return;
|
if (!$this->getIsSecurityEnabled()) {
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Update all instances of editablefilefield which do NOT have a secure folder assigned
|
// Update all instances of editablefilefield which do NOT have a secure folder assigned
|
||||||
foreach(EditableFileField::get() as $fileField) {
|
foreach (EditableFileField::get() as $fileField) {
|
||||||
// Skip if secured
|
// Skip if secured
|
||||||
if($fileField->getIsSecure()) {
|
if ($fileField->getIsSecure()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Force this field to secure itself on write
|
// Force this field to secure itself on write
|
||||||
$fileField->write(false, false, true);
|
$fileField->write(false, false, true);
|
||||||
DB::alteration_message(
|
DB::alteration_message(
|
||||||
"Restricting editable file field \"{$fileField->Title}\" to secure folder",
|
"Restricting editable file field \"{$fileField->Title}\" to secure folder",
|
||||||
"changed"
|
"changed"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Secure this field before saving
|
* Secure this field before saving
|
||||||
*/
|
*/
|
||||||
public function onBeforeWrite() {
|
public function onBeforeWrite()
|
||||||
$this->makeSecure();
|
{
|
||||||
}
|
$this->makeSecure();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensure this field is secured, but does not write changes to the database
|
* Ensure this field is secured, but does not write changes to the database
|
||||||
*/
|
*/
|
||||||
public function makeSecure() {
|
public function makeSecure()
|
||||||
// Skip if disabled or already secure
|
{
|
||||||
if(!$this->getIsSecurityEnabled() || $this->owner->getIsSecure()) {
|
// Skip if disabled or already secure
|
||||||
return;
|
if (!$this->getIsSecurityEnabled() || $this->owner->getIsSecure()) {
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Ensure folder exists
|
// Ensure folder exists
|
||||||
$folder = $this->owner->Folder();
|
$folder = $this->owner->Folder();
|
||||||
if(!$folder || !$folder->exists()) {
|
if (!$folder || !$folder->exists()) {
|
||||||
// Create new folder in default location
|
// Create new folder in default location
|
||||||
$folder = Folder::find_or_make($this->owner->config()->secure_folder_name);
|
$folder = Folder::find_or_make($this->owner->config()->secure_folder_name);
|
||||||
$this->owner->FolderID = $folder->ID;
|
$this->owner->FolderID = $folder->ID;
|
||||||
|
} elseif ($this->isFolderSecured($folder)) {
|
||||||
|
// If folder exists and is secure stop
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
} elseif($this->isFolderSecured($folder)) {
|
// Make secure
|
||||||
// If folder exists and is secure stop
|
$folder->CanViewType = 'OnlyTheseUsers';
|
||||||
return;
|
$folder->ViewerGroups()->add($this->findAdminGroup());
|
||||||
}
|
$folder->write();
|
||||||
|
}
|
||||||
|
|
||||||
// Make secure
|
/**
|
||||||
$folder->CanViewType = 'OnlyTheseUsers';
|
* Find target group to record
|
||||||
$folder->ViewerGroups()->add($this->findAdminGroup());
|
*
|
||||||
$folder->write();
|
* @return Group
|
||||||
}
|
*/
|
||||||
|
protected function findAdminGroup()
|
||||||
|
{
|
||||||
|
singleton('Group')->requireDefaultRecords();
|
||||||
|
return Permission::get_groups_by_permission('ADMIN')->First();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find target group to record
|
* Determine if the field is secure
|
||||||
*
|
*
|
||||||
* @return Group
|
* @return bool
|
||||||
*/
|
*/
|
||||||
protected function findAdminGroup() {
|
public function getIsSecure()
|
||||||
singleton('Group')->requireDefaultRecords();
|
{
|
||||||
return Permission::get_groups_by_permission('ADMIN')->First();
|
return $this->isFolderSecured($this->owner->Folder());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if the field is secure
|
* Check if a Folder object is secure
|
||||||
*
|
*
|
||||||
* @return bool
|
* @param Folder $folder
|
||||||
*/
|
* @return boolean
|
||||||
public function getIsSecure() {
|
*/
|
||||||
return $this->isFolderSecured($this->owner->Folder());
|
protected function isFolderSecured($folder)
|
||||||
}
|
{
|
||||||
|
if (! ($folder instanceof Folder) || !$folder->exists()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
switch ($folder->CanViewType) {
|
||||||
* Check if a Folder object is secure
|
case 'OnlyTheseUsers':
|
||||||
*
|
return true;
|
||||||
* @param Folder $folder
|
case 'Inherit':
|
||||||
* @return boolean
|
$parent = $folder->Parent();
|
||||||
*/
|
return $parent && $parent->exists() && $this->isFolderSecured($parent);
|
||||||
protected function isFolderSecured($folder) {
|
case 'Anyone':
|
||||||
if(! ($folder instanceof Folder) || !$folder->exists()) {
|
case 'LoggedInUsers':
|
||||||
return false;
|
default:
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
switch($folder->CanViewType) {
|
}
|
||||||
case 'OnlyTheseUsers':
|
|
||||||
return true;
|
|
||||||
case 'Inherit':
|
|
||||||
$parent = $folder->Parent();
|
|
||||||
return $parent && $parent->exists() && $this->isFolderSecured($parent);
|
|
||||||
case 'Anyone':
|
|
||||||
case 'LoggedInUsers':
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -3,235 +3,245 @@
|
|||||||
/**
|
/**
|
||||||
* @package userforms
|
* @package userforms
|
||||||
*/
|
*/
|
||||||
class UserFormFieldEditorExtension extends DataExtension {
|
class UserFormFieldEditorExtension extends DataExtension
|
||||||
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
private static $has_many = array(
|
private static $has_many = array(
|
||||||
'Fields' => 'EditableFormField'
|
'Fields' => 'EditableFormField'
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds the field editor to the page.
|
* Adds the field editor to the page.
|
||||||
*
|
*
|
||||||
* @return FieldList
|
* @return FieldList
|
||||||
*/
|
*/
|
||||||
public function updateCMSFields(FieldList $fields) {
|
public function updateCMSFields(FieldList $fields)
|
||||||
$fieldEditor = $this->getFieldEditorGrid();
|
{
|
||||||
|
$fieldEditor = $this->getFieldEditorGrid();
|
||||||
|
|
||||||
$fields->insertAfter(new Tab('FormFields', _t('UserFormFieldEditorExtension.FORMFIELDS', 'Form Fields')), 'Main');
|
$fields->insertAfter(new Tab('FormFields', _t('UserFormFieldEditorExtension.FORMFIELDS', 'Form Fields')), 'Main');
|
||||||
$fields->addFieldToTab('Root.FormFields', $fieldEditor);
|
$fields->addFieldToTab('Root.FormFields', $fieldEditor);
|
||||||
|
|
||||||
return $fields;
|
return $fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the field editor, for adding and removing EditableFormFields.
|
* Gets the field editor, for adding and removing EditableFormFields.
|
||||||
*
|
*
|
||||||
* @return GridField
|
* @return GridField
|
||||||
*/
|
*/
|
||||||
public function getFieldEditorGrid() {
|
public function getFieldEditorGrid()
|
||||||
Requirements::javascript(USERFORMS_DIR . '/javascript/FieldEditor.js');
|
{
|
||||||
|
Requirements::javascript(USERFORMS_DIR . '/javascript/FieldEditor.js');
|
||||||
|
|
||||||
$fields = $this->owner->Fields();
|
$fields = $this->owner->Fields();
|
||||||
|
|
||||||
$this->createInitialFormStep(true);
|
$this->createInitialFormStep(true);
|
||||||
|
|
||||||
$editableColumns = new GridFieldEditableColumns();
|
$editableColumns = new GridFieldEditableColumns();
|
||||||
$fieldClasses = singleton('EditableFormField')->getEditableFieldClasses();
|
$fieldClasses = singleton('EditableFormField')->getEditableFieldClasses();
|
||||||
$editableColumns->setDisplayFields(array(
|
$editableColumns->setDisplayFields(array(
|
||||||
'ClassName' => function($record, $column, $grid) use ($fieldClasses) {
|
'ClassName' => function ($record, $column, $grid) use ($fieldClasses) {
|
||||||
if($record instanceof EditableFormField) {
|
if ($record instanceof EditableFormField) {
|
||||||
return $record->getInlineClassnameField($column, $fieldClasses);
|
return $record->getInlineClassnameField($column, $fieldClasses);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'Title' => function($record, $column, $grid) {
|
'Title' => function ($record, $column, $grid) {
|
||||||
if($record instanceof EditableFormField) {
|
if ($record instanceof EditableFormField) {
|
||||||
return $record->getInlineTitleField($column);
|
return $record->getInlineTitleField($column);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
|
|
||||||
$config = GridFieldConfig::create()
|
$config = GridFieldConfig::create()
|
||||||
->addComponents(
|
->addComponents(
|
||||||
$editableColumns,
|
$editableColumns,
|
||||||
new GridFieldButtonRow(),
|
new GridFieldButtonRow(),
|
||||||
GridFieldAddClassesButton::create('EditableTextField')
|
GridFieldAddClassesButton::create('EditableTextField')
|
||||||
->setButtonName(_t('UserFormFieldEditorExtension.ADD_FIELD', 'Add Field'))
|
->setButtonName(_t('UserFormFieldEditorExtension.ADD_FIELD', 'Add Field'))
|
||||||
->setButtonClass('ss-ui-action-constructive'),
|
->setButtonClass('ss-ui-action-constructive'),
|
||||||
GridFieldAddClassesButton::create('EditableFormStep')
|
GridFieldAddClassesButton::create('EditableFormStep')
|
||||||
->setButtonName(_t('UserFormFieldEditorExtension.ADD_PAGE_BREAK', 'Add Page Break')),
|
->setButtonName(_t('UserFormFieldEditorExtension.ADD_PAGE_BREAK', 'Add Page Break')),
|
||||||
GridFieldAddClassesButton::create(array('EditableFieldGroup', 'EditableFieldGroupEnd'))
|
GridFieldAddClassesButton::create(array('EditableFieldGroup', 'EditableFieldGroupEnd'))
|
||||||
->setButtonName(_t('UserFormFieldEditorExtension.ADD_FIELD_GROUP', 'Add Field Group')),
|
->setButtonName(_t('UserFormFieldEditorExtension.ADD_FIELD_GROUP', 'Add Field Group')),
|
||||||
new GridFieldEditButton(),
|
new GridFieldEditButton(),
|
||||||
new GridFieldDeleteAction(),
|
new GridFieldDeleteAction(),
|
||||||
new GridFieldToolbarHeader(),
|
new GridFieldToolbarHeader(),
|
||||||
new GridFieldOrderableRows('Sort'),
|
new GridFieldOrderableRows('Sort'),
|
||||||
new GridFieldDetailForm()
|
new GridFieldDetailForm()
|
||||||
);
|
);
|
||||||
|
|
||||||
$fieldEditor = GridField::create(
|
$fieldEditor = GridField::create(
|
||||||
'Fields',
|
'Fields',
|
||||||
_t('UserDefinedForm.FIELDS', 'Fields'),
|
_t('UserDefinedForm.FIELDS', 'Fields'),
|
||||||
$fields,
|
$fields,
|
||||||
$config
|
$config
|
||||||
)->addExtraClass('uf-field-editor');
|
)->addExtraClass('uf-field-editor');
|
||||||
|
|
||||||
return $fieldEditor;
|
return $fieldEditor;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A UserForm must have at least one step.
|
* A UserForm must have at least one step.
|
||||||
* If no steps exist, create an initial step, and put all fields inside it.
|
* If no steps exist, create an initial step, and put all fields inside it.
|
||||||
*
|
*
|
||||||
* @param bool $force
|
* @param bool $force
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function createInitialFormStep($force = false) {
|
public function createInitialFormStep($force = false)
|
||||||
// Only invoke once saved
|
{
|
||||||
if(!$this->owner->exists()) {
|
// Only invoke once saved
|
||||||
return;
|
if (!$this->owner->exists()) {
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if first field is a step
|
// Check if first field is a step
|
||||||
$fields = $this->owner->Fields();
|
$fields = $this->owner->Fields();
|
||||||
$firstField = $fields->first();
|
$firstField = $fields->first();
|
||||||
if($firstField instanceof EditableFormStep) {
|
if ($firstField instanceof EditableFormStep) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't create steps on write if there are no formfields, as this
|
// Don't create steps on write if there are no formfields, as this
|
||||||
// can create duplicate first steps during publish of new records
|
// can create duplicate first steps during publish of new records
|
||||||
if(!$force && !$firstField) {
|
if (!$force && !$firstField) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Re-apply sort to each field starting at 2
|
// Re-apply sort to each field starting at 2
|
||||||
$next = 2;
|
$next = 2;
|
||||||
foreach($fields as $field) {
|
foreach ($fields as $field) {
|
||||||
$field->Sort = $next++;
|
$field->Sort = $next++;
|
||||||
$field->write();
|
$field->write();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add step
|
// Add step
|
||||||
$step = EditableFormStep::create();
|
$step = EditableFormStep::create();
|
||||||
$step->Title = _t('EditableFormStep.TITLE_FIRST', 'First Page');
|
$step->Title = _t('EditableFormStep.TITLE_FIRST', 'First Page');
|
||||||
$step->Sort = 1;
|
$step->Sort = 1;
|
||||||
$step->write();
|
$step->write();
|
||||||
$fields->add($step);
|
$fields->add($step);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensure that at least one page exists at the start
|
* Ensure that at least one page exists at the start
|
||||||
*/
|
*/
|
||||||
public function onAfterWrite() {
|
public function onAfterWrite()
|
||||||
$this->createInitialFormStep();
|
{
|
||||||
}
|
$this->createInitialFormStep();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see SiteTree::doPublish
|
* @see SiteTree::doPublish
|
||||||
* @param Page $original
|
* @param Page $original
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function onAfterPublish($original) {
|
public function onAfterPublish($original)
|
||||||
// Remove fields on the live table which could have been orphaned.
|
{
|
||||||
$live = Versioned::get_by_stage("EditableFormField", "Live")
|
// Remove fields on the live table which could have been orphaned.
|
||||||
->filter('ParentID', $original->ID);
|
$live = Versioned::get_by_stage("EditableFormField", "Live")
|
||||||
|
->filter('ParentID', $original->ID);
|
||||||
|
|
||||||
if($live) {
|
if ($live) {
|
||||||
foreach($live as $field) {
|
foreach ($live as $field) {
|
||||||
$field->doDeleteFromStage('Live');
|
$field->doDeleteFromStage('Live');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach($this->owner->Fields() as $field) {
|
foreach ($this->owner->Fields() as $field) {
|
||||||
$field->doPublish('Stage', 'Live');
|
$field->doPublish('Stage', 'Live');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see SiteTree::doUnpublish
|
* @see SiteTree::doUnpublish
|
||||||
* @param Page $page
|
* @param Page $page
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function onAfterUnpublish($page) {
|
public function onAfterUnpublish($page)
|
||||||
foreach($page->Fields() as $field) {
|
{
|
||||||
$field->doDeleteFromStage('Live');
|
foreach ($page->Fields() as $field) {
|
||||||
}
|
$field->doDeleteFromStage('Live');
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see SiteTree::duplicate
|
* @see SiteTree::duplicate
|
||||||
* @param DataObject $newPage
|
* @param DataObject $newPage
|
||||||
*
|
*
|
||||||
* @return DataObject
|
* @return DataObject
|
||||||
*/
|
*/
|
||||||
public function onAfterDuplicate($newPage) {
|
public function onAfterDuplicate($newPage)
|
||||||
// List of EditableFieldGroups, where the
|
{
|
||||||
// key of the array is the ID of the old end group
|
// List of EditableFieldGroups, where the
|
||||||
$fieldGroups = array();
|
// key of the array is the ID of the old end group
|
||||||
foreach($this->owner->Fields() as $field) {
|
$fieldGroups = array();
|
||||||
$newField = $field->duplicate(false);
|
foreach ($this->owner->Fields() as $field) {
|
||||||
$newField->ParentID = $newPage->ID;
|
$newField = $field->duplicate(false);
|
||||||
$newField->ParentClass = $newPage->ClassName;
|
$newField->ParentID = $newPage->ID;
|
||||||
$newField->Version = 0;
|
$newField->ParentClass = $newPage->ClassName;
|
||||||
$newField->write();
|
$newField->Version = 0;
|
||||||
|
$newField->write();
|
||||||
|
|
||||||
// If we encounter a group start, record it for later use
|
// If we encounter a group start, record it for later use
|
||||||
if($field instanceof EditableFieldGroup) {
|
if ($field instanceof EditableFieldGroup) {
|
||||||
$fieldGroups[$field->EndID] = $newField;
|
$fieldGroups[$field->EndID] = $newField;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we encounter an end group, link it back to the group start
|
// If we encounter an end group, link it back to the group start
|
||||||
if($field instanceof EditableFieldGroupEnd && isset($fieldGroups[$field->ID])) {
|
if ($field instanceof EditableFieldGroupEnd && isset($fieldGroups[$field->ID])) {
|
||||||
$groupStart = $fieldGroups[$field->ID];
|
$groupStart = $fieldGroups[$field->ID];
|
||||||
$groupStart->EndID = $newField->ID;
|
$groupStart->EndID = $newField->ID;
|
||||||
$groupStart->write();
|
$groupStart->write();
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($field->DisplayRules() as $customRule) {
|
foreach ($field->DisplayRules() as $customRule) {
|
||||||
$newRule = $customRule->duplicate(false);
|
$newRule = $customRule->duplicate(false);
|
||||||
$newRule->ParentID = $newField->ID;
|
$newRule->ParentID = $newField->ID;
|
||||||
$newRule->Version = 0;
|
$newRule->Version = 0;
|
||||||
$newRule->write();
|
$newRule->write();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $newPage;
|
return $newPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see SiteTree::getIsModifiedOnStage
|
* @see SiteTree::getIsModifiedOnStage
|
||||||
* @param boolean $isModified
|
* @param boolean $isModified
|
||||||
*
|
*
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function getIsModifiedOnStage($isModified) {
|
public function getIsModifiedOnStage($isModified)
|
||||||
if(!$isModified) {
|
{
|
||||||
foreach($this->owner->Fields() as $field) {
|
if (!$isModified) {
|
||||||
if($field->getIsModifiedOnStage()) {
|
foreach ($this->owner->Fields() as $field) {
|
||||||
$isModified = true;
|
if ($field->getIsModifiedOnStage()) {
|
||||||
break;
|
$isModified = true;
|
||||||
}
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return $isModified;
|
return $isModified;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see SiteTree::doRevertToLive
|
* @see SiteTree::doRevertToLive
|
||||||
* @param Page $page
|
* @param Page $page
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function onAfterRevertToLive($page) {
|
public function onAfterRevertToLive($page)
|
||||||
foreach($page->Fields() as $field) {
|
{
|
||||||
$field->publish('Live', 'Stage', false);
|
foreach ($page->Fields() as $field) {
|
||||||
$field->writeWithoutVersion();
|
$field->publish('Live', 'Stage', false);
|
||||||
}
|
$field->writeWithoutVersion();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,126 +1,128 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
|
||||||
class UserFormValidator extends RequiredFields {
|
class UserFormValidator extends RequiredFields
|
||||||
public function php($data) {
|
{
|
||||||
if(!parent::php($data)) {
|
public function php($data)
|
||||||
return false;
|
{
|
||||||
}
|
if (!parent::php($data)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Skip unsaved records
|
// Skip unsaved records
|
||||||
if(empty($data['ID']) || !is_numeric($data['ID'])) {
|
if (empty($data['ID']) || !is_numeric($data['ID'])) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
$fields = EditableFormField::get()->filter('ParentID', $data['ID'])->sort('"Sort" ASC');
|
$fields = EditableFormField::get()->filter('ParentID', $data['ID'])->sort('"Sort" ASC');
|
||||||
|
|
||||||
// Current nesting
|
// Current nesting
|
||||||
$stack = array();
|
$stack = array();
|
||||||
$conditionalStep = false; // Is the current step conditional?
|
$conditionalStep = false; // Is the current step conditional?
|
||||||
foreach($fields as $field) {
|
foreach ($fields as $field) {
|
||||||
if($field instanceof EditableFormStep) {
|
if ($field instanceof EditableFormStep) {
|
||||||
// Page at top level, or after another page is ok
|
// Page at top level, or after another page is ok
|
||||||
if(empty($stack) || (count($stack) === 1 && $stack[0] instanceof EditableFormStep)) {
|
if (empty($stack) || (count($stack) === 1 && $stack[0] instanceof EditableFormStep)) {
|
||||||
$stack = array($field);
|
$stack = array($field);
|
||||||
$conditionalStep = $field->EffectiveDisplayRules()->count() > 0;
|
$conditionalStep = $field->EffectiveDisplayRules()->count() > 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->validationError(
|
$this->validationError(
|
||||||
'FormFields',
|
'FormFields',
|
||||||
_t(
|
_t(
|
||||||
"UserFormValidator.UNEXPECTED_BREAK",
|
"UserFormValidator.UNEXPECTED_BREAK",
|
||||||
"Unexpected page break '{name}' inside nested field '{group}'",
|
"Unexpected page break '{name}' inside nested field '{group}'",
|
||||||
array(
|
array(
|
||||||
'name' => $field->CMSTitle,
|
'name' => $field->CMSTitle,
|
||||||
'group' => end($stack)->CMSTitle
|
'group' => end($stack)->CMSTitle
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
'error'
|
'error'
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate no pages
|
// Validate no pages
|
||||||
if(empty($stack)) {
|
if (empty($stack)) {
|
||||||
$this->validationError(
|
$this->validationError(
|
||||||
'FormFields',
|
'FormFields',
|
||||||
_t(
|
_t(
|
||||||
"UserFormValidator.NO_PAGE",
|
"UserFormValidator.NO_PAGE",
|
||||||
"Field '{name}' found before any pages",
|
"Field '{name}' found before any pages",
|
||||||
array(
|
array(
|
||||||
'name' => $field->CMSTitle
|
'name' => $field->CMSTitle
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
'error'
|
'error'
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Nest field group
|
// Nest field group
|
||||||
if($field instanceof EditableFieldGroup) {
|
if ($field instanceof EditableFieldGroup) {
|
||||||
$stack[] = $field;
|
$stack[] = $field;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unnest field group
|
// Unnest field group
|
||||||
if($field instanceof EditableFieldGroupEnd) {
|
if ($field instanceof EditableFieldGroupEnd) {
|
||||||
$top = end($stack);
|
$top = end($stack);
|
||||||
|
|
||||||
// Check that the top is a group at all
|
// Check that the top is a group at all
|
||||||
if(!$top instanceof EditableFieldGroup) {
|
if (!$top instanceof EditableFieldGroup) {
|
||||||
$this->validationError(
|
$this->validationError(
|
||||||
'FormFields',
|
'FormFields',
|
||||||
_t(
|
_t(
|
||||||
"UserFormValidator.UNEXPECTED_GROUP_END",
|
"UserFormValidator.UNEXPECTED_GROUP_END",
|
||||||
"'{name}' found without a matching group",
|
"'{name}' found without a matching group",
|
||||||
array(
|
array(
|
||||||
'name' => $field->CMSTitle
|
'name' => $field->CMSTitle
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
'error'
|
'error'
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that the top is the right group
|
// Check that the top is the right group
|
||||||
if($top->EndID != $field->ID) {
|
if ($top->EndID != $field->ID) {
|
||||||
$this->validationError(
|
$this->validationError(
|
||||||
'FormFields',
|
'FormFields',
|
||||||
_t(
|
_t(
|
||||||
"UserFormValidator.WRONG_GROUP_END",
|
"UserFormValidator.WRONG_GROUP_END",
|
||||||
"'{name}' found closes the wrong group '{group}'",
|
"'{name}' found closes the wrong group '{group}'",
|
||||||
array(
|
array(
|
||||||
'name' => $field->CMSTitle,
|
'name' => $field->CMSTitle,
|
||||||
'group' => $top->CMSTitle
|
'group' => $top->CMSTitle
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
'error'
|
'error'
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unnest group
|
// Unnest group
|
||||||
array_pop($stack);
|
array_pop($stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normal field type
|
// Normal field type
|
||||||
if($conditionalStep && $field->Required) {
|
if ($conditionalStep && $field->Required) {
|
||||||
$this->validationError(
|
$this->validationError(
|
||||||
'FormFields',
|
'FormFields',
|
||||||
_t(
|
_t(
|
||||||
"UserFormValidator.CONDITIONAL_REQUIRED",
|
"UserFormValidator.CONDITIONAL_REQUIRED",
|
||||||
"Required field '{name}' cannot be placed within a conditional page",
|
"Required field '{name}' cannot be placed within a conditional page",
|
||||||
array(
|
array(
|
||||||
'name' => $field->CMSTitle
|
'name' => $field->CMSTitle
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
'error'
|
'error'
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,63 +3,65 @@
|
|||||||
/**
|
/**
|
||||||
* @package userforms
|
* @package userforms
|
||||||
*/
|
*/
|
||||||
class UserFormsCheckboxSetField extends CheckboxSetField {
|
class UserFormsCheckboxSetField extends CheckboxSetField
|
||||||
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* jQuery validate requires that the value of the option does not contain
|
* jQuery validate requires that the value of the option does not contain
|
||||||
* the actual value of the input.
|
* the actual value of the input.
|
||||||
*
|
*
|
||||||
* @return ArrayList
|
* @return ArrayList
|
||||||
*/
|
*/
|
||||||
public function getOptions() {
|
public function getOptions()
|
||||||
$options = parent::getOptions();
|
{
|
||||||
|
$options = parent::getOptions();
|
||||||
|
|
||||||
foreach($options as $option) {
|
foreach ($options as $option) {
|
||||||
$option->Name = "{$this->name}[]";
|
$option->Name = "{$this->name}[]";
|
||||||
}
|
}
|
||||||
|
|
||||||
return $options;
|
return $options;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function getSourceAsArray()
|
public function getSourceAsArray()
|
||||||
{
|
{
|
||||||
$array = parent::getSourceAsArray();
|
$array = parent::getSourceAsArray();
|
||||||
|
|
||||||
return array_values($array);
|
return array_values($array);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*
|
*
|
||||||
* @param Validator $validator
|
* @param Validator $validator
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function validate($validator)
|
public function validate($validator)
|
||||||
{
|
{
|
||||||
// get the previous values (could contain comma-delimited list)
|
// get the previous values (could contain comma-delimited list)
|
||||||
|
|
||||||
$previous = $value = $this->Value();
|
$previous = $value = $this->Value();
|
||||||
|
|
||||||
if (is_string($value) && strstr($value, ",")) {
|
if (is_string($value) && strstr($value, ",")) {
|
||||||
$value = explode(",", $value);
|
$value = explode(",", $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the value as an array for parent validation
|
// set the value as an array for parent validation
|
||||||
|
|
||||||
$this->setValue($value);
|
$this->setValue($value);
|
||||||
|
|
||||||
$validated = parent::validate($validator);
|
$validated = parent::validate($validator);
|
||||||
|
|
||||||
// restore previous value after validation
|
// restore previous value after validation
|
||||||
|
|
||||||
$this->setValue($previous);
|
$this->setValue($previous);
|
||||||
|
|
||||||
return $validated;
|
return $validated;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,45 +3,49 @@
|
|||||||
/**
|
/**
|
||||||
* Represents a composite field group, which may contain other groups
|
* Represents a composite field group, which may contain other groups
|
||||||
*/
|
*/
|
||||||
abstract class UserFormsCompositeField extends CompositeField implements UserFormsFieldContainer {
|
abstract class UserFormsCompositeField extends CompositeField implements UserFormsFieldContainer
|
||||||
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parent field
|
* Parent field
|
||||||
*
|
*
|
||||||
* @var UserFormsFieldContainer
|
* @var UserFormsFieldContainer
|
||||||
*/
|
*/
|
||||||
protected $parent = null;
|
protected $parent = null;
|
||||||
|
|
||||||
public function getParent() {
|
public function getParent()
|
||||||
return $this->parent;
|
{
|
||||||
}
|
return $this->parent;
|
||||||
|
}
|
||||||
|
|
||||||
public function setParent(UserFormsFieldContainer $parent) {
|
public function setParent(UserFormsFieldContainer $parent)
|
||||||
$this->parent = $parent;
|
{
|
||||||
return $this;
|
$this->parent = $parent;
|
||||||
}
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function processNext(EditableFormField $field) {
|
public function processNext(EditableFormField $field)
|
||||||
// When we find a step, bubble up to the top
|
{
|
||||||
if($field instanceof EditableFormStep) {
|
// When we find a step, bubble up to the top
|
||||||
return $this->getParent()->processNext($field);
|
if ($field instanceof EditableFormStep) {
|
||||||
}
|
return $this->getParent()->processNext($field);
|
||||||
|
}
|
||||||
|
|
||||||
// Skip over fields that don't generate formfields
|
// Skip over fields that don't generate formfields
|
||||||
$formField = $field->getFormField();
|
$formField = $field->getFormField();
|
||||||
if(!$formField) {
|
if (!$formField) {
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save this field
|
// Save this field
|
||||||
$this->push($formField);
|
$this->push($formField);
|
||||||
|
|
||||||
// Nest fields that are containers
|
// Nest fields that are containers
|
||||||
if($formField instanceof UserFormsFieldContainer) {
|
if ($formField instanceof UserFormsFieldContainer) {
|
||||||
return $formField->setParent($this);
|
return $formField->setParent($this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add any subsequent fields to this
|
// Add any subsequent fields to this
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,28 +3,29 @@
|
|||||||
/**
|
/**
|
||||||
* Represents a field container which can iteratively process nested fields, converting it into a fieldset
|
* Represents a field container which can iteratively process nested fields, converting it into a fieldset
|
||||||
*/
|
*/
|
||||||
interface UserFormsFieldContainer {
|
interface UserFormsFieldContainer
|
||||||
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process the next field in the list, returning the container to add the next field to.
|
* Process the next field in the list, returning the container to add the next field to.
|
||||||
*
|
*
|
||||||
* @param EditableFormField $field
|
* @param EditableFormField $field
|
||||||
* @return EditableContainerField
|
* @return EditableContainerField
|
||||||
*/
|
*/
|
||||||
public function processNext(EditableFormField $field);
|
public function processNext(EditableFormField $field);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the parent
|
* Set the parent
|
||||||
*
|
*
|
||||||
* @param UserFormsFieldContainer $parent
|
* @param UserFormsFieldContainer $parent
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function setParent(UserFormsFieldContainer $parent);
|
public function setParent(UserFormsFieldContainer $parent);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the parent
|
* Get the parent
|
||||||
*
|
*
|
||||||
* @return UserFormsFieldContainer
|
* @return UserFormsFieldContainer
|
||||||
*/
|
*/
|
||||||
public function getParent();
|
public function getParent();
|
||||||
}
|
}
|
||||||
|
@ -3,41 +3,45 @@
|
|||||||
/**
|
/**
|
||||||
* A list of formfields which allows for iterative processing of nested composite fields
|
* A list of formfields which allows for iterative processing of nested composite fields
|
||||||
*/
|
*/
|
||||||
class UserFormsFieldList extends FieldList implements UserFormsFieldContainer {
|
class UserFormsFieldList extends FieldList implements UserFormsFieldContainer
|
||||||
|
{
|
||||||
|
|
||||||
public function processNext(EditableFormField $field) {
|
public function processNext(EditableFormField $field)
|
||||||
$formField = $field->getFormField();
|
{
|
||||||
if(!$formField) {
|
$formField = $field->getFormField();
|
||||||
return $this;
|
if (!$formField) {
|
||||||
}
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
$this->push($formField);
|
$this->push($formField);
|
||||||
|
|
||||||
if($formField instanceof UserFormsFieldContainer) {
|
if ($formField instanceof UserFormsFieldContainer) {
|
||||||
return $formField->setParent($this);
|
return $formField->setParent($this);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getParent() {
|
public function getParent()
|
||||||
// Field list does not have a parent
|
{
|
||||||
return null;
|
// Field list does not have a parent
|
||||||
}
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public function setParent(UserFormsFieldContainer $parent) {
|
public function setParent(UserFormsFieldContainer $parent)
|
||||||
return $this;
|
{
|
||||||
}
|
return $this;
|
||||||
|
}
|
||||||
/**
|
|
||||||
* Remove all empty steps
|
|
||||||
*/
|
|
||||||
public function clearEmptySteps() {
|
|
||||||
foreach($this as $field) {
|
|
||||||
if($field instanceof UserFormsStepField && count($field->getChildren()) === 0) {
|
|
||||||
$this->remove($field);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove all empty steps
|
||||||
|
*/
|
||||||
|
public function clearEmptySteps()
|
||||||
|
{
|
||||||
|
foreach ($this as $field) {
|
||||||
|
if ($field instanceof UserFormsStepField && count($field->getChildren()) === 0) {
|
||||||
|
$this->remove($field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,25 +3,29 @@
|
|||||||
/**
|
/**
|
||||||
* Front end composite field for userforms
|
* Front end composite field for userforms
|
||||||
*/
|
*/
|
||||||
class UserFormsGroupField extends UserFormsCompositeField {
|
class UserFormsGroupField extends UserFormsCompositeField
|
||||||
|
{
|
||||||
|
|
||||||
public function __construct($children = null) {
|
public function __construct($children = null)
|
||||||
parent::__construct($children);
|
{
|
||||||
$this->setTag('fieldset');
|
parent::__construct($children);
|
||||||
}
|
$this->setTag('fieldset');
|
||||||
|
}
|
||||||
|
|
||||||
public function getLegend() {
|
public function getLegend()
|
||||||
// Legend defaults to title
|
{
|
||||||
return parent::getLegend() ?: $this->Title();
|
// Legend defaults to title
|
||||||
}
|
return parent::getLegend() ?: $this->Title();
|
||||||
|
}
|
||||||
|
|
||||||
public function processNext(EditableFormField $field) {
|
public function processNext(EditableFormField $field)
|
||||||
// When ending a group, jump up one level
|
{
|
||||||
if($field instanceof EditableFieldGroupEnd) {
|
// When ending a group, jump up one level
|
||||||
return $this->getParent();
|
if ($field instanceof EditableFieldGroupEnd) {
|
||||||
}
|
return $this->getParent();
|
||||||
|
}
|
||||||
|
|
||||||
// Otherwise behave as per normal composite field
|
// Otherwise behave as per normal composite field
|
||||||
return parent::processNext($field);
|
return parent::processNext($field);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,42 +3,46 @@
|
|||||||
/**
|
/**
|
||||||
* Represents a page step in a form, which may contain form fields or other groups
|
* Represents a page step in a form, which may contain form fields or other groups
|
||||||
*/
|
*/
|
||||||
class UserFormsStepField extends UserFormsCompositeField {
|
class UserFormsStepField extends UserFormsCompositeField
|
||||||
|
{
|
||||||
|
|
||||||
private static $casting = array(
|
private static $casting = array(
|
||||||
'StepNumber' => 'Int'
|
'StepNumber' => 'Int'
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Numeric index (1 based) of this step
|
* Numeric index (1 based) of this step
|
||||||
*
|
*
|
||||||
* Null if unassigned
|
* Null if unassigned
|
||||||
*
|
*
|
||||||
* @var int|null
|
* @var int|null
|
||||||
*/
|
*/
|
||||||
protected $number = null;
|
protected $number = null;
|
||||||
|
|
||||||
public function FieldHolder($properties = array()) {
|
public function FieldHolder($properties = array())
|
||||||
return $this->Field($properties);
|
{
|
||||||
}
|
return $this->Field($properties);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the step number
|
* Get the step number
|
||||||
*
|
*
|
||||||
* @return int|null
|
* @return int|null
|
||||||
*/
|
*/
|
||||||
public function getStepNumber() {
|
public function getStepNumber()
|
||||||
return $this->number;
|
{
|
||||||
}
|
return $this->number;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Re-assign this step to another number
|
* Re-assign this step to another number
|
||||||
*
|
*
|
||||||
* @param type $number
|
* @param type $number
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function setStepNumber($number) {
|
public function setStepNumber($number)
|
||||||
$this->number = $number;
|
{
|
||||||
return $this;
|
$this->number = $number;
|
||||||
}
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,11 +7,13 @@
|
|||||||
* @deprecated since version 4.0
|
* @deprecated since version 4.0
|
||||||
* @package userforms
|
* @package userforms
|
||||||
*/
|
*/
|
||||||
class UserformsTreeDropdownField extends TreeDropdownField {
|
class UserformsTreeDropdownField extends TreeDropdownField
|
||||||
|
{
|
||||||
|
|
||||||
public function __construct($name, $title = null, $sourceObject = 'Group', $keyField = 'ID', $labelField = 'TreeTitle', $showSearch = true) {
|
public function __construct($name, $title = null, $sourceObject = 'Group', $keyField = 'ID', $labelField = 'TreeTitle', $showSearch = true)
|
||||||
parent::__construct($name, $title, $sourceObject, $keyField, $labelField, $showSearch);
|
{
|
||||||
|
parent::__construct($name, $title, $sourceObject, $keyField, $labelField, $showSearch);
|
||||||
|
|
||||||
Deprecation::notice('4.0', __CLASS__ . " is deprecated");
|
Deprecation::notice('4.0', __CLASS__ . " is deprecated");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,230 +3,246 @@
|
|||||||
/**
|
/**
|
||||||
* A button which allows objects to be created with a specified classname(s)
|
* A button which allows objects to be created with a specified classname(s)
|
||||||
*/
|
*/
|
||||||
class GridFieldAddClassesButton extends Object implements GridField_HTMLProvider, GridField_ActionProvider {
|
class GridFieldAddClassesButton extends Object implements GridField_HTMLProvider, GridField_ActionProvider
|
||||||
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Name of fragment to insert into
|
* Name of fragment to insert into
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $targetFragment;
|
protected $targetFragment;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Button title
|
* Button title
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $buttonName;
|
protected $buttonName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Additonal CSS classes for the button
|
* Additonal CSS classes for the button
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $buttonClass = null;
|
protected $buttonClass = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class names
|
* Class names
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $modelClasses = null;
|
protected $modelClasses = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $classes Class or list of classes to create.
|
* @param array $classes Class or list of classes to create.
|
||||||
* If you enter more than one class, each click of the "add" button will create one of each
|
* If you enter more than one class, each click of the "add" button will create one of each
|
||||||
* @param string $targetFragment The fragment to render the button into
|
* @param string $targetFragment The fragment to render the button into
|
||||||
*/
|
*/
|
||||||
public function __construct($classes, $targetFragment = 'buttons-before-left') {
|
public function __construct($classes, $targetFragment = 'buttons-before-left')
|
||||||
parent::__construct();
|
{
|
||||||
$this->setClasses($classes);
|
parent::__construct();
|
||||||
$this->setFragment($targetFragment);
|
$this->setClasses($classes);
|
||||||
}
|
$this->setFragment($targetFragment);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Change the button name
|
* Change the button name
|
||||||
*
|
*
|
||||||
* @param string $name
|
* @param string $name
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function setButtonName($name) {
|
public function setButtonName($name)
|
||||||
$this->buttonName = $name;
|
{
|
||||||
return $this;
|
$this->buttonName = $name;
|
||||||
}
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the button name
|
* Get the button name
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getButtonName() {
|
public function getButtonName()
|
||||||
return $this->buttonName;
|
{
|
||||||
}
|
return $this->buttonName;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the fragment name this button is rendered into.
|
* Gets the fragment name this button is rendered into.
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getFragment() {
|
public function getFragment()
|
||||||
return $this->targetFragment;
|
{
|
||||||
}
|
return $this->targetFragment;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the fragment name this button is rendered into.
|
* Sets the fragment name this button is rendered into.
|
||||||
*
|
*
|
||||||
* @param string $fragment
|
* @param string $fragment
|
||||||
* @return GridFieldAddNewInlineButton $this
|
* @return GridFieldAddNewInlineButton $this
|
||||||
*/
|
*/
|
||||||
public function setFragment($fragment) {
|
public function setFragment($fragment)
|
||||||
$this->targetFragment = $fragment;
|
{
|
||||||
return $this;
|
$this->targetFragment = $fragment;
|
||||||
}
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get extra button class
|
* Get extra button class
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getButtonClass() {
|
public function getButtonClass()
|
||||||
return $this->buttonClass;
|
{
|
||||||
}
|
return $this->buttonClass;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets extra CSS classes for this button
|
* Sets extra CSS classes for this button
|
||||||
*
|
*
|
||||||
* @param string $buttonClass
|
* @param string $buttonClass
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function setButtonClass($buttonClass) {
|
public function setButtonClass($buttonClass)
|
||||||
$this->buttonClass = $buttonClass;
|
{
|
||||||
return $this;
|
$this->buttonClass = $buttonClass;
|
||||||
}
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the classes of the objects to create
|
* Get the classes of the objects to create
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function getClasses() {
|
public function getClasses()
|
||||||
return $this->modelClasses;
|
{
|
||||||
}
|
return $this->modelClasses;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the list of classes which can be created, with checks for permissions.
|
* Gets the list of classes which can be created, with checks for permissions.
|
||||||
* Will fallback to the default model class for the given DataGrid
|
* Will fallback to the default model class for the given DataGrid
|
||||||
*
|
*
|
||||||
* @param DataGrid $grid
|
* @param DataGrid $grid
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function getClassesCreate($grid) {
|
public function getClassesCreate($grid)
|
||||||
// Get explicit or fallback class list
|
{
|
||||||
$classes = $this->getClasses();
|
// Get explicit or fallback class list
|
||||||
if(empty($classes) && $grid) {
|
$classes = $this->getClasses();
|
||||||
$classes = array($grid->getModelClass());
|
if (empty($classes) && $grid) {
|
||||||
}
|
$classes = array($grid->getModelClass());
|
||||||
|
}
|
||||||
|
|
||||||
// Filter out classes without permission
|
// Filter out classes without permission
|
||||||
return array_filter($classes, function($class) {
|
return array_filter($classes, function ($class) {
|
||||||
return singleton($class)->canCreate();
|
return singleton($class)->canCreate();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specify the classes to create
|
* Specify the classes to create
|
||||||
*
|
*
|
||||||
* @param array $classes
|
* @param array $classes
|
||||||
*/
|
*/
|
||||||
public function setClasses($classes) {
|
public function setClasses($classes)
|
||||||
if(!is_array($classes)) {
|
{
|
||||||
$classes = $classes ? array($classes) : array();
|
if (!is_array($classes)) {
|
||||||
}
|
$classes = $classes ? array($classes) : array();
|
||||||
$this->modelClasses = $classes;
|
}
|
||||||
}
|
$this->modelClasses = $classes;
|
||||||
|
}
|
||||||
|
|
||||||
public function getHTMLFragments($grid) {
|
public function getHTMLFragments($grid)
|
||||||
// Check create permission
|
{
|
||||||
$singleton = singleton($grid->getModelClass());
|
// Check create permission
|
||||||
if(!$singleton->canCreate()) {
|
$singleton = singleton($grid->getModelClass());
|
||||||
return array();
|
if (!$singleton->canCreate()) {
|
||||||
}
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
// Get button name
|
// Get button name
|
||||||
$buttonName = $this->getButtonName();
|
$buttonName = $this->getButtonName();
|
||||||
if(!$buttonName) {
|
if (!$buttonName) {
|
||||||
// provide a default button name, can be changed by calling {@link setButtonName()} on this component
|
// provide a default button name, can be changed by calling {@link setButtonName()} on this component
|
||||||
$objectName = $singleton->i18n_singular_name();
|
$objectName = $singleton->i18n_singular_name();
|
||||||
$buttonName = _t('GridField.Add', 'Add {name}', array('name' => $objectName));
|
$buttonName = _t('GridField.Add', 'Add {name}', array('name' => $objectName));
|
||||||
}
|
}
|
||||||
|
|
||||||
$addAction = new GridField_FormAction(
|
$addAction = new GridField_FormAction(
|
||||||
$grid,
|
$grid,
|
||||||
$this->getAction(),
|
$this->getAction(),
|
||||||
$buttonName,
|
$buttonName,
|
||||||
$this->getAction(),
|
$this->getAction(),
|
||||||
array()
|
array()
|
||||||
);
|
);
|
||||||
$addAction->setAttribute('data-icon', 'add');
|
$addAction->setAttribute('data-icon', 'add');
|
||||||
|
|
||||||
if($this->getButtonClass()) {
|
if ($this->getButtonClass()) {
|
||||||
$addAction->addExtraClass($this->getButtonClass());
|
$addAction->addExtraClass($this->getButtonClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
$this->targetFragment => $addAction->forTemplate()
|
$this->targetFragment => $addAction->forTemplate()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public function getActions($gridField) {
|
public function getActions($gridField)
|
||||||
return array(
|
{
|
||||||
$this->getAction()
|
return array(
|
||||||
);
|
$this->getAction()
|
||||||
}
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the action suburl for this component
|
* Get the action suburl for this component
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected function getAction() {
|
protected function getAction()
|
||||||
return 'add-classes-' . strtolower(implode('-', $this->getClasses()));
|
{
|
||||||
}
|
return 'add-classes-' . strtolower(implode('-', $this->getClasses()));
|
||||||
|
}
|
||||||
|
|
||||||
public function handleAction(GridField $gridField, $actionName, $arguments, $data) {
|
public function handleAction(GridField $gridField, $actionName, $arguments, $data)
|
||||||
switch(strtolower($actionName)) {
|
{
|
||||||
case $this->getAction():
|
switch (strtolower($actionName)) {
|
||||||
return $this->handleAdd($gridField);
|
case $this->getAction():
|
||||||
default:
|
return $this->handleAdd($gridField);
|
||||||
return null;
|
default:
|
||||||
}
|
return null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles adding a new instance of a selected class.
|
* Handles adding a new instance of a selected class.
|
||||||
*
|
*
|
||||||
* @param GridField $grid
|
* @param GridField $grid
|
||||||
* @return null
|
* @return null
|
||||||
*/
|
*/
|
||||||
public function handleAdd($grid) {
|
public function handleAdd($grid)
|
||||||
$classes = $this->getClassesCreate($grid);
|
{
|
||||||
if(empty($classes)) {
|
$classes = $this->getClassesCreate($grid);
|
||||||
throw new SS_HTTPResponse_Exception(400);
|
if (empty($classes)) {
|
||||||
}
|
throw new SS_HTTPResponse_Exception(400);
|
||||||
|
}
|
||||||
|
|
||||||
// Add item to gridfield
|
// Add item to gridfield
|
||||||
$list = $grid->getList();
|
$list = $grid->getList();
|
||||||
foreach($classes as $class) {
|
foreach ($classes as $class) {
|
||||||
$item = $class::create();
|
$item = $class::create();
|
||||||
$item->write();
|
$item->write();
|
||||||
$list->add($item);
|
$list->add($item);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Should trigger a simple reload
|
// Should trigger a simple reload
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,167 +3,175 @@
|
|||||||
/**
|
/**
|
||||||
* @package userforms
|
* @package userforms
|
||||||
*/
|
*/
|
||||||
class UserForm extends Form {
|
class UserForm extends Form
|
||||||
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Controller $controller
|
* @param Controller $controller
|
||||||
* @param string $name
|
* @param string $name
|
||||||
*/
|
*/
|
||||||
public function __construct(Controller $controller, $name = 'Form') {
|
public function __construct(Controller $controller, $name = 'Form')
|
||||||
|
{
|
||||||
|
$this->controller = $controller;
|
||||||
|
$this->setRedirectToFormOnValidationError(true);
|
||||||
|
|
||||||
$this->controller = $controller;
|
parent::__construct(
|
||||||
$this->setRedirectToFormOnValidationError(true);
|
$controller,
|
||||||
|
$name,
|
||||||
|
new FieldList(),
|
||||||
|
new FieldList()
|
||||||
|
);
|
||||||
|
|
||||||
parent::__construct(
|
$this->setFields($fields = $this->getFormFields());
|
||||||
$controller,
|
$fields->setForm($this);
|
||||||
$name,
|
$this->setActions($actions = $this->getFormActions());
|
||||||
new FieldList(),
|
$actions->setForm($this);
|
||||||
new FieldList()
|
$this->setValidator($this->getRequiredFields());
|
||||||
);
|
|
||||||
|
|
||||||
$this->setFields($fields = $this->getFormFields());
|
// This needs to be re-evaluated since fields have been assigned
|
||||||
$fields->setForm($this);
|
$this->setupFormErrors();
|
||||||
$this->setActions($actions = $this->getFormActions());
|
|
||||||
$actions->setForm($this);
|
|
||||||
$this->setValidator($this->getRequiredFields());
|
|
||||||
|
|
||||||
// This needs to be re-evaluated since fields have been assigned
|
// Number each page
|
||||||
$this->setupFormErrors();
|
$stepNumber = 1;
|
||||||
|
foreach ($this->getSteps() as $step) {
|
||||||
|
$step->setStepNumber($stepNumber++);
|
||||||
|
}
|
||||||
|
|
||||||
// Number each page
|
if ($controller->DisableCsrfSecurityToken) {
|
||||||
$stepNumber = 1;
|
$this->disableSecurityToken();
|
||||||
foreach($this->getSteps() as $step) {
|
}
|
||||||
$step->setStepNumber($stepNumber++);
|
|
||||||
}
|
|
||||||
|
|
||||||
if($controller->DisableCsrfSecurityToken) {
|
$data = Session::get("FormInfo.{$this->FormName()}.data");
|
||||||
$this->disableSecurityToken();
|
|
||||||
}
|
|
||||||
|
|
||||||
$data = Session::get("FormInfo.{$this->FormName()}.data");
|
if (is_array($data)) {
|
||||||
|
$this->loadDataFrom($data);
|
||||||
|
}
|
||||||
|
|
||||||
if(is_array($data)) {
|
$this->extend('updateForm');
|
||||||
$this->loadDataFrom($data);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
$this->extend('updateForm');
|
public function setupFormErrors()
|
||||||
}
|
{
|
||||||
|
// Suppress setupFormErrors if fields haven't been bootstrapped
|
||||||
|
if ($this->fields && $this->fields->exists()) {
|
||||||
|
return parent::setupFormErrors();
|
||||||
|
}
|
||||||
|
|
||||||
public function setupFormErrors()
|
return $this;
|
||||||
{
|
}
|
||||||
// Suppress setupFormErrors if fields haven't been bootstrapped
|
|
||||||
if($this->fields && $this->fields->exists()) {
|
|
||||||
return parent::setupFormErrors();
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
/**
|
||||||
}
|
* Used for partial caching in the template.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getLastEdited()
|
||||||
|
{
|
||||||
|
return $this->controller->LastEdited;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used for partial caching in the template.
|
* @return bool
|
||||||
*
|
*/
|
||||||
* @return string
|
public function getDisplayErrorMessagesAtTop()
|
||||||
*/
|
{
|
||||||
public function getLastEdited() {
|
return (bool)$this->controller->DisplayErrorMessagesAtTop;
|
||||||
return $this->controller->LastEdited;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return bool
|
* Return the fieldlist, filtered to only contain steps
|
||||||
*/
|
*
|
||||||
public function getDisplayErrorMessagesAtTop() {
|
* @return ArrayList
|
||||||
return (bool)$this->controller->DisplayErrorMessagesAtTop;
|
*/
|
||||||
}
|
public function getSteps()
|
||||||
|
{
|
||||||
|
return $this->Fields()->filterByCallback(function ($field) {
|
||||||
|
return $field instanceof UserFormsStepField;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the fieldlist, filtered to only contain steps
|
* Get the form fields for the form on this page. Can modify this FieldSet
|
||||||
*
|
* by using {@link updateFormFields()} on an {@link Extension} subclass which
|
||||||
* @return ArrayList
|
* is applied to this controller.
|
||||||
*/
|
*
|
||||||
public function getSteps() {
|
* This will be a list of top level composite steps
|
||||||
return $this->Fields()->filterByCallback(function($field) {
|
*
|
||||||
return $field instanceof UserFormsStepField;
|
* @return FieldList
|
||||||
});
|
*/
|
||||||
}
|
public function getFormFields()
|
||||||
|
{
|
||||||
|
$fields = new UserFormsFieldList();
|
||||||
|
$target = $fields;
|
||||||
|
foreach ($this->controller->Fields() as $field) {
|
||||||
|
$target = $target->processNext($field);
|
||||||
|
}
|
||||||
|
$fields->clearEmptySteps();
|
||||||
|
$this->extend('updateFormFields', $fields);
|
||||||
|
$fields->setForm($this);
|
||||||
|
return $fields;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the form fields for the form on this page. Can modify this FieldSet
|
* Generate the form actions for the UserDefinedForm. You
|
||||||
* by using {@link updateFormFields()} on an {@link Extension} subclass which
|
* can manipulate these by using {@link updateFormActions()} on
|
||||||
* is applied to this controller.
|
* a decorator.
|
||||||
*
|
*
|
||||||
* This will be a list of top level composite steps
|
* @todo Make form actions editable via their own field editor.
|
||||||
*
|
*
|
||||||
* @return FieldList
|
* @return FieldList
|
||||||
*/
|
*/
|
||||||
public function getFormFields() {
|
public function getFormActions()
|
||||||
$fields = new UserFormsFieldList();
|
{
|
||||||
$target = $fields;
|
$submitText = ($this->controller->SubmitButtonText) ? $this->controller->SubmitButtonText : _t('UserDefinedForm.SUBMITBUTTON', 'Submit');
|
||||||
foreach ($this->controller->Fields() as $field) {
|
$clearText = ($this->controller->ClearButtonText) ? $this->controller->ClearButtonText : _t('UserDefinedForm.CLEARBUTTON', 'Clear');
|
||||||
$target = $target->processNext($field);
|
|
||||||
}
|
|
||||||
$fields->clearEmptySteps();
|
|
||||||
$this->extend('updateFormFields', $fields);
|
|
||||||
$fields->setForm($this);
|
|
||||||
return $fields;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
$actions = new FieldList(
|
||||||
* Generate the form actions for the UserDefinedForm. You
|
new FormAction("process", $submitText)
|
||||||
* can manipulate these by using {@link updateFormActions()} on
|
);
|
||||||
* a decorator.
|
|
||||||
*
|
|
||||||
* @todo Make form actions editable via their own field editor.
|
|
||||||
*
|
|
||||||
* @return FieldList
|
|
||||||
*/
|
|
||||||
public function getFormActions() {
|
|
||||||
$submitText = ($this->controller->SubmitButtonText) ? $this->controller->SubmitButtonText : _t('UserDefinedForm.SUBMITBUTTON', 'Submit');
|
|
||||||
$clearText = ($this->controller->ClearButtonText) ? $this->controller->ClearButtonText : _t('UserDefinedForm.CLEARBUTTON', 'Clear');
|
|
||||||
|
|
||||||
$actions = new FieldList(
|
if ($this->controller->ShowClearButton) {
|
||||||
new FormAction("process", $submitText)
|
$actions->push(new ResetFormAction("clearForm", $clearText));
|
||||||
);
|
}
|
||||||
|
|
||||||
if($this->controller->ShowClearButton) {
|
$this->extend('updateFormActions', $actions);
|
||||||
$actions->push(new ResetFormAction("clearForm", $clearText));
|
$actions->setForm($this);
|
||||||
}
|
return $actions;
|
||||||
|
}
|
||||||
|
|
||||||
$this->extend('updateFormActions', $actions);
|
/**
|
||||||
$actions->setForm($this);
|
* Get the required form fields for this form.
|
||||||
return $actions;
|
*
|
||||||
}
|
* @return RequiredFields
|
||||||
|
*/
|
||||||
|
public function getRequiredFields()
|
||||||
|
{
|
||||||
|
// Generate required field validator
|
||||||
|
$requiredNames = $this
|
||||||
|
->getController()
|
||||||
|
->Fields()
|
||||||
|
->filter('Required', true)
|
||||||
|
->column('Name');
|
||||||
|
$required = new RequiredFields($requiredNames);
|
||||||
|
$this->extend('updateRequiredFields', $required);
|
||||||
|
$required->setForm($this);
|
||||||
|
return $required;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the required form fields for this form.
|
* Override some we can add UserForm specific attributes to the form.
|
||||||
*
|
*
|
||||||
* @return RequiredFields
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function getRequiredFields() {
|
public function getAttributes()
|
||||||
// Generate required field validator
|
{
|
||||||
$requiredNames = $this
|
$attrs = parent::getAttributes();
|
||||||
->getController()
|
|
||||||
->Fields()
|
|
||||||
->filter('Required', true)
|
|
||||||
->column('Name');
|
|
||||||
$required = new RequiredFields($requiredNames);
|
|
||||||
$this->extend('updateRequiredFields', $required);
|
|
||||||
$required->setForm($this);
|
|
||||||
return $required;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
$attrs['class'] = $attrs['class'] . ' userform';
|
||||||
* Override some we can add UserForm specific attributes to the form.
|
$attrs['data-livevalidation'] = (bool)$this->controller->EnableLiveValidation;
|
||||||
*
|
$attrs['data-toperrors'] = (bool)$this->controller->DisplayErrorMessagesAtTop;
|
||||||
* @return array
|
$attrs['data-hidefieldlabels'] = (bool)$this->controller->HideFieldLabels;
|
||||||
*/
|
|
||||||
public function getAttributes() {
|
|
||||||
$attrs = parent::getAttributes();
|
|
||||||
|
|
||||||
$attrs['class'] = $attrs['class'] . ' userform';
|
return $attrs;
|
||||||
$attrs['data-livevalidation'] = (bool)$this->controller->EnableLiveValidation;
|
}
|
||||||
$attrs['data-toperrors'] = (bool)$this->controller->DisplayErrorMessagesAtTop;
|
|
||||||
$attrs['data-hidefieldlabels'] = (bool)$this->controller->HideFieldLabels;
|
|
||||||
|
|
||||||
return $attrs;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -7,100 +7,107 @@
|
|||||||
* @method EditableFormField Parent()
|
* @method EditableFormField Parent()
|
||||||
* @package userforms
|
* @package userforms
|
||||||
*/
|
*/
|
||||||
class EditableCustomRule extends DataObject {
|
class EditableCustomRule extends DataObject
|
||||||
|
{
|
||||||
|
|
||||||
private static $condition_options = array(
|
private static $condition_options = array(
|
||||||
"IsBlank" => "Is blank",
|
"IsBlank" => "Is blank",
|
||||||
"IsNotBlank" => "Is not blank",
|
"IsNotBlank" => "Is not blank",
|
||||||
"HasValue" => "Equals",
|
"HasValue" => "Equals",
|
||||||
"ValueNot" => "Doesn't equal",
|
"ValueNot" => "Doesn't equal",
|
||||||
"ValueLessThan" => "Less than",
|
"ValueLessThan" => "Less than",
|
||||||
"ValueLessThanEqual" => "Less than or equal",
|
"ValueLessThanEqual" => "Less than or equal",
|
||||||
"ValueGreaterThan" => "Greater than",
|
"ValueGreaterThan" => "Greater than",
|
||||||
"ValueGreaterThanEqual" => "Greater than or equal"
|
"ValueGreaterThanEqual" => "Greater than or equal"
|
||||||
);
|
);
|
||||||
|
|
||||||
private static $db = array(
|
private static $db = array(
|
||||||
'Display' => 'Enum("Show,Hide")',
|
'Display' => 'Enum("Show,Hide")',
|
||||||
'ConditionOption' => 'Enum("IsBlank,IsNotBlank,HasValue,ValueNot,ValueLessThan,ValueLessThanEqual,ValueGreaterThan,ValueGreaterThanEqual")',
|
'ConditionOption' => 'Enum("IsBlank,IsNotBlank,HasValue,ValueNot,ValueLessThan,ValueLessThanEqual,ValueGreaterThan,ValueGreaterThanEqual")',
|
||||||
'FieldValue' => 'Varchar(255)'
|
'FieldValue' => 'Varchar(255)'
|
||||||
);
|
);
|
||||||
|
|
||||||
private static $has_one = array(
|
private static $has_one = array(
|
||||||
'Parent' => 'EditableFormField',
|
'Parent' => 'EditableFormField',
|
||||||
'ConditionField' => 'EditableFormField'
|
'ConditionField' => 'EditableFormField'
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Built in extensions required
|
* Built in extensions required
|
||||||
*
|
*
|
||||||
* @config
|
* @config
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
private static $extensions = array(
|
private static $extensions = array(
|
||||||
"Versioned('Stage', 'Live')"
|
"Versioned('Stage', 'Live')"
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Publish this custom rule to the live site
|
* Publish this custom rule to the live site
|
||||||
*
|
*
|
||||||
* Wrapper for the {@link Versioned} publish function
|
* Wrapper for the {@link Versioned} publish function
|
||||||
*/
|
*/
|
||||||
public function doPublish($fromStage, $toStage, $createNewVersion = false) {
|
public function doPublish($fromStage, $toStage, $createNewVersion = false)
|
||||||
$this->publish($fromStage, $toStage, $createNewVersion);
|
{
|
||||||
}
|
$this->publish($fromStage, $toStage, $createNewVersion);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete this custom rule from a given stage
|
* Delete this custom rule from a given stage
|
||||||
*
|
*
|
||||||
* Wrapper for the {@link Versioned} deleteFromStage function
|
* Wrapper for the {@link Versioned} deleteFromStage function
|
||||||
*/
|
*/
|
||||||
public function doDeleteFromStage($stage) {
|
public function doDeleteFromStage($stage)
|
||||||
$this->deleteFromStage($stage);
|
{
|
||||||
}
|
$this->deleteFromStage($stage);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Member $member
|
* @param Member $member
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function canDelete($member = null) {
|
public function canDelete($member = null)
|
||||||
return $this->canEdit($member);
|
{
|
||||||
}
|
return $this->canEdit($member);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Member $member
|
* @param Member $member
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function canEdit($member = null) {
|
public function canEdit($member = null)
|
||||||
|
{
|
||||||
return $this->Parent()->canEdit($member);
|
return $this->Parent()->canEdit($member);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Member $member
|
* @param Member $member
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function canView($member = null) {
|
public function canView($member = null)
|
||||||
return $this->Parent()->canView($member);
|
{
|
||||||
}
|
return $this->Parent()->canView($member);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return whether a user can create an object of this type
|
* Return whether a user can create an object of this type
|
||||||
*
|
*
|
||||||
* @param Member $member
|
* @param Member $member
|
||||||
* @param array $context Virtual parameter to allow context to be passed in to check
|
* @param array $context Virtual parameter to allow context to be passed in to check
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function canCreate($member = null) {
|
public function canCreate($member = null)
|
||||||
// Check parent page
|
{
|
||||||
|
// Check parent page
|
||||||
$parent = $this->getCanCreateContext(func_get_args());
|
$parent = $this->getCanCreateContext(func_get_args());
|
||||||
if($parent) {
|
if ($parent) {
|
||||||
return $parent->canEdit($member);
|
return $parent->canEdit($member);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fall back to secure admin permissions
|
// Fall back to secure admin permissions
|
||||||
return parent::canCreate($member);
|
return parent::canCreate($member);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to check the parent for this object
|
* Helper method to check the parent for this object
|
||||||
@ -108,13 +115,14 @@ class EditableCustomRule extends DataObject {
|
|||||||
* @param array $args List of arguments passed to canCreate
|
* @param array $args List of arguments passed to canCreate
|
||||||
* @return DataObject Some parent dataobject to inherit permissions from
|
* @return DataObject Some parent dataobject to inherit permissions from
|
||||||
*/
|
*/
|
||||||
protected function getCanCreateContext($args) {
|
protected function getCanCreateContext($args)
|
||||||
|
{
|
||||||
// Inspect second parameter to canCreate for a 'Parent' context
|
// Inspect second parameter to canCreate for a 'Parent' context
|
||||||
if(isset($args[1]['Parent'])) {
|
if (isset($args[1]['Parent'])) {
|
||||||
return $args[1]['Parent'];
|
return $args[1]['Parent'];
|
||||||
}
|
}
|
||||||
// Hack in currently edited page if context is missing
|
// Hack in currently edited page if context is missing
|
||||||
if(Controller::has_curr() && Controller::curr() instanceof CMSMain) {
|
if (Controller::has_curr() && Controller::curr() instanceof CMSMain) {
|
||||||
return Controller::curr()->currentPage();
|
return Controller::curr()->currentPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,7 +134,8 @@ class EditableCustomRule extends DataObject {
|
|||||||
* @param Member $member
|
* @param Member $member
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function canPublish($member = null) {
|
public function canPublish($member = null)
|
||||||
|
{
|
||||||
return $this->canEdit($member);
|
return $this->canEdit($member);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,7 +143,8 @@ class EditableCustomRule extends DataObject {
|
|||||||
* @param Member $member
|
* @param Member $member
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function canUnpublish($member = null) {
|
public function canUnpublish($member = null)
|
||||||
|
{
|
||||||
return $this->canDelete($member);
|
return $this->canDelete($member);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,178 +4,180 @@
|
|||||||
* @package userforms
|
* @package userforms
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class UserDefinedForm extends Page {
|
class UserDefinedForm extends Page
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private static $icon = 'userforms/images/sitetree_icon.png';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private static $icon = 'userforms/images/sitetree_icon.png';
|
private static $description = 'Adds a customizable form.';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var string Required Identifier
|
||||||
*/
|
*/
|
||||||
private static $description = 'Adds a customizable form.';
|
private static $required_identifier = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string Required Identifier
|
* @var string
|
||||||
*/
|
*/
|
||||||
private static $required_identifier = null;
|
private static $email_template_directory = 'userforms/templates/email/';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string
|
* Should this module automatically upgrade on dev/build?
|
||||||
*/
|
*
|
||||||
private static $email_template_directory = 'userforms/templates/email/';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Should this module automatically upgrade on dev/build?
|
|
||||||
*
|
|
||||||
* @config
|
|
||||||
* @var bool
|
|
||||||
*/
|
|
||||||
private static $upgrade_on_build = true;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Built in extensions required by this page
|
|
||||||
* @config
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
private static $extensions = array(
|
|
||||||
'UserFormFieldEditorExtension'
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var array Fields on the user defined form page.
|
|
||||||
*/
|
|
||||||
private static $db = array(
|
|
||||||
"SubmitButtonText" => "Varchar",
|
|
||||||
"ClearButtonText" => "Varchar",
|
|
||||||
"OnCompleteMessage" => "HTMLText",
|
|
||||||
"ShowClearButton" => "Boolean",
|
|
||||||
'DisableSaveSubmissions' => 'Boolean',
|
|
||||||
'EnableLiveValidation' => 'Boolean',
|
|
||||||
'HideFieldLabels' => 'Boolean',
|
|
||||||
'DisplayErrorMessagesAtTop' => 'Boolean',
|
|
||||||
'DisableAuthenicatedFinishAction' => 'Boolean',
|
|
||||||
'DisableCsrfSecurityToken' => 'Boolean'
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var array Default values of variables when this page is created
|
|
||||||
*/
|
|
||||||
private static $defaults = array(
|
|
||||||
'Content' => '$UserDefinedForm',
|
|
||||||
'DisableSaveSubmissions' => 0,
|
|
||||||
'OnCompleteMessage' => '<p>Thanks, we\'ve received your submission.</p>'
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
private static $has_many = array(
|
|
||||||
"Submissions" => "SubmittedForm",
|
|
||||||
"EmailRecipients" => "UserDefinedForm_EmailRecipient"
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var array
|
|
||||||
* @config
|
|
||||||
*/
|
|
||||||
private static $casting = array(
|
|
||||||
'ErrorContainerID' => 'Text'
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Error container selector which matches the element for grouped messages
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
* @config
|
|
||||||
*/
|
|
||||||
private static $error_container_id = 'error-container';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The configuration used to determine whether a confirmation message is to
|
|
||||||
* appear when navigating away from a partially completed form.
|
|
||||||
*
|
|
||||||
* @var boolean
|
|
||||||
* @config
|
|
||||||
*/
|
|
||||||
private static $enable_are_you_sure = true;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var bool
|
|
||||||
* @config
|
* @config
|
||||||
*/
|
* @var bool
|
||||||
private static $recipients_warning_enabled = false;
|
*/
|
||||||
|
private static $upgrade_on_build = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Temporary storage of field ids when the form is duplicated.
|
* Built in extensions required by this page
|
||||||
* Example layout: array('EditableCheckbox3' => 'EditableCheckbox14')
|
* @config
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $fieldsFromTo = array();
|
private static $extensions = array(
|
||||||
|
'UserFormFieldEditorExtension'
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return FieldList
|
* @var array Fields on the user defined form page.
|
||||||
*/
|
*/
|
||||||
public function getCMSFields() {
|
private static $db = array(
|
||||||
Requirements::css(USERFORMS_DIR . '/css/UserForm_cms.css');
|
"SubmitButtonText" => "Varchar",
|
||||||
|
"ClearButtonText" => "Varchar",
|
||||||
|
"OnCompleteMessage" => "HTMLText",
|
||||||
|
"ShowClearButton" => "Boolean",
|
||||||
|
'DisableSaveSubmissions' => 'Boolean',
|
||||||
|
'EnableLiveValidation' => 'Boolean',
|
||||||
|
'HideFieldLabels' => 'Boolean',
|
||||||
|
'DisplayErrorMessagesAtTop' => 'Boolean',
|
||||||
|
'DisableAuthenicatedFinishAction' => 'Boolean',
|
||||||
|
'DisableCsrfSecurityToken' => 'Boolean'
|
||||||
|
);
|
||||||
|
|
||||||
$self = $this;
|
/**
|
||||||
|
* @var array Default values of variables when this page is created
|
||||||
|
*/
|
||||||
|
private static $defaults = array(
|
||||||
|
'Content' => '$UserDefinedForm',
|
||||||
|
'DisableSaveSubmissions' => 0,
|
||||||
|
'OnCompleteMessage' => '<p>Thanks, we\'ve received your submission.</p>'
|
||||||
|
);
|
||||||
|
|
||||||
$this->beforeUpdateCMSFields(function($fields) use ($self) {
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private static $has_many = array(
|
||||||
|
"Submissions" => "SubmittedForm",
|
||||||
|
"EmailRecipients" => "UserDefinedForm_EmailRecipient"
|
||||||
|
);
|
||||||
|
|
||||||
// define tabs
|
/**
|
||||||
$fields->findOrMakeTab('Root.FormOptions', _t('UserDefinedForm.CONFIGURATION', 'Configuration'));
|
* @var array
|
||||||
$fields->findOrMakeTab('Root.Recipients', _t('UserDefinedForm.RECIPIENTS', 'Recipients'));
|
* @config
|
||||||
$fields->findOrMakeTab('Root.Submissions', _t('UserDefinedForm.SUBMISSIONS', 'Submissions'));
|
*/
|
||||||
|
private static $casting = array(
|
||||||
|
'ErrorContainerID' => 'Text'
|
||||||
|
);
|
||||||
|
|
||||||
// text to show on complete
|
/**
|
||||||
$onCompleteFieldSet = new CompositeField(
|
* Error container selector which matches the element for grouped messages
|
||||||
$label = new LabelField('OnCompleteMessageLabel',_t('UserDefinedForm.ONCOMPLETELABEL', 'Show on completion')),
|
*
|
||||||
$editor = new HtmlEditorField( 'OnCompleteMessage', '', _t('UserDefinedForm.ONCOMPLETEMESSAGE', $self->OnCompleteMessage))
|
* @var string
|
||||||
);
|
* @config
|
||||||
|
*/
|
||||||
|
private static $error_container_id = 'error-container';
|
||||||
|
|
||||||
$onCompleteFieldSet->addExtraClass('field');
|
/**
|
||||||
|
* The configuration used to determine whether a confirmation message is to
|
||||||
|
* appear when navigating away from a partially completed form.
|
||||||
|
*
|
||||||
|
* @var boolean
|
||||||
|
* @config
|
||||||
|
*/
|
||||||
|
private static $enable_are_you_sure = true;
|
||||||
|
|
||||||
$editor->setRows(3);
|
/**
|
||||||
$label->addExtraClass('left');
|
* @var bool
|
||||||
|
* @config
|
||||||
|
*/
|
||||||
|
private static $recipients_warning_enabled = false;
|
||||||
|
|
||||||
// Define config for email recipients
|
/**
|
||||||
$emailRecipientsConfig = GridFieldConfig_RecordEditor::create(10);
|
* Temporary storage of field ids when the form is duplicated.
|
||||||
$emailRecipientsConfig->getComponentByType('GridFieldAddNewButton')
|
* Example layout: array('EditableCheckbox3' => 'EditableCheckbox14')
|
||||||
->setButtonName(
|
* @var array
|
||||||
_t('UserDefinedForm.ADDEMAILRECIPIENT', 'Add Email Recipient')
|
*/
|
||||||
);
|
protected $fieldsFromTo = array();
|
||||||
|
|
||||||
// who do we email on submission
|
/**
|
||||||
$emailRecipients = new GridField(
|
* @return FieldList
|
||||||
'EmailRecipients',
|
*/
|
||||||
_t('UserDefinedForm.EMAILRECIPIENTS', 'Email Recipients'),
|
public function getCMSFields()
|
||||||
$self->EmailRecipients(),
|
{
|
||||||
$emailRecipientsConfig
|
Requirements::css(USERFORMS_DIR . '/css/UserForm_cms.css');
|
||||||
);
|
|
||||||
$emailRecipients
|
|
||||||
->getConfig()
|
|
||||||
->getComponentByType('GridFieldDetailForm')
|
|
||||||
->setItemRequestClass('UserFormRecipientItemRequest');
|
|
||||||
|
|
||||||
$fields->addFieldsToTab('Root.FormOptions', $onCompleteFieldSet);
|
$self = $this;
|
||||||
$fields->addFieldToTab('Root.Recipients', $emailRecipients);
|
|
||||||
$fields->addFieldsToTab('Root.FormOptions', $self->getFormOptions());
|
$this->beforeUpdateCMSFields(function ($fields) use ($self) {
|
||||||
|
|
||||||
|
// define tabs
|
||||||
|
$fields->findOrMakeTab('Root.FormOptions', _t('UserDefinedForm.CONFIGURATION', 'Configuration'));
|
||||||
|
$fields->findOrMakeTab('Root.Recipients', _t('UserDefinedForm.RECIPIENTS', 'Recipients'));
|
||||||
|
$fields->findOrMakeTab('Root.Submissions', _t('UserDefinedForm.SUBMISSIONS', 'Submissions'));
|
||||||
|
|
||||||
|
// text to show on complete
|
||||||
|
$onCompleteFieldSet = new CompositeField(
|
||||||
|
$label = new LabelField('OnCompleteMessageLabel', _t('UserDefinedForm.ONCOMPLETELABEL', 'Show on completion')),
|
||||||
|
$editor = new HtmlEditorField('OnCompleteMessage', '', _t('UserDefinedForm.ONCOMPLETEMESSAGE', $self->OnCompleteMessage))
|
||||||
|
);
|
||||||
|
|
||||||
|
$onCompleteFieldSet->addExtraClass('field');
|
||||||
|
|
||||||
|
$editor->setRows(3);
|
||||||
|
$label->addExtraClass('left');
|
||||||
|
|
||||||
|
// Define config for email recipients
|
||||||
|
$emailRecipientsConfig = GridFieldConfig_RecordEditor::create(10);
|
||||||
|
$emailRecipientsConfig->getComponentByType('GridFieldAddNewButton')
|
||||||
|
->setButtonName(
|
||||||
|
_t('UserDefinedForm.ADDEMAILRECIPIENT', 'Add Email Recipient')
|
||||||
|
);
|
||||||
|
|
||||||
|
// who do we email on submission
|
||||||
|
$emailRecipients = new GridField(
|
||||||
|
'EmailRecipients',
|
||||||
|
_t('UserDefinedForm.EMAILRECIPIENTS', 'Email Recipients'),
|
||||||
|
$self->EmailRecipients(),
|
||||||
|
$emailRecipientsConfig
|
||||||
|
);
|
||||||
|
$emailRecipients
|
||||||
|
->getConfig()
|
||||||
|
->getComponentByType('GridFieldDetailForm')
|
||||||
|
->setItemRequestClass('UserFormRecipientItemRequest');
|
||||||
|
|
||||||
|
$fields->addFieldsToTab('Root.FormOptions', $onCompleteFieldSet);
|
||||||
|
$fields->addFieldToTab('Root.Recipients', $emailRecipients);
|
||||||
|
$fields->addFieldsToTab('Root.FormOptions', $self->getFormOptions());
|
||||||
|
|
||||||
|
|
||||||
// view the submissions
|
// view the submissions
|
||||||
$submissions = new GridField(
|
$submissions = new GridField(
|
||||||
'Submissions',
|
'Submissions',
|
||||||
_t('UserDefinedForm.SUBMISSIONS', 'Submissions'),
|
_t('UserDefinedForm.SUBMISSIONS', 'Submissions'),
|
||||||
$self->Submissions()->sort('Created', 'DESC')
|
$self->Submissions()->sort('Created', 'DESC')
|
||||||
);
|
);
|
||||||
|
|
||||||
// make sure a numeric not a empty string is checked against this int column for SQL server
|
// make sure a numeric not a empty string is checked against this int column for SQL server
|
||||||
$parentID = (!empty($self->ID)) ? (int) $self->ID : 0;
|
$parentID = (!empty($self->ID)) ? (int) $self->ID : 0;
|
||||||
|
|
||||||
// get a list of all field names and values used for print and export CSV views of the GridField below.
|
// get a list of all field names and values used for print and export CSV views of the GridField below.
|
||||||
$columnSQL = <<<SQL
|
$columnSQL = <<<SQL
|
||||||
SELECT "SubmittedFormField"."Name" as "Name", "SubmittedFormField"."Title" as "Title", COALESCE("EditableFormField"."Sort", 999) AS "Sort"
|
SELECT "SubmittedFormField"."Name" as "Name", "SubmittedFormField"."Title" as "Title", COALESCE("EditableFormField"."Sort", 999) AS "Sort"
|
||||||
FROM "SubmittedFormField"
|
FROM "SubmittedFormField"
|
||||||
LEFT JOIN "SubmittedForm" ON "SubmittedForm"."ID" = "SubmittedFormField"."ParentID"
|
LEFT JOIN "SubmittedForm" ON "SubmittedForm"."ID" = "SubmittedFormField"."ParentID"
|
||||||
@ -183,147 +185,152 @@ LEFT JOIN "EditableFormField" ON "EditableFormField"."Title" = "SubmittedFormFie
|
|||||||
WHERE "SubmittedForm"."ParentID" = '$parentID'
|
WHERE "SubmittedForm"."ParentID" = '$parentID'
|
||||||
ORDER BY "Sort", "Title"
|
ORDER BY "Sort", "Title"
|
||||||
SQL;
|
SQL;
|
||||||
// Sanitise periods in title
|
// Sanitise periods in title
|
||||||
$columns = array();
|
$columns = array();
|
||||||
foreach(DB::query($columnSQL)->map() as $name => $title) {
|
foreach (DB::query($columnSQL)->map() as $name => $title) {
|
||||||
$columns[$name] = trim(strtr($title, '.', ' '));
|
$columns[$name] = trim(strtr($title, '.', ' '));
|
||||||
}
|
}
|
||||||
|
|
||||||
$config = new GridFieldConfig();
|
$config = new GridFieldConfig();
|
||||||
$config->addComponent(new GridFieldToolbarHeader());
|
$config->addComponent(new GridFieldToolbarHeader());
|
||||||
$config->addComponent($sort = new GridFieldSortableHeader());
|
$config->addComponent($sort = new GridFieldSortableHeader());
|
||||||
$config->addComponent($filter = new UserFormsGridFieldFilterHeader());
|
$config->addComponent($filter = new UserFormsGridFieldFilterHeader());
|
||||||
$config->addComponent(new GridFieldDataColumns());
|
$config->addComponent(new GridFieldDataColumns());
|
||||||
$config->addComponent(new GridFieldEditButton());
|
$config->addComponent(new GridFieldEditButton());
|
||||||
$config->addComponent(new GridFieldDeleteAction());
|
$config->addComponent(new GridFieldDeleteAction());
|
||||||
$config->addComponent(new GridFieldPageCount('toolbar-header-right'));
|
$config->addComponent(new GridFieldPageCount('toolbar-header-right'));
|
||||||
$config->addComponent($pagination = new GridFieldPaginator(25));
|
$config->addComponent($pagination = new GridFieldPaginator(25));
|
||||||
$config->addComponent(new GridFieldDetailForm());
|
$config->addComponent(new GridFieldDetailForm());
|
||||||
$config->addComponent(new GridFieldButtonRow('after'));
|
$config->addComponent(new GridFieldButtonRow('after'));
|
||||||
$config->addComponent($export = new GridFieldExportButton('buttons-after-left'));
|
$config->addComponent($export = new GridFieldExportButton('buttons-after-left'));
|
||||||
$config->addComponent($print = new GridFieldPrintButton('buttons-after-left'));
|
$config->addComponent($print = new GridFieldPrintButton('buttons-after-left'));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Support for {@link https://github.com/colymba/GridFieldBulkEditingTools}
|
* Support for {@link https://github.com/colymba/GridFieldBulkEditingTools}
|
||||||
*/
|
*/
|
||||||
if(class_exists('GridFieldBulkManager')) {
|
if (class_exists('GridFieldBulkManager')) {
|
||||||
$config->addComponent(new GridFieldBulkManager());
|
$config->addComponent(new GridFieldBulkManager());
|
||||||
}
|
}
|
||||||
|
|
||||||
$sort->setThrowExceptionOnBadDataType(false);
|
$sort->setThrowExceptionOnBadDataType(false);
|
||||||
$filter->setThrowExceptionOnBadDataType(false);
|
$filter->setThrowExceptionOnBadDataType(false);
|
||||||
$pagination->setThrowExceptionOnBadDataType(false);
|
$pagination->setThrowExceptionOnBadDataType(false);
|
||||||
|
|
||||||
// attach every column to the print view form
|
// attach every column to the print view form
|
||||||
$columns['Created'] = 'Created';
|
$columns['Created'] = 'Created';
|
||||||
$filter->setColumns($columns);
|
$filter->setColumns($columns);
|
||||||
|
|
||||||
// print configuration
|
// print configuration
|
||||||
|
|
||||||
$print->setPrintHasHeader(true);
|
$print->setPrintHasHeader(true);
|
||||||
$print->setPrintColumns($columns);
|
$print->setPrintColumns($columns);
|
||||||
|
|
||||||
// export configuration
|
// export configuration
|
||||||
$export->setCsvHasHeader(true);
|
$export->setCsvHasHeader(true);
|
||||||
$export->setExportColumns($columns);
|
$export->setExportColumns($columns);
|
||||||
|
|
||||||
$submissions->setConfig($config);
|
$submissions->setConfig($config);
|
||||||
$fields->addFieldToTab('Root.Submissions', $submissions);
|
$fields->addFieldToTab('Root.Submissions', $submissions);
|
||||||
$fields->addFieldToTab('Root.FormOptions', new CheckboxField('DisableSaveSubmissions', _t('UserDefinedForm.SAVESUBMISSIONS', 'Disable Saving Submissions to Server')));
|
$fields->addFieldToTab('Root.FormOptions', new CheckboxField('DisableSaveSubmissions', _t('UserDefinedForm.SAVESUBMISSIONS', 'Disable Saving Submissions to Server')));
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$fields = parent::getCMSFields();
|
$fields = parent::getCMSFields();
|
||||||
|
|
||||||
if($this->EmailRecipients()->Count() == 0 && static::config()->recipients_warning_enabled) {
|
if ($this->EmailRecipients()->Count() == 0 && static::config()->recipients_warning_enabled) {
|
||||||
$fields->addFieldToTab("Root.Main", new LiteralField("EmailRecipientsWarning",
|
$fields->addFieldToTab("Root.Main", new LiteralField("EmailRecipientsWarning",
|
||||||
"<p class=\"message warning\">" . _t("UserDefinedForm.NORECIPIENTS",
|
"<p class=\"message warning\">" . _t("UserDefinedForm.NORECIPIENTS",
|
||||||
"Warning: You have not configured any recipients. Form submissions may be missed.")
|
"Warning: You have not configured any recipients. Form submissions may be missed.")
|
||||||
. "</p>"), "Title");
|
. "</p>"), "Title");
|
||||||
}
|
}
|
||||||
|
|
||||||
return $fields;
|
return $fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allow overriding the EmailRecipients on a {@link DataExtension}
|
* Allow overriding the EmailRecipients on a {@link DataExtension}
|
||||||
* so you can customise who receives an email.
|
* so you can customise who receives an email.
|
||||||
* Converts the RelationList to an ArrayList so that manipulation
|
* Converts the RelationList to an ArrayList so that manipulation
|
||||||
* of the original source data isn't possible.
|
* of the original source data isn't possible.
|
||||||
*
|
*
|
||||||
* @return ArrayList
|
* @return ArrayList
|
||||||
*/
|
*/
|
||||||
public function FilteredEmailRecipients($data = null, $form = null) {
|
public function FilteredEmailRecipients($data = null, $form = null)
|
||||||
$recipients = new ArrayList($this->EmailRecipients()->toArray());
|
{
|
||||||
|
$recipients = new ArrayList($this->EmailRecipients()->toArray());
|
||||||
|
|
||||||
// Filter by rules
|
// Filter by rules
|
||||||
$recipients = $recipients->filterByCallback(function($recipient) use ($data, $form) {
|
$recipients = $recipients->filterByCallback(function ($recipient) use ($data, $form) {
|
||||||
return $recipient->canSend($data, $form);
|
return $recipient->canSend($data, $form);
|
||||||
});
|
});
|
||||||
|
|
||||||
$this->extend('updateFilteredEmailRecipients', $recipients, $data, $form);
|
$this->extend('updateFilteredEmailRecipients', $recipients, $data, $form);
|
||||||
|
|
||||||
return $recipients;
|
return $recipients;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom options for the form. You can extend the built in options by
|
* Custom options for the form. You can extend the built in options by
|
||||||
* using {@link updateFormOptions()}
|
* using {@link updateFormOptions()}
|
||||||
*
|
*
|
||||||
* @return FieldList
|
* @return FieldList
|
||||||
*/
|
*/
|
||||||
public function getFormOptions() {
|
public function getFormOptions()
|
||||||
$submit = ($this->SubmitButtonText) ? $this->SubmitButtonText : _t('UserDefinedForm.SUBMITBUTTON', 'Submit');
|
{
|
||||||
$clear = ($this->ClearButtonText) ? $this->ClearButtonText : _t('UserDefinedForm.CLEARBUTTON', 'Clear');
|
$submit = ($this->SubmitButtonText) ? $this->SubmitButtonText : _t('UserDefinedForm.SUBMITBUTTON', 'Submit');
|
||||||
|
$clear = ($this->ClearButtonText) ? $this->ClearButtonText : _t('UserDefinedForm.CLEARBUTTON', 'Clear');
|
||||||
|
|
||||||
$options = new FieldList(
|
$options = new FieldList(
|
||||||
new TextField("SubmitButtonText", _t('UserDefinedForm.TEXTONSUBMIT', 'Text on submit button:'), $submit),
|
new TextField("SubmitButtonText", _t('UserDefinedForm.TEXTONSUBMIT', 'Text on submit button:'), $submit),
|
||||||
new TextField("ClearButtonText", _t('UserDefinedForm.TEXTONCLEAR', 'Text on clear button:'), $clear),
|
new TextField("ClearButtonText", _t('UserDefinedForm.TEXTONCLEAR', 'Text on clear button:'), $clear),
|
||||||
new CheckboxField("ShowClearButton", _t('UserDefinedForm.SHOWCLEARFORM', 'Show Clear Form Button'), $this->ShowClearButton),
|
new CheckboxField("ShowClearButton", _t('UserDefinedForm.SHOWCLEARFORM', 'Show Clear Form Button'), $this->ShowClearButton),
|
||||||
new CheckboxField("EnableLiveValidation", _t('UserDefinedForm.ENABLELIVEVALIDATION', 'Enable live validation')),
|
new CheckboxField("EnableLiveValidation", _t('UserDefinedForm.ENABLELIVEVALIDATION', 'Enable live validation')),
|
||||||
new CheckboxField("HideFieldLabels", _t('UserDefinedForm.HIDEFIELDLABELS', 'Hide field labels')),
|
new CheckboxField("HideFieldLabels", _t('UserDefinedForm.HIDEFIELDLABELS', 'Hide field labels')),
|
||||||
new CheckboxField("DisplayErrorMessagesAtTop", _t('UserDefinedForm.DISPLAYERRORMESSAGESATTOP', 'Display error messages above the form?')),
|
new CheckboxField("DisplayErrorMessagesAtTop", _t('UserDefinedForm.DISPLAYERRORMESSAGESATTOP', 'Display error messages above the form?')),
|
||||||
new CheckboxField('DisableCsrfSecurityToken', _t('UserDefinedForm.DISABLECSRFSECURITYTOKEN', 'Disable CSRF Token')),
|
new CheckboxField('DisableCsrfSecurityToken', _t('UserDefinedForm.DISABLECSRFSECURITYTOKEN', 'Disable CSRF Token')),
|
||||||
new CheckboxField('DisableAuthenicatedFinishAction', _t('UserDefinedForm.DISABLEAUTHENICATEDFINISHACTION', 'Disable Authentication on finish action'))
|
new CheckboxField('DisableAuthenicatedFinishAction', _t('UserDefinedForm.DISABLEAUTHENICATEDFINISHACTION', 'Disable Authentication on finish action'))
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->extend('updateFormOptions', $options);
|
$this->extend('updateFormOptions', $options);
|
||||||
|
|
||||||
return $options;
|
return $options;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the HTML id of the error container displayed above the form.
|
* Get the HTML id of the error container displayed above the form.
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getErrorContainerID() {
|
public function getErrorContainerID()
|
||||||
return $this->config()->error_container_id;
|
{
|
||||||
}
|
return $this->config()->error_container_id;
|
||||||
|
}
|
||||||
|
|
||||||
public function requireDefaultRecords() {
|
public function requireDefaultRecords()
|
||||||
parent::requireDefaultRecords();
|
{
|
||||||
|
parent::requireDefaultRecords();
|
||||||
|
|
||||||
if(!$this->config()->upgrade_on_build) {
|
if (!$this->config()->upgrade_on_build) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perform migrations
|
// Perform migrations
|
||||||
Injector::inst()
|
Injector::inst()
|
||||||
->create('UserFormsUpgradeService')
|
->create('UserFormsUpgradeService')
|
||||||
->setQuiet(true)
|
->setQuiet(true)
|
||||||
->run();
|
->run();
|
||||||
|
|
||||||
DB::alteration_message('Migrated userforms', 'changed');
|
DB::alteration_message('Migrated userforms', 'changed');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate formfields
|
* Validate formfields
|
||||||
*/
|
*/
|
||||||
public function getCMSValidator() {
|
public function getCMSValidator()
|
||||||
return new UserFormValidator();
|
{
|
||||||
}
|
return new UserFormValidator();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -332,232 +339,238 @@ SQL;
|
|||||||
* @package userforms
|
* @package userforms
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class UserDefinedForm_Controller extends Page_Controller {
|
class UserDefinedForm_Controller extends Page_Controller
|
||||||
|
{
|
||||||
|
|
||||||
private static $finished_anchor = '#uff';
|
private static $finished_anchor = '#uff';
|
||||||
|
|
||||||
private static $allowed_actions = array(
|
private static $allowed_actions = array(
|
||||||
'index',
|
'index',
|
||||||
'ping',
|
'ping',
|
||||||
'Form',
|
'Form',
|
||||||
'finished'
|
'finished'
|
||||||
);
|
);
|
||||||
|
|
||||||
public function init() {
|
public function init()
|
||||||
parent::init();
|
{
|
||||||
|
parent::init();
|
||||||
|
|
||||||
// load the jquery
|
// load the jquery
|
||||||
$lang = i18n::get_lang_from_locale(i18n::get_locale());
|
$lang = i18n::get_lang_from_locale(i18n::get_locale());
|
||||||
Requirements::css(USERFORMS_DIR . '/css/UserForm.css');
|
Requirements::css(USERFORMS_DIR . '/css/UserForm.css');
|
||||||
Requirements::javascript(FRAMEWORK_DIR .'/thirdparty/jquery/jquery.js');
|
Requirements::javascript(FRAMEWORK_DIR .'/thirdparty/jquery/jquery.js');
|
||||||
Requirements::javascript(USERFORMS_DIR . '/thirdparty/jquery-validate/jquery.validate.min.js');
|
Requirements::javascript(USERFORMS_DIR . '/thirdparty/jquery-validate/jquery.validate.min.js');
|
||||||
Requirements::add_i18n_javascript(USERFORMS_DIR . '/javascript/lang');
|
Requirements::add_i18n_javascript(USERFORMS_DIR . '/javascript/lang');
|
||||||
Requirements::javascript(USERFORMS_DIR . '/javascript/UserForm.js');
|
Requirements::javascript(USERFORMS_DIR . '/javascript/UserForm.js');
|
||||||
|
|
||||||
Requirements::javascript(
|
Requirements::javascript(
|
||||||
USERFORMS_DIR . "/thirdparty/jquery-validate/localization/messages_{$lang}.min.js"
|
USERFORMS_DIR . "/thirdparty/jquery-validate/localization/messages_{$lang}.min.js"
|
||||||
);
|
);
|
||||||
Requirements::javascript(
|
Requirements::javascript(
|
||||||
USERFORMS_DIR . "/thirdparty/jquery-validate/localization/methods_{$lang}.min.js"
|
USERFORMS_DIR . "/thirdparty/jquery-validate/localization/methods_{$lang}.min.js"
|
||||||
);
|
);
|
||||||
if($this->HideFieldLabels) {
|
if ($this->HideFieldLabels) {
|
||||||
Requirements::javascript(USERFORMS_DIR . '/thirdparty/Placeholders.js/Placeholders.min.js');
|
Requirements::javascript(USERFORMS_DIR . '/thirdparty/Placeholders.js/Placeholders.min.js');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bind a confirmation message when navigating away from a partially completed form.
|
// Bind a confirmation message when navigating away from a partially completed form.
|
||||||
$page = $this->data();
|
$page = $this->data();
|
||||||
if($page::config()->enable_are_you_sure) {
|
if ($page::config()->enable_are_you_sure) {
|
||||||
Requirements::javascript(USERFORMS_DIR . '/thirdparty/jquery.are-you-sure/jquery.are-you-sure.js');
|
Requirements::javascript(USERFORMS_DIR . '/thirdparty/jquery.are-you-sure/jquery.are-you-sure.js');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Using $UserDefinedForm in the Content area of the page shows
|
* Using $UserDefinedForm in the Content area of the page shows
|
||||||
* where the form should be rendered into. If it does not exist
|
* where the form should be rendered into. If it does not exist
|
||||||
* then default back to $Form.
|
* then default back to $Form.
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function index() {
|
public function index()
|
||||||
if($this->Content && $form = $this->Form()) {
|
{
|
||||||
$hasLocation = stristr($this->Content, '$UserDefinedForm');
|
if ($this->Content && $form = $this->Form()) {
|
||||||
if($hasLocation) {
|
$hasLocation = stristr($this->Content, '$UserDefinedForm');
|
||||||
$content = preg_replace('/(<p[^>]*>)?\\$UserDefinedForm(<\\/p>)?/i', $form->forTemplate(), $this->Content);
|
if ($hasLocation) {
|
||||||
return array(
|
$content = preg_replace('/(<p[^>]*>)?\\$UserDefinedForm(<\\/p>)?/i', $form->forTemplate(), $this->Content);
|
||||||
'Content' => DBField::create_field('HTMLText', $content),
|
return array(
|
||||||
'Form' => ""
|
'Content' => DBField::create_field('HTMLText', $content),
|
||||||
);
|
'Form' => ""
|
||||||
}
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
'Content' => DBField::create_field('HTMLText', $this->Content),
|
'Content' => DBField::create_field('HTMLText', $this->Content),
|
||||||
'Form' => $this->Form()
|
'Form' => $this->Form()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Keep the session alive for the user.
|
* Keep the session alive for the user.
|
||||||
*
|
*
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function ping() {
|
public function ping()
|
||||||
return 1;
|
{
|
||||||
}
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the form for the page. Form can be modified by calling {@link updateForm()}
|
* Get the form for the page. Form can be modified by calling {@link updateForm()}
|
||||||
* on a UserDefinedForm extension.
|
* on a UserDefinedForm extension.
|
||||||
*
|
*
|
||||||
* @return Forms
|
* @return Forms
|
||||||
*/
|
*/
|
||||||
public function Form() {
|
public function Form()
|
||||||
$form = UserForm::create($this);
|
{
|
||||||
$this->generateConditionalJavascript();
|
$form = UserForm::create($this);
|
||||||
return $form;
|
$this->generateConditionalJavascript();
|
||||||
}
|
return $form;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate the javascript for the conditional field show / hiding logic.
|
* Generate the javascript for the conditional field show / hiding logic.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function generateConditionalJavascript() {
|
public function generateConditionalJavascript()
|
||||||
$default = "";
|
{
|
||||||
$rules = "";
|
$default = "";
|
||||||
|
$rules = "";
|
||||||
|
|
||||||
$watch = array();
|
$watch = array();
|
||||||
$watchLoad = array();
|
$watchLoad = array();
|
||||||
|
|
||||||
if($this->Fields()) {
|
if ($this->Fields()) {
|
||||||
foreach($this->Fields() as $field) {
|
foreach ($this->Fields() as $field) {
|
||||||
$holderSelector = $field->getSelectorHolder();
|
$holderSelector = $field->getSelectorHolder();
|
||||||
|
|
||||||
// Is this Field Show by Default
|
// Is this Field Show by Default
|
||||||
if(!$field->ShowOnLoad) {
|
if (!$field->ShowOnLoad) {
|
||||||
$default .= "{$holderSelector}.hide().trigger('userform.field.hide');\n";
|
$default .= "{$holderSelector}.hide().trigger('userform.field.hide');\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for field dependencies / default
|
// Check for field dependencies / default
|
||||||
foreach($field->EffectiveDisplayRules() as $rule) {
|
foreach ($field->EffectiveDisplayRules() as $rule) {
|
||||||
|
|
||||||
// Get the field which is effected
|
// Get the field which is effected
|
||||||
$formFieldWatch = EditableFormField::get()->byId($rule->ConditionFieldID);
|
$formFieldWatch = EditableFormField::get()->byId($rule->ConditionFieldID);
|
||||||
|
|
||||||
// Skip deleted fields
|
// Skip deleted fields
|
||||||
if(!$formFieldWatch) {
|
if (!$formFieldWatch) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$fieldToWatch = $formFieldWatch->getSelectorField($rule);
|
$fieldToWatch = $formFieldWatch->getSelectorField($rule);
|
||||||
$fieldToWatchOnLoad = $formFieldWatch->getSelectorField($rule, true);
|
$fieldToWatchOnLoad = $formFieldWatch->getSelectorField($rule, true);
|
||||||
|
|
||||||
// show or hide?
|
// show or hide?
|
||||||
$view = ($rule->Display == 'Hide') ? 'hide' : 'show';
|
$view = ($rule->Display == 'Hide') ? 'hide' : 'show';
|
||||||
$opposite = ($view == "show") ? "hide" : "show";
|
$opposite = ($view == "show") ? "hide" : "show";
|
||||||
|
|
||||||
// what action do we need to keep track of. Something nicer here maybe?
|
// what action do we need to keep track of. Something nicer here maybe?
|
||||||
// @todo encapulsation
|
// @todo encapulsation
|
||||||
$action = "change";
|
$action = "change";
|
||||||
|
|
||||||
if($formFieldWatch instanceof EditableTextField) {
|
if ($formFieldWatch instanceof EditableTextField) {
|
||||||
$action = "keyup";
|
$action = "keyup";
|
||||||
}
|
}
|
||||||
|
|
||||||
// is this field a special option field
|
// is this field a special option field
|
||||||
$checkboxField = false;
|
$checkboxField = false;
|
||||||
$radioField = false;
|
$radioField = false;
|
||||||
|
|
||||||
if(in_array($formFieldWatch->ClassName, array('EditableCheckboxGroupField', 'EditableCheckbox'))) {
|
if (in_array($formFieldWatch->ClassName, array('EditableCheckboxGroupField', 'EditableCheckbox'))) {
|
||||||
$action = "click";
|
$action = "click";
|
||||||
$checkboxField = true;
|
$checkboxField = true;
|
||||||
} else if ($formFieldWatch->ClassName == "EditableRadioField") {
|
} elseif ($formFieldWatch->ClassName == "EditableRadioField") {
|
||||||
$radioField = true;
|
$radioField = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// and what should we evaluate
|
// and what should we evaluate
|
||||||
switch($rule->ConditionOption) {
|
switch ($rule->ConditionOption) {
|
||||||
case 'IsNotBlank':
|
case 'IsNotBlank':
|
||||||
$expression = ($checkboxField || $radioField) ? '$(this).is(":checked")' :'$(this).val() != ""';
|
$expression = ($checkboxField || $radioField) ? '$(this).is(":checked")' :'$(this).val() != ""';
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 'IsBlank':
|
case 'IsBlank':
|
||||||
$expression = ($checkboxField || $radioField) ? '!($(this).is(":checked"))' : '$(this).val() == ""';
|
$expression = ($checkboxField || $radioField) ? '!($(this).is(":checked"))' : '$(this).val() == ""';
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 'HasValue':
|
case 'HasValue':
|
||||||
if ($checkboxField) {
|
if ($checkboxField) {
|
||||||
$expression = '$(this).prop("checked")';
|
$expression = '$(this).prop("checked")';
|
||||||
} else if ($radioField) {
|
} elseif ($radioField) {
|
||||||
// We cannot simply get the value of the radio group, we need to find the checked option first.
|
// We cannot simply get the value of the radio group, we need to find the checked option first.
|
||||||
$expression = '$(this).parents(".field, .control-group").find("input:checked").val()=="'. $rule->FieldValue .'"';
|
$expression = '$(this).parents(".field, .control-group").find("input:checked").val()=="'. $rule->FieldValue .'"';
|
||||||
} else {
|
} else {
|
||||||
$expression = '$(this).val() == "'. $rule->FieldValue .'"';
|
$expression = '$(this).val() == "'. $rule->FieldValue .'"';
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 'ValueLessThan':
|
case 'ValueLessThan':
|
||||||
$expression = '$(this).val() < parseFloat("'. $rule->FieldValue .'")';
|
$expression = '$(this).val() < parseFloat("'. $rule->FieldValue .'")';
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 'ValueLessThanEqual':
|
case 'ValueLessThanEqual':
|
||||||
$expression = '$(this).val() <= parseFloat("'. $rule->FieldValue .'")';
|
$expression = '$(this).val() <= parseFloat("'. $rule->FieldValue .'")';
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 'ValueGreaterThan':
|
case 'ValueGreaterThan':
|
||||||
$expression = '$(this).val() > parseFloat("'. $rule->FieldValue .'")';
|
$expression = '$(this).val() > parseFloat("'. $rule->FieldValue .'")';
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 'ValueGreaterThanEqual':
|
case 'ValueGreaterThanEqual':
|
||||||
$expression = '$(this).val() >= parseFloat("'. $rule->FieldValue .'")';
|
$expression = '$(this).val() >= parseFloat("'. $rule->FieldValue .'")';
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default: // ==HasNotValue
|
default: // ==HasNotValue
|
||||||
if ($checkboxField) {
|
if ($checkboxField) {
|
||||||
$expression = '!$(this).prop("checked")';
|
$expression = '!$(this).prop("checked")';
|
||||||
} else if ($radioField) {
|
} elseif ($radioField) {
|
||||||
// We cannot simply get the value of the radio group, we need to find the checked option first.
|
// We cannot simply get the value of the radio group, we need to find the checked option first.
|
||||||
$expression = '$(this).parents(".field, .control-group").find("input:checked").val()!="'. $rule->FieldValue .'"';
|
$expression = '$(this).parents(".field, .control-group").find("input:checked").val()!="'. $rule->FieldValue .'"';
|
||||||
} else {
|
} else {
|
||||||
$expression = '$(this).val() != "'. $rule->FieldValue .'"';
|
$expression = '$(this).val() != "'. $rule->FieldValue .'"';
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!isset($watch[$fieldToWatch])) {
|
if (!isset($watch[$fieldToWatch])) {
|
||||||
$watch[$fieldToWatch] = array();
|
$watch[$fieldToWatch] = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
$watch[$fieldToWatch][] = array(
|
$watch[$fieldToWatch][] = array(
|
||||||
'expression' => $expression,
|
'expression' => $expression,
|
||||||
'holder_selector' => $holderSelector,
|
'holder_selector' => $holderSelector,
|
||||||
'view' => $view,
|
'view' => $view,
|
||||||
'opposite' => $opposite,
|
'opposite' => $opposite,
|
||||||
'action' => $action
|
'action' => $action
|
||||||
);
|
);
|
||||||
|
|
||||||
$watchLoad[$fieldToWatchOnLoad] = true;
|
$watchLoad[$fieldToWatchOnLoad] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if($watch) {
|
if ($watch) {
|
||||||
foreach($watch as $key => $values) {
|
foreach ($watch as $key => $values) {
|
||||||
$logic = array();
|
$logic = array();
|
||||||
$actions = array();
|
$actions = array();
|
||||||
|
|
||||||
foreach($values as $rule) {
|
foreach ($values as $rule) {
|
||||||
// Assign action
|
// Assign action
|
||||||
$actions[$rule['action']] = $rule['action'];
|
$actions[$rule['action']] = $rule['action'];
|
||||||
|
|
||||||
// Assign behaviour
|
// Assign behaviour
|
||||||
$expression = $rule['expression'];
|
$expression = $rule['expression'];
|
||||||
$holder = $rule['holder_selector'];
|
$holder = $rule['holder_selector'];
|
||||||
$view = $rule['view']; // hide or show
|
$view = $rule['view']; // hide or show
|
||||||
$opposite = $rule['opposite'];
|
$opposite = $rule['opposite'];
|
||||||
// Generated javascript for triggering visibility
|
// Generated javascript for triggering visibility
|
||||||
$logic[] = <<<"EOS"
|
$logic[] = <<<"EOS"
|
||||||
if({$expression}) {
|
if({$expression}) {
|
||||||
{$holder}
|
{$holder}
|
||||||
.{$view}()
|
.{$view}()
|
||||||
@ -568,33 +581,33 @@ if({$expression}) {
|
|||||||
.trigger('userform.field.{$opposite}');
|
.trigger('userform.field.{$opposite}');
|
||||||
}
|
}
|
||||||
EOS;
|
EOS;
|
||||||
}
|
}
|
||||||
|
|
||||||
$logic = implode("\n", $logic);
|
$logic = implode("\n", $logic);
|
||||||
$rules .= $key.".each(function() {\n
|
$rules .= $key.".each(function() {\n
|
||||||
$(this).data('userformConditions', function() {\n
|
$(this).data('userformConditions', function() {\n
|
||||||
$logic\n
|
$logic\n
|
||||||
}); \n
|
}); \n
|
||||||
});\n";
|
});\n";
|
||||||
foreach($actions as $action) {
|
foreach ($actions as $action) {
|
||||||
$rules .= $key.".$action(function() {
|
$rules .= $key.".$action(function() {
|
||||||
$(this).data('userformConditions').call(this);\n
|
$(this).data('userformConditions').call(this);\n
|
||||||
});\n";
|
});\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if($watchLoad) {
|
if ($watchLoad) {
|
||||||
foreach($watchLoad as $key => $value) {
|
foreach ($watchLoad as $key => $value) {
|
||||||
$rules .= $key.".each(function() {
|
$rules .= $key.".each(function() {
|
||||||
$(this).data('userformConditions').call(this);\n
|
$(this).data('userformConditions').call(this);\n
|
||||||
});\n";
|
});\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only add customScript if $default or $rules is defined
|
// Only add customScript if $default or $rules is defined
|
||||||
if($default || $rules) {
|
if ($default || $rules) {
|
||||||
Requirements::customScript(<<<JS
|
Requirements::customScript(<<<JS
|
||||||
(function($) {
|
(function($) {
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
$default
|
$default
|
||||||
@ -604,265 +617,266 @@ EOS;
|
|||||||
})(jQuery);
|
})(jQuery);
|
||||||
JS
|
JS
|
||||||
, 'UserFormsConditional');
|
, 'UserFormsConditional');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process the form that is submitted through the site
|
* Process the form that is submitted through the site
|
||||||
*
|
*
|
||||||
* {@see UserForm::validate()} for validation step prior to processing
|
* {@see UserForm::validate()} for validation step prior to processing
|
||||||
*
|
*
|
||||||
* @param array $data
|
* @param array $data
|
||||||
* @param Form $form
|
* @param Form $form
|
||||||
*
|
*
|
||||||
* @return Redirection
|
* @return Redirection
|
||||||
*/
|
*/
|
||||||
public function process($data, $form) {
|
public function process($data, $form)
|
||||||
$submittedForm = Object::create('SubmittedForm');
|
{
|
||||||
$submittedForm->SubmittedByID = ($id = Member::currentUserID()) ? $id : 0;
|
$submittedForm = Object::create('SubmittedForm');
|
||||||
$submittedForm->ParentID = $this->ID;
|
$submittedForm->SubmittedByID = ($id = Member::currentUserID()) ? $id : 0;
|
||||||
|
$submittedForm->ParentID = $this->ID;
|
||||||
|
|
||||||
// if saving is not disabled save now to generate the ID
|
// if saving is not disabled save now to generate the ID
|
||||||
if(!$this->DisableSaveSubmissions) {
|
if (!$this->DisableSaveSubmissions) {
|
||||||
$submittedForm->write();
|
$submittedForm->write();
|
||||||
}
|
}
|
||||||
|
|
||||||
$attachments = array();
|
$attachments = array();
|
||||||
$submittedFields = new ArrayList();
|
$submittedFields = new ArrayList();
|
||||||
|
|
||||||
foreach($this->Fields() as $field) {
|
foreach ($this->Fields() as $field) {
|
||||||
if(!$field->showInReports()) {
|
if (!$field->showInReports()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$submittedField = $field->getSubmittedFormField();
|
$submittedField = $field->getSubmittedFormField();
|
||||||
$submittedField->ParentID = $submittedForm->ID;
|
$submittedField->ParentID = $submittedForm->ID;
|
||||||
$submittedField->Name = $field->Name;
|
$submittedField->Name = $field->Name;
|
||||||
$submittedField->Title = $field->getField('Title');
|
$submittedField->Title = $field->getField('Title');
|
||||||
|
|
||||||
// save the value from the data
|
// save the value from the data
|
||||||
if($field->hasMethod('getValueFromData')) {
|
if ($field->hasMethod('getValueFromData')) {
|
||||||
$submittedField->Value = $field->getValueFromData($data);
|
$submittedField->Value = $field->getValueFromData($data);
|
||||||
} else {
|
} else {
|
||||||
if(isset($data[$field->Name])) {
|
if (isset($data[$field->Name])) {
|
||||||
$submittedField->Value = $data[$field->Name];
|
$submittedField->Value = $data[$field->Name];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!empty($data[$field->Name])) {
|
if (!empty($data[$field->Name])) {
|
||||||
if(in_array("EditableFileField", $field->getClassAncestry())) {
|
if (in_array("EditableFileField", $field->getClassAncestry())) {
|
||||||
if(isset($_FILES[$field->Name])) {
|
if (isset($_FILES[$field->Name])) {
|
||||||
$foldername = $field->getFormField()->getFolderName();
|
$foldername = $field->getFormField()->getFolderName();
|
||||||
|
|
||||||
// create the file from post data
|
// create the file from post data
|
||||||
$upload = new Upload();
|
$upload = new Upload();
|
||||||
$file = new File();
|
$file = new File();
|
||||||
$file->ShowInSearch = 0;
|
$file->ShowInSearch = 0;
|
||||||
try {
|
try {
|
||||||
$upload->loadIntoFile($_FILES[$field->Name], $file, $foldername);
|
$upload->loadIntoFile($_FILES[$field->Name], $file, $foldername);
|
||||||
} catch( ValidationException $e ) {
|
} catch (ValidationException $e) {
|
||||||
$validationResult = $e->getResult();
|
$validationResult = $e->getResult();
|
||||||
$form->addErrorMessage($field->Name, $validationResult->message(), 'bad');
|
$form->addErrorMessage($field->Name, $validationResult->message(), 'bad');
|
||||||
Controller::curr()->redirectBack();
|
Controller::curr()->redirectBack();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// write file to form field
|
// write file to form field
|
||||||
$submittedField->UploadedFileID = $file->ID;
|
$submittedField->UploadedFileID = $file->ID;
|
||||||
|
|
||||||
// attach a file only if lower than 1MB
|
// attach a file only if lower than 1MB
|
||||||
if($file->getAbsoluteSize() < 1024*1024*1) {
|
if ($file->getAbsoluteSize() < 1024*1024*1) {
|
||||||
$attachments[] = $file;
|
$attachments[] = $file;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$submittedField->extend('onPopulationFromField', $field);
|
$submittedField->extend('onPopulationFromField', $field);
|
||||||
|
|
||||||
if(!$this->DisableSaveSubmissions) {
|
if (!$this->DisableSaveSubmissions) {
|
||||||
$submittedField->write();
|
$submittedField->write();
|
||||||
}
|
}
|
||||||
|
|
||||||
$submittedFields->push($submittedField);
|
$submittedFields->push($submittedField);
|
||||||
}
|
}
|
||||||
|
|
||||||
$emailData = array(
|
$emailData = array(
|
||||||
"Sender" => Member::currentUser(),
|
"Sender" => Member::currentUser(),
|
||||||
"Fields" => $submittedFields
|
"Fields" => $submittedFields
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->extend('updateEmailData', $emailData, $attachments);
|
$this->extend('updateEmailData', $emailData, $attachments);
|
||||||
|
|
||||||
// email users on submit.
|
// email users on submit.
|
||||||
if($recipients = $this->FilteredEmailRecipients($data, $form)) {
|
if ($recipients = $this->FilteredEmailRecipients($data, $form)) {
|
||||||
|
foreach ($recipients as $recipient) {
|
||||||
|
$email = new UserFormRecipientEmail($submittedFields);
|
||||||
|
$mergeFields = $this->getMergeFieldsMap($emailData['Fields']);
|
||||||
|
|
||||||
|
if ($attachments) {
|
||||||
|
foreach ($attachments as $file) {
|
||||||
|
if ($file->ID != 0) {
|
||||||
|
$email->attachFile(
|
||||||
|
$file->Filename,
|
||||||
|
$file->Filename,
|
||||||
|
HTTP::get_mime_type($file->Filename)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$parsedBody = SSViewer::execute_string($recipient->getEmailBodyContent(), $mergeFields);
|
||||||
|
|
||||||
foreach($recipients as $recipient) {
|
if (!$recipient->SendPlain && $recipient->emailTemplateExists()) {
|
||||||
$email = new UserFormRecipientEmail($submittedFields);
|
$email->setTemplate($recipient->EmailTemplate);
|
||||||
$mergeFields = $this->getMergeFieldsMap($emailData['Fields']);
|
}
|
||||||
|
|
||||||
if($attachments) {
|
$email->populateTemplate($recipient);
|
||||||
foreach($attachments as $file) {
|
$email->populateTemplate($emailData);
|
||||||
if($file->ID != 0) {
|
$email->setFrom($recipient->EmailFrom);
|
||||||
$email->attachFile(
|
$email->setBody($parsedBody);
|
||||||
$file->Filename,
|
$email->setTo($recipient->EmailAddress);
|
||||||
$file->Filename,
|
$email->setSubject($recipient->EmailSubject);
|
||||||
HTTP::get_mime_type($file->Filename)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$parsedBody = SSViewer::execute_string($recipient->getEmailBodyContent(), $mergeFields);
|
if ($recipient->EmailReplyTo) {
|
||||||
|
$email->setReplyTo($recipient->EmailReplyTo);
|
||||||
|
}
|
||||||
|
|
||||||
if (!$recipient->SendPlain && $recipient->emailTemplateExists()) {
|
// check to see if they are a dynamic reply to. eg based on a email field a user selected
|
||||||
$email->setTemplate($recipient->EmailTemplate);
|
if ($recipient->SendEmailFromField()) {
|
||||||
}
|
$submittedFormField = $submittedFields->find('Name', $recipient->SendEmailFromField()->Name);
|
||||||
|
|
||||||
$email->populateTemplate($recipient);
|
if ($submittedFormField && is_string($submittedFormField->Value)) {
|
||||||
$email->populateTemplate($emailData);
|
$email->setReplyTo($submittedFormField->Value);
|
||||||
$email->setFrom($recipient->EmailFrom);
|
}
|
||||||
$email->setBody($parsedBody);
|
}
|
||||||
$email->setTo($recipient->EmailAddress);
|
// check to see if they are a dynamic reciever eg based on a dropdown field a user selected
|
||||||
$email->setSubject($recipient->EmailSubject);
|
if ($recipient->SendEmailToField()) {
|
||||||
|
$submittedFormField = $submittedFields->find('Name', $recipient->SendEmailToField()->Name);
|
||||||
|
|
||||||
if($recipient->EmailReplyTo) {
|
if ($submittedFormField && is_string($submittedFormField->Value)) {
|
||||||
$email->setReplyTo($recipient->EmailReplyTo);
|
$email->setTo($submittedFormField->Value);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// check to see if they are a dynamic reply to. eg based on a email field a user selected
|
// check to see if there is a dynamic subject
|
||||||
if($recipient->SendEmailFromField()) {
|
if ($recipient->SendEmailSubjectField()) {
|
||||||
$submittedFormField = $submittedFields->find('Name', $recipient->SendEmailFromField()->Name);
|
$submittedFormField = $submittedFields->find('Name', $recipient->SendEmailSubjectField()->Name);
|
||||||
|
|
||||||
if($submittedFormField && is_string($submittedFormField->Value)) {
|
if ($submittedFormField && trim($submittedFormField->Value)) {
|
||||||
$email->setReplyTo($submittedFormField->Value);
|
$email->setSubject($submittedFormField->Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// check to see if they are a dynamic reciever eg based on a dropdown field a user selected
|
|
||||||
if($recipient->SendEmailToField()) {
|
|
||||||
$submittedFormField = $submittedFields->find('Name', $recipient->SendEmailToField()->Name);
|
|
||||||
|
|
||||||
if($submittedFormField && is_string($submittedFormField->Value)) {
|
$this->extend('updateEmail', $email, $recipient, $emailData);
|
||||||
$email->setTo($submittedFormField->Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// check to see if there is a dynamic subject
|
if ($recipient->SendPlain) {
|
||||||
if($recipient->SendEmailSubjectField()) {
|
$body = strip_tags($recipient->getEmailBodyContent()) . "\n";
|
||||||
$submittedFormField = $submittedFields->find('Name', $recipient->SendEmailSubjectField()->Name);
|
if (isset($emailData['Fields']) && !$recipient->HideFormData) {
|
||||||
|
foreach ($emailData['Fields'] as $Field) {
|
||||||
|
$body .= $Field->Title .': '. $Field->Value ." \n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if($submittedFormField && trim($submittedFormField->Value)) {
|
$email->setBody($body);
|
||||||
$email->setSubject($submittedFormField->Value);
|
$email->sendPlain();
|
||||||
}
|
} else {
|
||||||
}
|
$email->send();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$this->extend('updateEmail', $email, $recipient, $emailData);
|
$submittedForm->extend('updateAfterProcess');
|
||||||
|
|
||||||
if($recipient->SendPlain) {
|
Session::clear("FormInfo.{$form->FormName()}.errors");
|
||||||
$body = strip_tags($recipient->getEmailBodyContent()) . "\n";
|
Session::clear("FormInfo.{$form->FormName()}.data");
|
||||||
if(isset($emailData['Fields']) && !$recipient->HideFormData) {
|
|
||||||
foreach($emailData['Fields'] as $Field) {
|
|
||||||
$body .= $Field->Title .': '. $Field->Value ." \n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$email->setBody($body);
|
$referrer = (isset($data['Referrer'])) ? '?referrer=' . urlencode($data['Referrer']) : "";
|
||||||
$email->sendPlain();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$email->send();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$submittedForm->extend('updateAfterProcess');
|
// set a session variable from the security ID to stop people accessing
|
||||||
|
// the finished method directly.
|
||||||
|
if (!$this->DisableAuthenicatedFinishAction) {
|
||||||
|
if (isset($data['SecurityID'])) {
|
||||||
|
Session::set('FormProcessed', $data['SecurityID']);
|
||||||
|
} else {
|
||||||
|
// if the form has had tokens disabled we still need to set FormProcessed
|
||||||
|
// to allow us to get through the finshed method
|
||||||
|
if (!$this->Form()->getSecurityToken()->isEnabled()) {
|
||||||
|
$randNum = rand(1, 1000);
|
||||||
|
$randHash = md5($randNum);
|
||||||
|
Session::set('FormProcessed', $randHash);
|
||||||
|
Session::set('FormProcessedNum', $randNum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Session::clear("FormInfo.{$form->FormName()}.errors");
|
if (!$this->DisableSaveSubmissions) {
|
||||||
Session::clear("FormInfo.{$form->FormName()}.data");
|
Session::set('userformssubmission'. $this->ID, $submittedForm->ID);
|
||||||
|
}
|
||||||
|
|
||||||
$referrer = (isset($data['Referrer'])) ? '?referrer=' . urlencode($data['Referrer']) : "";
|
return $this->redirect($this->Link('finished') . $referrer . $this->config()->finished_anchor);
|
||||||
|
}
|
||||||
|
|
||||||
// set a session variable from the security ID to stop people accessing
|
/**
|
||||||
// the finished method directly.
|
* Allows the use of field values in email body.
|
||||||
if(!$this->DisableAuthenicatedFinishAction) {
|
*
|
||||||
if (isset($data['SecurityID'])) {
|
* @param ArrayList fields
|
||||||
Session::set('FormProcessed',$data['SecurityID']);
|
* @return ArrayData
|
||||||
} else {
|
*/
|
||||||
// if the form has had tokens disabled we still need to set FormProcessed
|
private function getMergeFieldsMap($fields = array())
|
||||||
// to allow us to get through the finshed method
|
{
|
||||||
if (!$this->Form()->getSecurityToken()->isEnabled()) {
|
$data = new ArrayData(array());
|
||||||
$randNum = rand(1, 1000);
|
|
||||||
$randHash = md5($randNum);
|
|
||||||
Session::set('FormProcessed',$randHash);
|
|
||||||
Session::set('FormProcessedNum',$randNum);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!$this->DisableSaveSubmissions) {
|
foreach ($fields as $field) {
|
||||||
Session::set('userformssubmission'. $this->ID, $submittedForm->ID);
|
$data->setField($field->Name, DBField::create_field('Text', $field->Value));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->redirect($this->Link('finished') . $referrer . $this->config()->finished_anchor);
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows the use of field values in email body.
|
* This action handles rendering the "finished" message, which is
|
||||||
*
|
* customizable by editing the ReceivedFormSubmission template.
|
||||||
* @param ArrayList fields
|
*
|
||||||
* @return ArrayData
|
* @return ViewableData
|
||||||
*/
|
*/
|
||||||
private function getMergeFieldsMap($fields = array()) {
|
public function finished()
|
||||||
$data = new ArrayData(array());
|
{
|
||||||
|
$submission = Session::get('userformssubmission'. $this->ID);
|
||||||
|
|
||||||
foreach ($fields as $field) {
|
if ($submission) {
|
||||||
$data->setField($field->Name, DBField::create_field('Text', $field->Value));
|
$submission = SubmittedForm::get()->byId($submission);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $data;
|
$referrer = isset($_GET['referrer']) ? urldecode($_GET['referrer']) : null;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
if (!$this->DisableAuthenicatedFinishAction) {
|
||||||
* This action handles rendering the "finished" message, which is
|
$formProcessed = Session::get('FormProcessed');
|
||||||
* customizable by editing the ReceivedFormSubmission template.
|
|
||||||
*
|
|
||||||
* @return ViewableData
|
|
||||||
*/
|
|
||||||
public function finished() {
|
|
||||||
$submission = Session::get('userformssubmission'. $this->ID);
|
|
||||||
|
|
||||||
if($submission) {
|
if (!isset($formProcessed)) {
|
||||||
$submission = SubmittedForm::get()->byId($submission);
|
return $this->redirect($this->Link() . $referrer);
|
||||||
}
|
} else {
|
||||||
|
$securityID = Session::get('SecurityID');
|
||||||
|
// make sure the session matches the SecurityID and is not left over from another form
|
||||||
|
if ($formProcessed != $securityID) {
|
||||||
|
// they may have disabled tokens on the form
|
||||||
|
$securityID = md5(Session::get('FormProcessedNum'));
|
||||||
|
if ($formProcessed != $securityID) {
|
||||||
|
return $this->redirect($this->Link() . $referrer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$referrer = isset($_GET['referrer']) ? urldecode($_GET['referrer']) : null;
|
Session::clear('FormProcessed');
|
||||||
|
}
|
||||||
|
|
||||||
if(!$this->DisableAuthenicatedFinishAction) {
|
return $this->customise(array(
|
||||||
$formProcessed = Session::get('FormProcessed');
|
'Content' => $this->customise(array(
|
||||||
|
'Submission' => $submission,
|
||||||
if (!isset($formProcessed)) {
|
'Link' => $referrer
|
||||||
return $this->redirect($this->Link() . $referrer);
|
))->renderWith('ReceivedFormSubmission'),
|
||||||
} else {
|
'Form' => '',
|
||||||
$securityID = Session::get('SecurityID');
|
));
|
||||||
// make sure the session matches the SecurityID and is not left over from another form
|
}
|
||||||
if ($formProcessed != $securityID) {
|
|
||||||
// they may have disabled tokens on the form
|
|
||||||
$securityID = md5(Session::get('FormProcessedNum'));
|
|
||||||
if ($formProcessed != $securityID) {
|
|
||||||
return $this->redirect($this->Link() . $referrer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Session::clear('FormProcessed');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->customise(array(
|
|
||||||
'Content' => $this->customise(array(
|
|
||||||
'Submission' => $submission,
|
|
||||||
'Link' => $referrer
|
|
||||||
))->renderWith('ReceivedFormSubmission'),
|
|
||||||
'Form' => '',
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -7,53 +7,58 @@
|
|||||||
* @package userforms
|
* @package userforms
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class EditableCheckbox extends EditableFormField {
|
class EditableCheckbox extends EditableFormField
|
||||||
|
{
|
||||||
|
|
||||||
private static $singular_name = 'Checkbox Field';
|
private static $singular_name = 'Checkbox Field';
|
||||||
|
|
||||||
private static $plural_name = 'Checkboxes';
|
private static $plural_name = 'Checkboxes';
|
||||||
|
|
||||||
private static $db = array(
|
private static $db = array(
|
||||||
'CheckedDefault' => 'Boolean' // from CustomSettings
|
'CheckedDefault' => 'Boolean' // from CustomSettings
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return FieldList
|
* @return FieldList
|
||||||
*/
|
*/
|
||||||
public function getCMSFields() {
|
public function getCMSFields()
|
||||||
$fields = parent::getCMSFields();
|
{
|
||||||
|
$fields = parent::getCMSFields();
|
||||||
|
|
||||||
$fields->replaceField('Default', CheckboxField::create(
|
$fields->replaceField('Default', CheckboxField::create(
|
||||||
"CheckedDefault",
|
"CheckedDefault",
|
||||||
_t('EditableFormField.CHECKEDBYDEFAULT', 'Checked by Default?')
|
_t('EditableFormField.CHECKEDBYDEFAULT', 'Checked by Default?')
|
||||||
));
|
));
|
||||||
|
|
||||||
return $fields;
|
return $fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getFormField() {
|
public function getFormField()
|
||||||
$field = CheckboxField::create($this->Name, $this->EscapedTitle, $this->CheckedDefault)
|
{
|
||||||
->setFieldHolderTemplate('UserFormsCheckboxField_holder')
|
$field = CheckboxField::create($this->Name, $this->EscapedTitle, $this->CheckedDefault)
|
||||||
->setTemplate('UserFormsCheckboxField');
|
->setFieldHolderTemplate('UserFormsCheckboxField_holder')
|
||||||
|
->setTemplate('UserFormsCheckboxField');
|
||||||
|
|
||||||
$this->doUpdateFormField($field);
|
$this->doUpdateFormField($field);
|
||||||
|
|
||||||
return $field;
|
return $field;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getValueFromData($data) {
|
public function getValueFromData($data)
|
||||||
$value = (isset($data[$this->Name])) ? $data[$this->Name] : false;
|
{
|
||||||
|
$value = (isset($data[$this->Name])) ? $data[$this->Name] : false;
|
||||||
|
|
||||||
return ($value) ? _t('EditableFormField.YES', 'Yes') : _t('EditableFormField.NO', 'No');
|
return ($value) ? _t('EditableFormField.YES', 'Yes') : _t('EditableFormField.NO', 'No');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function migrateSettings($data) {
|
public function migrateSettings($data)
|
||||||
// Migrate 'Default' setting to 'CheckedDefault'
|
{
|
||||||
if(isset($data['Default'])) {
|
// Migrate 'Default' setting to 'CheckedDefault'
|
||||||
$this->CheckedDefault = (bool)$data['Default'];
|
if (isset($data['Default'])) {
|
||||||
unset($data['Default']);
|
$this->CheckedDefault = (bool)$data['Default'];
|
||||||
}
|
unset($data['Default']);
|
||||||
|
}
|
||||||
|
|
||||||
parent::migrateSettings($data);
|
parent::migrateSettings($data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,52 +7,56 @@
|
|||||||
* @package userforms
|
* @package userforms
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class EditableCheckboxGroupField extends EditableMultipleOptionField {
|
class EditableCheckboxGroupField extends EditableMultipleOptionField
|
||||||
|
{
|
||||||
|
|
||||||
private static $singular_name = "Checkbox Group";
|
private static $singular_name = "Checkbox Group";
|
||||||
|
|
||||||
private static $plural_name = "Checkbox Groups";
|
private static $plural_name = "Checkbox Groups";
|
||||||
|
|
||||||
public function getFormField() {
|
public function getFormField()
|
||||||
$field = new UserFormsCheckboxSetField($this->Name, $this->EscapedTitle, $this->getOptionsMap());
|
{
|
||||||
$field->setFieldHolderTemplate('UserFormsMultipleOptionField_holder');
|
$field = new UserFormsCheckboxSetField($this->Name, $this->EscapedTitle, $this->getOptionsMap());
|
||||||
|
$field->setFieldHolderTemplate('UserFormsMultipleOptionField_holder');
|
||||||
|
|
||||||
// Set the default checked items
|
// Set the default checked items
|
||||||
$defaultCheckedItems = $this->getDefaultOptions();
|
$defaultCheckedItems = $this->getDefaultOptions();
|
||||||
if ($defaultCheckedItems->count()) {
|
if ($defaultCheckedItems->count()) {
|
||||||
$field->setDefaultItems($defaultCheckedItems->map('EscapedTitle')->keys());
|
$field->setDefaultItems($defaultCheckedItems->map('EscapedTitle')->keys());
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->doUpdateFormField($field);
|
$this->doUpdateFormField($field);
|
||||||
return $field;
|
return $field;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getValueFromData($data) {
|
public function getValueFromData($data)
|
||||||
$result = '';
|
{
|
||||||
$entries = (isset($data[$this->Name])) ? $data[$this->Name] : false;
|
$result = '';
|
||||||
|
$entries = (isset($data[$this->Name])) ? $data[$this->Name] : false;
|
||||||
|
|
||||||
if($entries) {
|
if ($entries) {
|
||||||
if(!is_array($data[$this->Name])) {
|
if (!is_array($data[$this->Name])) {
|
||||||
$entries = array($data[$this->Name]);
|
$entries = array($data[$this->Name]);
|
||||||
}
|
}
|
||||||
foreach($entries as $selected => $value) {
|
foreach ($entries as $selected => $value) {
|
||||||
if(!$result) {
|
if (!$result) {
|
||||||
$result = $value;
|
$result = $value;
|
||||||
} else {
|
} else {
|
||||||
$result .= ", " . $value;
|
$result .= ", " . $value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSelectorField(EditableCustomRule $rule, $forOnLoad = false) {
|
public function getSelectorField(EditableCustomRule $rule, $forOnLoad = false)
|
||||||
// watch out for checkboxs as the inputs don't have values but are 'checked
|
{
|
||||||
// @todo - Test this
|
// watch out for checkboxs as the inputs don't have values but are 'checked
|
||||||
if($rule->FieldValue) {
|
// @todo - Test this
|
||||||
return "$(\"input[name='{$this->Name}[]'][value='{$rule->FieldValue}']\")";
|
if ($rule->FieldValue) {
|
||||||
} else {
|
return "$(\"input[name='{$this->Name}[]'][value='{$rule->FieldValue}']\")";
|
||||||
return "$(\"input[name='{$this->Name}[]']:first\")";
|
} else {
|
||||||
}
|
return "$(\"input[name='{$this->Name}[]']:first\")";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,45 +5,51 @@
|
|||||||
*
|
*
|
||||||
* @package userforms
|
* @package userforms
|
||||||
*/
|
*/
|
||||||
class EditableCountryDropdownField extends EditableFormField {
|
class EditableCountryDropdownField extends EditableFormField
|
||||||
|
{
|
||||||
|
|
||||||
private static $singular_name = 'Country Dropdown';
|
private static $singular_name = 'Country Dropdown';
|
||||||
|
|
||||||
private static $plural_name = 'Country Dropdowns';
|
private static $plural_name = 'Country Dropdowns';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return FieldList
|
* @return FieldList
|
||||||
*/
|
*/
|
||||||
public function getCMSFields() {
|
public function getCMSFields()
|
||||||
$fields = parent::getCMSFields();
|
{
|
||||||
|
$fields = parent::getCMSFields();
|
||||||
|
|
||||||
$fields->removeByName('Default');
|
$fields->removeByName('Default');
|
||||||
|
|
||||||
return $fields;
|
return $fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getFormField() {
|
public function getFormField()
|
||||||
$field = CountryDropdownField::create($this->Name, $this->EscapedTitle)
|
{
|
||||||
->setFieldHolderTemplate('UserFormsField_holder')
|
$field = CountryDropdownField::create($this->Name, $this->EscapedTitle)
|
||||||
->setTemplate('UserFormsDropdownField');
|
->setFieldHolderTemplate('UserFormsField_holder')
|
||||||
|
->setTemplate('UserFormsDropdownField');
|
||||||
|
|
||||||
$this->doUpdateFormField($field);
|
$this->doUpdateFormField($field);
|
||||||
|
|
||||||
return $field;
|
return $field;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getValueFromData($data) {
|
public function getValueFromData($data)
|
||||||
if(isset($data[$this->Name])) {
|
{
|
||||||
$source = $this->getFormField()->getSource();
|
if (isset($data[$this->Name])) {
|
||||||
return $source[$data[$this->Name]];
|
$source = $this->getFormField()->getSource();
|
||||||
}
|
return $source[$data[$this->Name]];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function getIcon() {
|
public function getIcon()
|
||||||
return USERFORMS_DIR . '/images/editabledropdown.png';
|
{
|
||||||
}
|
return USERFORMS_DIR . '/images/editabledropdown.png';
|
||||||
|
}
|
||||||
|
|
||||||
public function getSelectorField(EditableCustomRule $rule, $forOnLoad = false) {
|
public function getSelectorField(EditableCustomRule $rule, $forOnLoad = false)
|
||||||
return "$(\"select[name='{$this->Name}']\")";
|
{
|
||||||
}
|
return "$(\"select[name='{$this->Name}']\")";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -7,60 +7,65 @@
|
|||||||
* @package userforms
|
* @package userforms
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class EditableDateField extends EditableFormField {
|
class EditableDateField extends EditableFormField
|
||||||
|
{
|
||||||
|
|
||||||
private static $singular_name = 'Date Field';
|
private static $singular_name = 'Date Field';
|
||||||
|
|
||||||
private static $plural_name = 'Date Fields';
|
private static $plural_name = 'Date Fields';
|
||||||
|
|
||||||
private static $db = array(
|
private static $db = array(
|
||||||
'DefaultToToday' => 'Boolean' // From customsettings
|
'DefaultToToday' => 'Boolean' // From customsettings
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return FieldList
|
* @return FieldList
|
||||||
*/
|
*/
|
||||||
public function getCMSFields() {
|
public function getCMSFields()
|
||||||
$this->beforeUpdateCMSFields(function(FieldList $fields) {
|
{
|
||||||
$fields->addFieldToTab(
|
$this->beforeUpdateCMSFields(function (FieldList $fields) {
|
||||||
'Root.Main',
|
$fields->addFieldToTab(
|
||||||
CheckboxField::create(
|
'Root.Main',
|
||||||
'DefaultToToday',
|
CheckboxField::create(
|
||||||
_t('EditableFormField.DEFAULTTOTODAY', 'Default to Today?')
|
'DefaultToToday',
|
||||||
),
|
_t('EditableFormField.DEFAULTTOTODAY', 'Default to Today?')
|
||||||
'RightTitle'
|
),
|
||||||
);
|
'RightTitle'
|
||||||
});
|
);
|
||||||
|
});
|
||||||
|
|
||||||
return parent::getCMSFields();
|
return parent::getCMSFields();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the form field
|
* Return the form field
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public function getFormField() {
|
public function getFormField()
|
||||||
$defaultValue = $this->DefaultToToday
|
{
|
||||||
? SS_Datetime::now()->Format('Y-m-d')
|
$defaultValue = $this->DefaultToToday
|
||||||
: $this->Default;
|
? SS_Datetime::now()->Format('Y-m-d')
|
||||||
|
: $this->Default;
|
||||||
|
|
||||||
$field = EditableDateField_FormField::create( $this->Name, $this->EscapedTitle, $defaultValue)
|
$field = EditableDateField_FormField::create($this->Name, $this->EscapedTitle, $defaultValue)
|
||||||
->setConfig('showcalendar', true)
|
->setConfig('showcalendar', true)
|
||||||
->setFieldHolderTemplate('UserFormsField_holder')
|
->setFieldHolderTemplate('UserFormsField_holder')
|
||||||
->setTemplate('UserFormsField');
|
->setTemplate('UserFormsField');
|
||||||
|
|
||||||
$this->doUpdateFormField($field);
|
$this->doUpdateFormField($field);
|
||||||
|
|
||||||
return $field;
|
return $field;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @package userforms
|
* @package userforms
|
||||||
*/
|
*/
|
||||||
class EditableDateField_FormField extends DateField {
|
class EditableDateField_FormField extends DateField
|
||||||
|
{
|
||||||
|
|
||||||
public function Type() {
|
public function Type()
|
||||||
return "date-alt text";
|
{
|
||||||
}
|
return "date-alt text";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -7,41 +7,45 @@
|
|||||||
* @package userforms
|
* @package userforms
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class EditableDropdown extends EditableMultipleOptionField {
|
class EditableDropdown extends EditableMultipleOptionField
|
||||||
|
{
|
||||||
|
|
||||||
private static $singular_name = 'Dropdown Field';
|
private static $singular_name = 'Dropdown Field';
|
||||||
|
|
||||||
private static $plural_name = 'Dropdowns';
|
private static $plural_name = 'Dropdowns';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return FieldList
|
* @return FieldList
|
||||||
*/
|
*/
|
||||||
public function getCMSFields() {
|
public function getCMSFields()
|
||||||
$fields = parent::getCMSFields();
|
{
|
||||||
|
$fields = parent::getCMSFields();
|
||||||
|
|
||||||
$fields->removeByName('Default');
|
$fields->removeByName('Default');
|
||||||
|
|
||||||
return $fields;
|
return $fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return DropdownField
|
* @return DropdownField
|
||||||
*/
|
*/
|
||||||
public function getFormField() {
|
public function getFormField()
|
||||||
$field = DropdownField::create($this->Name, $this->EscapedTitle, $this->getOptionsMap())
|
{
|
||||||
->setFieldHolderTemplate('UserFormsField_holder')
|
$field = DropdownField::create($this->Name, $this->EscapedTitle, $this->getOptionsMap())
|
||||||
->setTemplate('UserFormsDropdownField');
|
->setFieldHolderTemplate('UserFormsField_holder')
|
||||||
|
->setTemplate('UserFormsDropdownField');
|
||||||
|
|
||||||
// Set default
|
// Set default
|
||||||
$defaultOption = $this->getDefaultOptions()->first();
|
$defaultOption = $this->getDefaultOptions()->first();
|
||||||
if($defaultOption) {
|
if ($defaultOption) {
|
||||||
$field->setValue($defaultOption->EscapedTitle);
|
$field->setValue($defaultOption->EscapedTitle);
|
||||||
}
|
}
|
||||||
$this->doUpdateFormField($field);
|
$this->doUpdateFormField($field);
|
||||||
return $field;
|
return $field;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSelectorField(EditableCustomRule $rule, $forOnLoad = false) {
|
public function getSelectorField(EditableCustomRule $rule, $forOnLoad = false)
|
||||||
return "$(\"select[name='{$this->Name}']\")";
|
{
|
||||||
}
|
return "$(\"select[name='{$this->Name}']\")";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -7,56 +7,61 @@
|
|||||||
* @package userforms
|
* @package userforms
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class EditableEmailField extends EditableFormField {
|
class EditableEmailField extends EditableFormField
|
||||||
|
{
|
||||||
|
|
||||||
private static $singular_name = 'Email Field';
|
private static $singular_name = 'Email Field';
|
||||||
|
|
||||||
private static $plural_name = 'Email Fields';
|
private static $plural_name = 'Email Fields';
|
||||||
|
|
||||||
private static $db = array(
|
private static $db = array(
|
||||||
'Placeholder' => 'Varchar(255)'
|
'Placeholder' => 'Varchar(255)'
|
||||||
);
|
);
|
||||||
|
|
||||||
public function getCMSFields() {
|
public function getCMSFields()
|
||||||
$this->beforeUpdateCMSFields(function($fields) {
|
{
|
||||||
$fields->addFieldToTab(
|
$this->beforeUpdateCMSFields(function ($fields) {
|
||||||
'Root.Main',
|
$fields->addFieldToTab(
|
||||||
TextField::create(
|
'Root.Main',
|
||||||
'Placeholder',
|
TextField::create(
|
||||||
_t('EditableTextField.PLACEHOLDER', 'Placeholder')
|
'Placeholder',
|
||||||
)
|
_t('EditableTextField.PLACEHOLDER', 'Placeholder')
|
||||||
);
|
)
|
||||||
});
|
);
|
||||||
|
});
|
||||||
|
|
||||||
return parent::getCMSFields();
|
return parent::getCMSFields();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSetsOwnError() {
|
public function getSetsOwnError()
|
||||||
return true;
|
{
|
||||||
}
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public function getFormField() {
|
public function getFormField()
|
||||||
$field = EmailField::create($this->Name, $this->EscapedTitle, $this->Default)
|
{
|
||||||
->setFieldHolderTemplate('UserFormsField_holder')
|
$field = EmailField::create($this->Name, $this->EscapedTitle, $this->Default)
|
||||||
->setTemplate('UserFormsField');
|
->setFieldHolderTemplate('UserFormsField_holder')
|
||||||
|
->setTemplate('UserFormsField');
|
||||||
|
|
||||||
$this->doUpdateFormField($field);
|
$this->doUpdateFormField($field);
|
||||||
|
|
||||||
return $field;
|
return $field;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates a formfield with the additional metadata specified by this field
|
* Updates a formfield with the additional metadata specified by this field
|
||||||
*
|
*
|
||||||
* @param FormField $field
|
* @param FormField $field
|
||||||
*/
|
*/
|
||||||
protected function updateFormField($field) {
|
protected function updateFormField($field)
|
||||||
parent::updateFormField($field);
|
{
|
||||||
|
parent::updateFormField($field);
|
||||||
|
|
||||||
$field->setAttribute('data-rule-email', true);
|
$field->setAttribute('data-rule-email', true);
|
||||||
|
|
||||||
if($this->Placeholder) {
|
if ($this->Placeholder) {
|
||||||
$field->setAttribute('placeholder', $this->Placeholder);
|
$field->setAttribute('placeholder', $this->Placeholder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,90 +3,98 @@
|
|||||||
/**
|
/**
|
||||||
* Specifies that this ends a group of fields
|
* Specifies that this ends a group of fields
|
||||||
*/
|
*/
|
||||||
class EditableFieldGroup extends EditableFormField {
|
class EditableFieldGroup extends EditableFormField
|
||||||
|
{
|
||||||
|
|
||||||
private static $has_one = array(
|
private static $has_one = array(
|
||||||
'End' => 'EditableFieldGroupEnd'
|
'End' => 'EditableFieldGroupEnd'
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disable selection of group class
|
* Disable selection of group class
|
||||||
*
|
*
|
||||||
* @config
|
* @config
|
||||||
* @var bool
|
* @var bool
|
||||||
*/
|
*/
|
||||||
private static $hidden = true;
|
private static $hidden = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Non-data field type
|
* Non-data field type
|
||||||
*
|
*
|
||||||
* @var type
|
* @var type
|
||||||
*/
|
*/
|
||||||
private static $literal = true;
|
private static $literal = true;
|
||||||
|
|
||||||
public function getCMSFields() {
|
public function getCMSFields()
|
||||||
$fields = parent::getCMSFields();
|
{
|
||||||
$fields->removeByName(array('MergeField', 'Default', 'Validation', 'DisplayRules'));
|
$fields = parent::getCMSFields();
|
||||||
return $fields;
|
$fields->removeByName(array('MergeField', 'Default', 'Validation', 'DisplayRules'));
|
||||||
}
|
return $fields;
|
||||||
|
}
|
||||||
|
|
||||||
public function getCMSTitle() {
|
public function getCMSTitle()
|
||||||
$title = $this->getFieldNumber()
|
{
|
||||||
?: $this->Title
|
$title = $this->getFieldNumber()
|
||||||
?: 'group';
|
?: $this->Title
|
||||||
|
?: 'group';
|
||||||
|
|
||||||
return _t(
|
return _t(
|
||||||
'EditableFieldGroupEnd.FIELD_GROUP_START',
|
'EditableFieldGroupEnd.FIELD_GROUP_START',
|
||||||
'Group {group}',
|
'Group {group}',
|
||||||
array(
|
array(
|
||||||
'group' => $title
|
'group' => $title
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getInlineClassnameField($column, $fieldClasses) {
|
public function getInlineClassnameField($column, $fieldClasses)
|
||||||
return new LabelField($column, $this->CMSTitle);
|
{
|
||||||
}
|
return new LabelField($column, $this->CMSTitle);
|
||||||
|
}
|
||||||
|
|
||||||
public function showInReports() {
|
public function showInReports()
|
||||||
return false;
|
{
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public function getFormField() {
|
public function getFormField()
|
||||||
$field = UserFormsGroupField::create()
|
{
|
||||||
->setTitle($this->EscapedTitle ?: false)
|
$field = UserFormsGroupField::create()
|
||||||
->setName($this->Name);
|
->setTitle($this->EscapedTitle ?: false)
|
||||||
$this->doUpdateFormField($field);
|
->setName($this->Name);
|
||||||
return $field;
|
$this->doUpdateFormField($field);
|
||||||
}
|
return $field;
|
||||||
|
}
|
||||||
|
|
||||||
protected function updateFormField($field) {
|
protected function updateFormField($field)
|
||||||
// set the right title on this field
|
{
|
||||||
if($this->RightTitle) {
|
// set the right title on this field
|
||||||
// Since this field expects raw html, safely escape the user data prior
|
if ($this->RightTitle) {
|
||||||
$field->setRightTitle(Convert::raw2xml($this->RightTitle));
|
// Since this field expects raw html, safely escape the user data prior
|
||||||
}
|
$field->setRightTitle(Convert::raw2xml($this->RightTitle));
|
||||||
|
}
|
||||||
|
|
||||||
// if this field has an extra class
|
// if this field has an extra class
|
||||||
if($this->ExtraClass) {
|
if ($this->ExtraClass) {
|
||||||
$field->addExtraClass($this->ExtraClass);
|
$field->addExtraClass($this->ExtraClass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function onBeforeDelete() {
|
protected function onBeforeDelete()
|
||||||
parent::onBeforeDelete();
|
{
|
||||||
|
parent::onBeforeDelete();
|
||||||
|
|
||||||
// Ensures EndID is lazy-loaded for onAfterDelete
|
// Ensures EndID is lazy-loaded for onAfterDelete
|
||||||
$this->EndID;
|
$this->EndID;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function onAfterDelete() {
|
protected function onAfterDelete()
|
||||||
parent::onAfterDelete();
|
{
|
||||||
|
parent::onAfterDelete();
|
||||||
// Delete end
|
|
||||||
if(($end = $this->End()) && $end->exists()) {
|
|
||||||
$end->delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Delete end
|
||||||
|
if (($end = $this->End()) && $end->exists()) {
|
||||||
|
$end->delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,92 +3,100 @@
|
|||||||
/**
|
/**
|
||||||
* Specifies that this ends a group of fields
|
* Specifies that this ends a group of fields
|
||||||
*/
|
*/
|
||||||
class EditableFieldGroupEnd extends EditableFormField {
|
class EditableFieldGroupEnd extends EditableFormField
|
||||||
|
{
|
||||||
|
|
||||||
private static $belongs_to = array(
|
private static $belongs_to = array(
|
||||||
'Group' => 'EditableFieldGroup'
|
'Group' => 'EditableFieldGroup'
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disable selection of group class
|
* Disable selection of group class
|
||||||
*
|
*
|
||||||
* @config
|
* @config
|
||||||
* @var bool
|
* @var bool
|
||||||
*/
|
*/
|
||||||
private static $hidden = true;
|
private static $hidden = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Non-data type
|
* Non-data type
|
||||||
*
|
*
|
||||||
* @config
|
* @config
|
||||||
* @var bool
|
* @var bool
|
||||||
*/
|
*/
|
||||||
private static $literal = true;
|
private static $literal = true;
|
||||||
|
|
||||||
public function getCMSTitle() {
|
public function getCMSTitle()
|
||||||
$group = $this->Group();
|
{
|
||||||
return _t(
|
$group = $this->Group();
|
||||||
'EditableFieldGroupEnd.FIELD_GROUP_END',
|
return _t(
|
||||||
'{group} end',
|
'EditableFieldGroupEnd.FIELD_GROUP_END',
|
||||||
array(
|
'{group} end',
|
||||||
'group' => ($group && $group->exists()) ? $group->CMSTitle : 'Group'
|
array(
|
||||||
)
|
'group' => ($group && $group->exists()) ? $group->CMSTitle : 'Group'
|
||||||
);
|
)
|
||||||
}
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public function getCMSFields() {
|
public function getCMSFields()
|
||||||
$fields = parent::getCMSFields();
|
{
|
||||||
$fields->removeByName(array('MergeField', 'Default', 'Validation', 'DisplayRules'));
|
$fields = parent::getCMSFields();
|
||||||
return $fields;
|
$fields->removeByName(array('MergeField', 'Default', 'Validation', 'DisplayRules'));
|
||||||
}
|
return $fields;
|
||||||
|
}
|
||||||
|
|
||||||
public function getInlineClassnameField($column, $fieldClasses) {
|
public function getInlineClassnameField($column, $fieldClasses)
|
||||||
return new LabelField($column, $this->CMSTitle);
|
{
|
||||||
}
|
return new LabelField($column, $this->CMSTitle);
|
||||||
|
}
|
||||||
|
|
||||||
public function getInlineTitleField($column) {
|
public function getInlineTitleField($column)
|
||||||
return HiddenField::create($column);
|
{
|
||||||
}
|
return HiddenField::create($column);
|
||||||
|
}
|
||||||
|
|
||||||
public function getFormField() {
|
public function getFormField()
|
||||||
return null;
|
{
|
||||||
}
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public function showInReports() {
|
public function showInReports()
|
||||||
return false;
|
{
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public function onAfterWrite() {
|
public function onAfterWrite()
|
||||||
parent::onAfterWrite();
|
{
|
||||||
|
parent::onAfterWrite();
|
||||||
|
|
||||||
// If this is not attached to a group, find the first group prior to this
|
// If this is not attached to a group, find the first group prior to this
|
||||||
// with no end attached
|
// with no end attached
|
||||||
$group = $this->Group();
|
$group = $this->Group();
|
||||||
if(!($group && $group->exists()) && $this->ParentID) {
|
if (!($group && $group->exists()) && $this->ParentID) {
|
||||||
$group = EditableFieldGroup::get()
|
$group = EditableFieldGroup::get()
|
||||||
->filter(array(
|
->filter(array(
|
||||||
'ParentID' => $this->ParentID,
|
'ParentID' => $this->ParentID,
|
||||||
'Sort:LessThanOrEqual' => $this->Sort
|
'Sort:LessThanOrEqual' => $this->Sort
|
||||||
))
|
))
|
||||||
->where('"EditableFieldGroup"."EndID" IS NULL OR "EditableFieldGroup"."EndID" = 0')
|
->where('"EditableFieldGroup"."EndID" IS NULL OR "EditableFieldGroup"."EndID" = 0')
|
||||||
->sort('"Sort" DESC')
|
->sort('"Sort" DESC')
|
||||||
->first();
|
->first();
|
||||||
|
|
||||||
// When a group is found, attach it to this end
|
// When a group is found, attach it to this end
|
||||||
if($group) {
|
if ($group) {
|
||||||
$group->EndID = $this->ID;
|
$group->EndID = $this->ID;
|
||||||
$group->write();
|
$group->write();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function onAfterDelete() {
|
protected function onAfterDelete()
|
||||||
parent::onAfterDelete();
|
{
|
||||||
|
parent::onAfterDelete();
|
||||||
// Delete group
|
|
||||||
if(($group = $this->Group()) && $group->exists()) {
|
|
||||||
$group->delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Delete group
|
||||||
|
if (($group = $this->Group()) && $group->exists()) {
|
||||||
|
$group->delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,99 +6,105 @@
|
|||||||
* @package userforms
|
* @package userforms
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class EditableFileField extends EditableFormField {
|
class EditableFileField extends EditableFormField
|
||||||
|
{
|
||||||
|
|
||||||
private static $singular_name = 'File Upload Field';
|
private static $singular_name = 'File Upload Field';
|
||||||
|
|
||||||
private static $plural_names = 'File Fields';
|
private static $plural_names = 'File Fields';
|
||||||
|
|
||||||
private static $has_one = array(
|
private static $has_one = array(
|
||||||
'Folder' => 'Folder' // From CustomFields
|
'Folder' => 'Folder' // From CustomFields
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Further limit uploadable file extensions in addition to the restrictions
|
* Further limit uploadable file extensions in addition to the restrictions
|
||||||
* imposed by the File.allowed_extensions global configuration.
|
* imposed by the File.allowed_extensions global configuration.
|
||||||
* @config
|
* @config
|
||||||
*/
|
*/
|
||||||
private static $allowed_extensions_blacklist = array(
|
private static $allowed_extensions_blacklist = array(
|
||||||
'htm', 'html', 'xhtml', 'swf', 'xml'
|
'htm', 'html', 'xhtml', 'swf', 'xml'
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return FieldList
|
* @return FieldList
|
||||||
*/
|
*/
|
||||||
public function getCMSFields() {
|
public function getCMSFields()
|
||||||
$fields = parent::getCMSFields();
|
{
|
||||||
|
$fields = parent::getCMSFields();
|
||||||
|
|
||||||
$fields->addFieldToTab(
|
$fields->addFieldToTab(
|
||||||
'Root.Main',
|
'Root.Main',
|
||||||
TreeDropdownField::create(
|
TreeDropdownField::create(
|
||||||
'FolderID',
|
'FolderID',
|
||||||
_t('EditableUploadField.SELECTUPLOADFOLDER', 'Select upload folder'),
|
_t('EditableUploadField.SELECTUPLOADFOLDER', 'Select upload folder'),
|
||||||
'Folder'
|
'Folder'
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
$fields->addFieldToTab("Root.Main", new LiteralField("FileUploadWarning",
|
$fields->addFieldToTab("Root.Main", new LiteralField("FileUploadWarning",
|
||||||
"<p class=\"message notice\">" . _t("UserDefinedForm.FileUploadWarning",
|
"<p class=\"message notice\">" . _t("UserDefinedForm.FileUploadWarning",
|
||||||
"Files uploaded through this field could be publicly accessible if the exact URL is known")
|
"Files uploaded through this field could be publicly accessible if the exact URL is known")
|
||||||
. "</p>"), "Type");
|
. "</p>"), "Type");
|
||||||
|
|
||||||
return $fields;
|
return $fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getFormField() {
|
public function getFormField()
|
||||||
|
{
|
||||||
$field = FileField::create($this->Name, $this->EscapedTitle)
|
$field = FileField::create($this->Name, $this->EscapedTitle)
|
||||||
->setFieldHolderTemplate('UserFormsField_holder')
|
->setFieldHolderTemplate('UserFormsField_holder')
|
||||||
->setTemplate('UserFormsFileField');
|
->setTemplate('UserFormsFileField');
|
||||||
|
|
||||||
$field->setFieldHolderTemplate('UserFormsField_holder')
|
$field->setFieldHolderTemplate('UserFormsField_holder')
|
||||||
->setTemplate('UserFormsFileField');
|
->setTemplate('UserFormsFileField');
|
||||||
|
|
||||||
$field->getValidator()->setAllowedExtensions(
|
$field->getValidator()->setAllowedExtensions(
|
||||||
array_diff(
|
array_diff(
|
||||||
// filter out '' since this would be a regex problem on JS end
|
// filter out '' since this would be a regex problem on JS end
|
||||||
array_filter(Config::inst()->get('File', 'allowed_extensions')),
|
array_filter(Config::inst()->get('File', 'allowed_extensions')),
|
||||||
$this->config()->allowed_extensions_blacklist
|
$this->config()->allowed_extensions_blacklist
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
$folder = $this->Folder();
|
$folder = $this->Folder();
|
||||||
if($folder && $folder->exists()) {
|
if ($folder && $folder->exists()) {
|
||||||
$field->setFolderName(
|
$field->setFolderName(
|
||||||
preg_replace("/^assets\//","", $folder->Filename)
|
preg_replace("/^assets\//", "", $folder->Filename)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->doUpdateFormField($field);
|
$this->doUpdateFormField($field);
|
||||||
|
|
||||||
return $field;
|
return $field;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the value for the database, link to the file is stored as a
|
* Return the value for the database, link to the file is stored as a
|
||||||
* relation so value for the field can be null.
|
* relation so value for the field can be null.
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getValueFromData() {
|
public function getValueFromData()
|
||||||
return null;
|
{
|
||||||
}
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public function getSubmittedFormField() {
|
public function getSubmittedFormField()
|
||||||
return new SubmittedFileField();
|
{
|
||||||
}
|
return new SubmittedFileField();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public function migrateSettings($data) {
|
public function migrateSettings($data)
|
||||||
// Migrate 'Folder' setting to 'FolderID'
|
{
|
||||||
if(isset($data['Folder'])) {
|
// Migrate 'Folder' setting to 'FolderID'
|
||||||
$this->FolderID = $data['Folder'];
|
if (isset($data['Folder'])) {
|
||||||
unset($data['Folder']);
|
$this->FolderID = $data['Folder'];
|
||||||
}
|
unset($data['Folder']);
|
||||||
|
}
|
||||||
|
|
||||||
parent::migrateSettings($data);
|
parent::migrateSettings($data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,380 +17,387 @@ use SilverStripe\Forms\SegmentField;
|
|||||||
* @method UserDefinedForm Parent() Parent page
|
* @method UserDefinedForm Parent() Parent page
|
||||||
* @method DataList DisplayRules() List of EditableCustomRule objects
|
* @method DataList DisplayRules() List of EditableCustomRule objects
|
||||||
*/
|
*/
|
||||||
class EditableFormField extends DataObject {
|
class EditableFormField extends DataObject
|
||||||
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set to true to hide from class selector
|
* Set to true to hide from class selector
|
||||||
*
|
*
|
||||||
* @config
|
* @config
|
||||||
* @var bool
|
* @var bool
|
||||||
*/
|
*/
|
||||||
private static $hidden = false;
|
private static $hidden = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define this field as abstract (not inherited)
|
* Define this field as abstract (not inherited)
|
||||||
*
|
*
|
||||||
* @config
|
* @config
|
||||||
* @var bool
|
* @var bool
|
||||||
*/
|
*/
|
||||||
private static $abstract = true;
|
private static $abstract = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag this field type as non-data (e.g. literal, header, html)
|
* Flag this field type as non-data (e.g. literal, header, html)
|
||||||
*
|
*
|
||||||
* @config
|
* @config
|
||||||
* @var bool
|
* @var bool
|
||||||
*/
|
*/
|
||||||
private static $literal = false;
|
private static $literal = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default sort order
|
* Default sort order
|
||||||
*
|
*
|
||||||
* @config
|
* @config
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private static $default_sort = '"Sort"';
|
private static $default_sort = '"Sort"';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A list of CSS classes that can be added
|
* A list of CSS classes that can be added
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
public static $allowed_css = array();
|
public static $allowed_css = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @config
|
* @config
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
private static $summary_fields = array(
|
private static $summary_fields = array(
|
||||||
'Title'
|
'Title'
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @config
|
* @config
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
private static $db = array(
|
private static $db = array(
|
||||||
"Name" => "Varchar",
|
"Name" => "Varchar",
|
||||||
"Title" => "Varchar(255)",
|
"Title" => "Varchar(255)",
|
||||||
"Default" => "Varchar(255)",
|
"Default" => "Varchar(255)",
|
||||||
"Sort" => "Int",
|
"Sort" => "Int",
|
||||||
"Required" => "Boolean",
|
"Required" => "Boolean",
|
||||||
"CustomErrorMessage" => "Varchar(255)",
|
"CustomErrorMessage" => "Varchar(255)",
|
||||||
|
|
||||||
"CustomRules" => "Text", // @deprecated from 2.0
|
"CustomRules" => "Text", // @deprecated from 2.0
|
||||||
"CustomSettings" => "Text", // @deprecated from 2.0
|
"CustomSettings" => "Text", // @deprecated from 2.0
|
||||||
"Migrated" => "Boolean", // set to true when migrated
|
"Migrated" => "Boolean", // set to true when migrated
|
||||||
|
|
||||||
"ExtraClass" => "Text", // from CustomSettings
|
"ExtraClass" => "Text", // from CustomSettings
|
||||||
"RightTitle" => "Varchar(255)", // from CustomSettings
|
"RightTitle" => "Varchar(255)", // from CustomSettings
|
||||||
"ShowOnLoad" => "Boolean(1)", // from CustomSettings
|
"ShowOnLoad" => "Boolean(1)", // from CustomSettings
|
||||||
);
|
);
|
||||||
|
|
||||||
private static $defaults = array(
|
private static $defaults = array(
|
||||||
'ShowOnLoad' => true,
|
'ShowOnLoad' => true,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @config
|
* @config
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
private static $has_one = array(
|
private static $has_one = array(
|
||||||
"Parent" => "UserDefinedForm",
|
"Parent" => "UserDefinedForm",
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Built in extensions required
|
* Built in extensions required
|
||||||
*
|
*
|
||||||
* @config
|
* @config
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
private static $extensions = array(
|
private static $extensions = array(
|
||||||
"Versioned('Stage', 'Live')"
|
"Versioned('Stage', 'Live')"
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @config
|
* @config
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
private static $has_many = array(
|
private static $has_many = array(
|
||||||
"DisplayRules" => "EditableCustomRule.Parent" // from CustomRules
|
"DisplayRules" => "EditableCustomRule.Parent" // from CustomRules
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var bool
|
* @var bool
|
||||||
*/
|
*/
|
||||||
protected $readonly;
|
protected $readonly;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the visibility of an individual form field
|
* Set the visibility of an individual form field
|
||||||
*
|
*
|
||||||
* @param bool
|
* @param bool
|
||||||
*/
|
*/
|
||||||
public function setReadonly($readonly = true) {
|
public function setReadonly($readonly = true)
|
||||||
$this->readonly = $readonly;
|
{
|
||||||
}
|
$this->readonly = $readonly;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether this field is readonly
|
* Returns whether this field is readonly
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
private function isReadonly() {
|
private function isReadonly()
|
||||||
return $this->readonly;
|
{
|
||||||
}
|
return $this->readonly;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return FieldList
|
* @return FieldList
|
||||||
*/
|
*/
|
||||||
public function getCMSFields() {
|
public function getCMSFields()
|
||||||
$fields = new FieldList(new TabSet('Root'));
|
{
|
||||||
|
$fields = new FieldList(new TabSet('Root'));
|
||||||
|
|
||||||
// Main tab
|
// Main tab
|
||||||
$fields->addFieldsToTab(
|
$fields->addFieldsToTab(
|
||||||
'Root.Main',
|
'Root.Main',
|
||||||
array(
|
array(
|
||||||
ReadonlyField::create(
|
ReadonlyField::create(
|
||||||
'Type',
|
'Type',
|
||||||
_t('EditableFormField.TYPE', 'Type'),
|
_t('EditableFormField.TYPE', 'Type'),
|
||||||
$this->i18n_singular_name()
|
$this->i18n_singular_name()
|
||||||
),
|
),
|
||||||
LiteralField::create(
|
LiteralField::create(
|
||||||
'MergeField',
|
'MergeField',
|
||||||
_t(
|
_t(
|
||||||
'EditableFormField.MERGEFIELDNAME',
|
'EditableFormField.MERGEFIELDNAME',
|
||||||
'<div class="field readonly">' .
|
'<div class="field readonly">' .
|
||||||
'<label class="left">Merge field</label>' .
|
'<label class="left">Merge field</label>' .
|
||||||
'<div class="middleColumn">' .
|
'<div class="middleColumn">' .
|
||||||
'<span class="readonly">$' . $this->Name . '</span>' .
|
'<span class="readonly">$' . $this->Name . '</span>' .
|
||||||
'</div>' .
|
'</div>' .
|
||||||
'</div>'
|
'</div>'
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
TextField::create('Title'),
|
TextField::create('Title'),
|
||||||
TextField::create('Default', _t('EditableFormField.DEFAULT', 'Default value')),
|
TextField::create('Default', _t('EditableFormField.DEFAULT', 'Default value')),
|
||||||
TextField::create('RightTitle', _t('EditableFormField.RIGHTTITLE', 'Right title')),
|
TextField::create('RightTitle', _t('EditableFormField.RIGHTTITLE', 'Right title')),
|
||||||
SegmentField::create('Name')->setModifiers(array(
|
SegmentField::create('Name')->setModifiers(array(
|
||||||
UnderscoreSegmentFieldModifier::create()->setDefault('FieldName'),
|
UnderscoreSegmentFieldModifier::create()->setDefault('FieldName'),
|
||||||
DisambiguationSegmentFieldModifier::create(),
|
DisambiguationSegmentFieldModifier::create(),
|
||||||
))->setPreview($this->Name)
|
))->setPreview($this->Name)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Custom settings
|
// Custom settings
|
||||||
if (!empty(self::$allowed_css)) {
|
if (!empty(self::$allowed_css)) {
|
||||||
$cssList = array();
|
$cssList = array();
|
||||||
foreach(self::$allowed_css as $k => $v) {
|
foreach (self::$allowed_css as $k => $v) {
|
||||||
if (!is_array($v)) {
|
if (!is_array($v)) {
|
||||||
$cssList[$k]=$v;
|
$cssList[$k]=$v;
|
||||||
} elseif ($k === $this->ClassName) {
|
} elseif ($k === $this->ClassName) {
|
||||||
$cssList = array_merge($cssList, $v);
|
$cssList = array_merge($cssList, $v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$fields->addFieldToTab('Root.Main',
|
$fields->addFieldToTab('Root.Main',
|
||||||
DropdownField::create(
|
DropdownField::create(
|
||||||
'ExtraClass',
|
'ExtraClass',
|
||||||
_t('EditableFormField.EXTRACLASS_TITLE', 'Extra Styling/Layout'),
|
_t('EditableFormField.EXTRACLASS_TITLE', 'Extra Styling/Layout'),
|
||||||
$cssList
|
$cssList
|
||||||
)->setDescription(_t(
|
)->setDescription(_t(
|
||||||
'EditableFormField.EXTRACLASS_SELECT',
|
'EditableFormField.EXTRACLASS_SELECT',
|
||||||
'Select from the list of allowed styles'
|
'Select from the list of allowed styles'
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
$fields->addFieldToTab('Root.Main',
|
$fields->addFieldToTab('Root.Main',
|
||||||
TextField::create(
|
TextField::create(
|
||||||
'ExtraClass',
|
'ExtraClass',
|
||||||
_t('EditableFormField.EXTRACLASS_Title', 'Extra CSS classes')
|
_t('EditableFormField.EXTRACLASS_Title', 'Extra CSS classes')
|
||||||
)->setDescription(_t(
|
)->setDescription(_t(
|
||||||
'EditableFormField.EXTRACLASS_MULTIPLE',
|
'EditableFormField.EXTRACLASS_MULTIPLE',
|
||||||
'Separate each CSS class with a single space'
|
'Separate each CSS class with a single space'
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validation
|
// Validation
|
||||||
$validationFields = $this->getFieldValidationOptions();
|
$validationFields = $this->getFieldValidationOptions();
|
||||||
if($validationFields && $validationFields->count()) {
|
if ($validationFields && $validationFields->count()) {
|
||||||
$fields->addFieldsToTab('Root.Validation', $validationFields);
|
$fields->addFieldsToTab('Root.Validation', $validationFields);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add display rule fields
|
// Add display rule fields
|
||||||
$displayFields = $this->getDisplayRuleFields();
|
$displayFields = $this->getDisplayRuleFields();
|
||||||
if($displayFields && $displayFields->count()) {
|
if ($displayFields && $displayFields->count()) {
|
||||||
$fields->addFieldsToTab('Root.DisplayRules', $displayFields);
|
$fields->addFieldsToTab('Root.DisplayRules', $displayFields);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->extend('updateCMSFields', $fields);
|
$this->extend('updateCMSFields', $fields);
|
||||||
|
|
||||||
return $fields;
|
return $fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return fields to display on the 'Display Rules' tab
|
* Return fields to display on the 'Display Rules' tab
|
||||||
*
|
*
|
||||||
* @return FieldList
|
* @return FieldList
|
||||||
*/
|
*/
|
||||||
protected function getDisplayRuleFields() {
|
protected function getDisplayRuleFields()
|
||||||
// Check display rules
|
{
|
||||||
if($this->Required) {
|
// Check display rules
|
||||||
return new FieldList(
|
if ($this->Required) {
|
||||||
LabelField::create(_t(
|
return new FieldList(
|
||||||
'EditableFormField.DISPLAY_RULES_DISABLED',
|
LabelField::create(_t(
|
||||||
'Display rules are not enabled for required fields. ' .
|
'EditableFormField.DISPLAY_RULES_DISABLED',
|
||||||
'Please uncheck "Is this field Required?" under "Validation" to re-enable.'
|
'Display rules are not enabled for required fields. ' .
|
||||||
))->addExtraClass('message warning')
|
'Please uncheck "Is this field Required?" under "Validation" to re-enable.'
|
||||||
);
|
))->addExtraClass('message warning')
|
||||||
}
|
);
|
||||||
$self = $this;
|
}
|
||||||
$allowedClasses = array_keys($this->getEditableFieldClasses(false));
|
$self = $this;
|
||||||
$editableColumns = new GridFieldEditableColumns();
|
$allowedClasses = array_keys($this->getEditableFieldClasses(false));
|
||||||
$editableColumns->setDisplayFields(array(
|
$editableColumns = new GridFieldEditableColumns();
|
||||||
'Display' => '',
|
$editableColumns->setDisplayFields(array(
|
||||||
'ConditionFieldID' => function($record, $column, $grid) use ($allowedClasses, $self) {
|
'Display' => '',
|
||||||
return DropdownField::create(
|
'ConditionFieldID' => function ($record, $column, $grid) use ($allowedClasses, $self) {
|
||||||
$column,
|
return DropdownField::create(
|
||||||
'',
|
$column,
|
||||||
EditableFormField::get()
|
'',
|
||||||
->filter(array(
|
EditableFormField::get()
|
||||||
'ParentID' => $self->ParentID,
|
->filter(array(
|
||||||
'ClassName' => $allowedClasses
|
'ParentID' => $self->ParentID,
|
||||||
))
|
'ClassName' => $allowedClasses
|
||||||
->exclude(array(
|
))
|
||||||
'ID' => $self->ID
|
->exclude(array(
|
||||||
))
|
'ID' => $self->ID
|
||||||
->map('ID', 'Title')
|
))
|
||||||
);
|
->map('ID', 'Title')
|
||||||
},
|
);
|
||||||
'ConditionOption' => function($record, $column, $grid) {
|
},
|
||||||
$options = Config::inst()->get('EditableCustomRule', 'condition_options');
|
'ConditionOption' => function ($record, $column, $grid) {
|
||||||
return DropdownField::create($column, '', $options);
|
$options = Config::inst()->get('EditableCustomRule', 'condition_options');
|
||||||
},
|
return DropdownField::create($column, '', $options);
|
||||||
'FieldValue' => function($record, $column, $grid) {
|
},
|
||||||
return TextField::create($column);
|
'FieldValue' => function ($record, $column, $grid) {
|
||||||
},
|
return TextField::create($column);
|
||||||
'ParentID' => function($record, $column, $grid) use ($self) {
|
},
|
||||||
return HiddenField::create($column, '', $self->ID);
|
'ParentID' => function ($record, $column, $grid) use ($self) {
|
||||||
}
|
return HiddenField::create($column, '', $self->ID);
|
||||||
));
|
}
|
||||||
|
));
|
||||||
|
|
||||||
// Custom rules
|
// Custom rules
|
||||||
$customRulesConfig = GridFieldConfig::create()
|
$customRulesConfig = GridFieldConfig::create()
|
||||||
->addComponents(
|
->addComponents(
|
||||||
$editableColumns,
|
$editableColumns,
|
||||||
new GridFieldButtonRow(),
|
new GridFieldButtonRow(),
|
||||||
new GridFieldToolbarHeader(),
|
new GridFieldToolbarHeader(),
|
||||||
new GridFieldAddNewInlineButton(),
|
new GridFieldAddNewInlineButton(),
|
||||||
new GridFieldDeleteAction()
|
new GridFieldDeleteAction()
|
||||||
);
|
);
|
||||||
|
|
||||||
return new FieldList(
|
return new FieldList(
|
||||||
CheckboxField::create('ShowOnLoad')
|
CheckboxField::create('ShowOnLoad')
|
||||||
->setDescription(_t(
|
->setDescription(_t(
|
||||||
'EditableFormField.SHOWONLOAD',
|
'EditableFormField.SHOWONLOAD',
|
||||||
'Initial visibility before processing these rules'
|
'Initial visibility before processing these rules'
|
||||||
)),
|
)),
|
||||||
GridField::create(
|
GridField::create(
|
||||||
'DisplayRules',
|
'DisplayRules',
|
||||||
_t('EditableFormField.CUSTOMRULES', 'Custom Rules'),
|
_t('EditableFormField.CUSTOMRULES', 'Custom Rules'),
|
||||||
$this->DisplayRules(),
|
$this->DisplayRules(),
|
||||||
$customRulesConfig
|
$customRulesConfig
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onBeforeWrite() {
|
public function onBeforeWrite()
|
||||||
parent::onBeforeWrite();
|
{
|
||||||
|
parent::onBeforeWrite();
|
||||||
|
|
||||||
// Set a field name.
|
// Set a field name.
|
||||||
if(!$this->Name) {
|
if (!$this->Name) {
|
||||||
// New random name
|
// New random name
|
||||||
$this->Name = $this->generateName();
|
$this->Name = $this->generateName();
|
||||||
|
} elseif ($this->Name === 'Field') {
|
||||||
|
throw new ValidationException('Field name cannot be "Field"');
|
||||||
|
}
|
||||||
|
|
||||||
} elseif($this->Name === 'Field') {
|
if (!$this->Sort && $this->ParentID) {
|
||||||
throw new ValidationException('Field name cannot be "Field"');
|
$parentID = $this->ParentID;
|
||||||
}
|
$this->Sort = EditableFormField::get()
|
||||||
|
->filter('ParentID', $parentID)
|
||||||
|
->max('Sort') + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(!$this->Sort && $this->ParentID) {
|
/**
|
||||||
$parentID = $this->ParentID;
|
* Generate a new non-conflicting Name value
|
||||||
$this->Sort = EditableFormField::get()
|
*
|
||||||
->filter('ParentID', $parentID)
|
* @return string
|
||||||
->max('Sort') + 1;
|
*/
|
||||||
}
|
protected function generateName()
|
||||||
}
|
{
|
||||||
|
do {
|
||||||
|
// Generate a new random name after this class
|
||||||
|
$class = get_class($this);
|
||||||
|
$entropy = substr(sha1(uniqid()), 0, 5);
|
||||||
|
$name = "{$class}_{$entropy}";
|
||||||
|
|
||||||
/**
|
// Check if it conflicts
|
||||||
* Generate a new non-conflicting Name value
|
$exists = EditableFormField::get()->filter('Name', $name)->count() > 0;
|
||||||
*
|
} while ($exists);
|
||||||
* @return string
|
return $name;
|
||||||
*/
|
}
|
||||||
protected function generateName() {
|
|
||||||
do {
|
|
||||||
// Generate a new random name after this class
|
|
||||||
$class = get_class($this);
|
|
||||||
$entropy = substr(sha1(uniqid()), 0, 5);
|
|
||||||
$name = "{$class}_{$entropy}";
|
|
||||||
|
|
||||||
// Check if it conflicts
|
/**
|
||||||
$exists = EditableFormField::get()->filter('Name', $name)->count() > 0;
|
* Flag indicating that this field will set its own error message via data-msg='' attributes
|
||||||
} while($exists);
|
*
|
||||||
return $name;
|
* @return bool
|
||||||
}
|
*/
|
||||||
|
public function getSetsOwnError()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag indicating that this field will set its own error message via data-msg='' attributes
|
* Return whether a user can delete this form field
|
||||||
*
|
* based on whether they can edit the page
|
||||||
* @return bool
|
*
|
||||||
*/
|
|
||||||
public function getSetsOwnError() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return whether a user can delete this form field
|
|
||||||
* based on whether they can edit the page
|
|
||||||
*
|
|
||||||
* @param Member $member
|
* @param Member $member
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function canDelete($member = null) {
|
public function canDelete($member = null)
|
||||||
return $this->canEdit($member);
|
{
|
||||||
}
|
return $this->canEdit($member);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return whether a user can edit this form field
|
* Return whether a user can edit this form field
|
||||||
* based on whether they can edit the page
|
* based on whether they can edit the page
|
||||||
*
|
*
|
||||||
* @param Member $member
|
* @param Member $member
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function canEdit($member = null) {
|
public function canEdit($member = null)
|
||||||
|
{
|
||||||
$parent = $this->Parent();
|
$parent = $this->Parent();
|
||||||
if($parent && $parent->exists()) {
|
if ($parent && $parent->exists()) {
|
||||||
return $parent->canEdit($member) && !$this->isReadonly();
|
return $parent->canEdit($member) && !$this->isReadonly();
|
||||||
} else if (!$this->exists() && Controller::has_curr()) {
|
} elseif (!$this->exists() && Controller::has_curr()) {
|
||||||
// This is for GridFieldOrderableRows support as it checks edit permissions on
|
// This is for GridFieldOrderableRows support as it checks edit permissions on
|
||||||
// singleton of the class. Allows editing of User Defined Form pages by
|
// singleton of the class. Allows editing of User Defined Form pages by
|
||||||
// 'Content Authors' and those with permission to edit the UDF page. (ie. CanEditType/EditorGroups)
|
// 'Content Authors' and those with permission to edit the UDF page. (ie. CanEditType/EditorGroups)
|
||||||
// This is to restore User Forms 2.x backwards compatibility.
|
// This is to restore User Forms 2.x backwards compatibility.
|
||||||
$controller = Controller::curr();
|
$controller = Controller::curr();
|
||||||
if ($controller && $controller instanceof CMSPageEditController)
|
if ($controller && $controller instanceof CMSPageEditController) {
|
||||||
{
|
$parent = $controller->getRecord($controller->currentPageID());
|
||||||
$parent = $controller->getRecord($controller->currentPageID());
|
// Only allow this behaviour on pages using UserFormFieldEditorExtension, such
|
||||||
// Only allow this behaviour on pages using UserFormFieldEditorExtension, such
|
// as UserDefinedForm page type.
|
||||||
// as UserDefinedForm page type.
|
if ($parent && $parent->hasExtension('UserFormFieldEditorExtension')) {
|
||||||
if ($parent && $parent->hasExtension('UserFormFieldEditorExtension'))
|
return $parent->canEdit($member);
|
||||||
{
|
}
|
||||||
return $parent->canEdit($member);
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fallback to secure admin permissions
|
// Fallback to secure admin permissions
|
||||||
return parent::canEdit($member);
|
return parent::canEdit($member);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return whether a user can view this form field
|
* Return whether a user can view this form field
|
||||||
@ -399,32 +406,34 @@ class EditableFormField extends DataObject {
|
|||||||
* @param Member $member
|
* @param Member $member
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function canView($member = null) {
|
public function canView($member = null)
|
||||||
$parent = $this->Parent();
|
{
|
||||||
if($parent && $parent->exists()) {
|
$parent = $this->Parent();
|
||||||
return $parent->canView($member);
|
if ($parent && $parent->exists()) {
|
||||||
}
|
return $parent->canView($member);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return whether a user can create an object of this type
|
* Return whether a user can create an object of this type
|
||||||
*
|
*
|
||||||
* @param Member $member
|
* @param Member $member
|
||||||
* @param array $context Virtual parameter to allow context to be passed in to check
|
* @param array $context Virtual parameter to allow context to be passed in to check
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function canCreate($member = null) {
|
public function canCreate($member = null)
|
||||||
// Check parent page
|
{
|
||||||
|
// Check parent page
|
||||||
$parent = $this->getCanCreateContext(func_get_args());
|
$parent = $this->getCanCreateContext(func_get_args());
|
||||||
if($parent) {
|
if ($parent) {
|
||||||
return $parent->canEdit($member);
|
return $parent->canEdit($member);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fall back to secure admin permissions
|
// Fall back to secure admin permissions
|
||||||
return parent::canCreate($member);
|
return parent::canCreate($member);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to check the parent for this object
|
* Helper method to check the parent for this object
|
||||||
@ -432,13 +441,14 @@ class EditableFormField extends DataObject {
|
|||||||
* @param array $args List of arguments passed to canCreate
|
* @param array $args List of arguments passed to canCreate
|
||||||
* @return SiteTree Parent page instance
|
* @return SiteTree Parent page instance
|
||||||
*/
|
*/
|
||||||
protected function getCanCreateContext($args) {
|
protected function getCanCreateContext($args)
|
||||||
|
{
|
||||||
// Inspect second parameter to canCreate for a 'Parent' context
|
// Inspect second parameter to canCreate for a 'Parent' context
|
||||||
if(isset($args[1]['Parent'])) {
|
if (isset($args[1]['Parent'])) {
|
||||||
return $args[1]['Parent'];
|
return $args[1]['Parent'];
|
||||||
}
|
}
|
||||||
// Hack in currently edited page if context is missing
|
// Hack in currently edited page if context is missing
|
||||||
if(Controller::has_curr() && Controller::curr() instanceof CMSMain) {
|
if (Controller::has_curr() && Controller::curr() instanceof CMSMain) {
|
||||||
return Controller::curr()->currentPage();
|
return Controller::curr()->currentPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -452,7 +462,8 @@ class EditableFormField extends DataObject {
|
|||||||
* @param Member $member
|
* @param Member $member
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function canPublish($member = null) {
|
public function canPublish($member = null)
|
||||||
|
{
|
||||||
return $this->canEdit($member);
|
return $this->canEdit($member);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -462,445 +473,483 @@ class EditableFormField extends DataObject {
|
|||||||
* @param Member $member
|
* @param Member $member
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function canUnpublish($member = null) {
|
public function canUnpublish($member = null)
|
||||||
|
{
|
||||||
return $this->canDelete($member);
|
return $this->canDelete($member);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Publish this Form Field to the live site
|
* Publish this Form Field to the live site
|
||||||
*
|
*
|
||||||
* Wrapper for the {@link Versioned} publish function
|
* Wrapper for the {@link Versioned} publish function
|
||||||
*/
|
*/
|
||||||
public function doPublish($fromStage, $toStage, $createNewVersion = false) {
|
public function doPublish($fromStage, $toStage, $createNewVersion = false)
|
||||||
$this->publish($fromStage, $toStage, $createNewVersion);
|
{
|
||||||
|
$this->publish($fromStage, $toStage, $createNewVersion);
|
||||||
|
|
||||||
// Don't forget to publish the related custom rules...
|
// Don't forget to publish the related custom rules...
|
||||||
foreach ($this->DisplayRules() as $rule) {
|
foreach ($this->DisplayRules() as $rule) {
|
||||||
$rule->doPublish($fromStage, $toStage, $createNewVersion);
|
$rule->doPublish($fromStage, $toStage, $createNewVersion);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete this field from a given stage
|
* Delete this field from a given stage
|
||||||
*
|
*
|
||||||
* Wrapper for the {@link Versioned} deleteFromStage function
|
* Wrapper for the {@link Versioned} deleteFromStage function
|
||||||
*/
|
*/
|
||||||
public function doDeleteFromStage($stage) {
|
public function doDeleteFromStage($stage)
|
||||||
// Remove custom rules in this stage
|
{
|
||||||
$rules = Versioned::get_by_stage('EditableCustomRule', $stage)
|
// Remove custom rules in this stage
|
||||||
->filter('ParentID', $this->ID);
|
$rules = Versioned::get_by_stage('EditableCustomRule', $stage)
|
||||||
foreach ($rules as $rule) {
|
->filter('ParentID', $this->ID);
|
||||||
$rule->deleteFromStage($stage);
|
foreach ($rules as $rule) {
|
||||||
}
|
$rule->deleteFromStage($stage);
|
||||||
|
}
|
||||||
|
|
||||||
// Remove record
|
// Remove record
|
||||||
$this->deleteFromStage($stage);
|
$this->deleteFromStage($stage);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* checks wether record is new, copied from Sitetree
|
* checks wether record is new, copied from Sitetree
|
||||||
*/
|
*/
|
||||||
function isNew() {
|
public function isNew()
|
||||||
if(empty($this->ID)) return true;
|
{
|
||||||
|
if (empty($this->ID)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if(is_numeric($this->ID)) return false;
|
if (is_numeric($this->ID)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return stripos($this->ID, 'new') === 0;
|
return stripos($this->ID, 'new') === 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* checks if records is changed on stage
|
* checks if records is changed on stage
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function getIsModifiedOnStage() {
|
public function getIsModifiedOnStage()
|
||||||
// new unsaved fields could be never be published
|
{
|
||||||
if($this->isNew()) return false;
|
// new unsaved fields could be never be published
|
||||||
|
if ($this->isNew()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
$stageVersion = Versioned::get_versionnumber_by_stage('EditableFormField', 'Stage', $this->ID);
|
$stageVersion = Versioned::get_versionnumber_by_stage('EditableFormField', 'Stage', $this->ID);
|
||||||
$liveVersion = Versioned::get_versionnumber_by_stage('EditableFormField', 'Live', $this->ID);
|
$liveVersion = Versioned::get_versionnumber_by_stage('EditableFormField', 'Live', $this->ID);
|
||||||
|
|
||||||
return ($stageVersion && $stageVersion != $liveVersion);
|
return ($stageVersion && $stageVersion != $liveVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated since version 4.0
|
* @deprecated since version 4.0
|
||||||
*/
|
*/
|
||||||
public function getSettings() {
|
public function getSettings()
|
||||||
Deprecation::notice('4.0', 'getSettings is deprecated');
|
{
|
||||||
return (!empty($this->CustomSettings)) ? unserialize($this->CustomSettings) : array();
|
Deprecation::notice('4.0', 'getSettings is deprecated');
|
||||||
}
|
return (!empty($this->CustomSettings)) ? unserialize($this->CustomSettings) : array();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated since version 4.0
|
* @deprecated since version 4.0
|
||||||
*/
|
*/
|
||||||
public function setSettings($settings = array()) {
|
public function setSettings($settings = array())
|
||||||
Deprecation::notice('4.0', 'setSettings is deprecated');
|
{
|
||||||
$this->CustomSettings = serialize($settings);
|
Deprecation::notice('4.0', 'setSettings is deprecated');
|
||||||
}
|
$this->CustomSettings = serialize($settings);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated since version 4.0
|
* @deprecated since version 4.0
|
||||||
*/
|
*/
|
||||||
public function setSetting($key, $value) {
|
public function setSetting($key, $value)
|
||||||
Deprecation::notice('4.0', "setSetting({$key}) is deprecated");
|
{
|
||||||
$settings = $this->getSettings();
|
Deprecation::notice('4.0', "setSetting({$key}) is deprecated");
|
||||||
$settings[$key] = $value;
|
$settings = $this->getSettings();
|
||||||
|
$settings[$key] = $value;
|
||||||
|
|
||||||
$this->setSettings($settings);
|
$this->setSettings($settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the allowed css classes for the extraClass custom setting
|
* Set the allowed css classes for the extraClass custom setting
|
||||||
*
|
*
|
||||||
* @param array The permissible CSS classes to add
|
* @param array The permissible CSS classes to add
|
||||||
*/
|
*/
|
||||||
public function setAllowedCss(array $allowed) {
|
public function setAllowedCss(array $allowed)
|
||||||
if (is_array($allowed)) {
|
{
|
||||||
foreach ($allowed as $k => $v) {
|
if (is_array($allowed)) {
|
||||||
self::$allowed_css[$k] = (!is_null($v)) ? $v : $k;
|
foreach ($allowed as $k => $v) {
|
||||||
}
|
self::$allowed_css[$k] = (!is_null($v)) ? $v : $k;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated since version 4.0
|
* @deprecated since version 4.0
|
||||||
*/
|
*/
|
||||||
public function getSetting($setting) {
|
public function getSetting($setting)
|
||||||
Deprecation::notice("4.0", "getSetting({$setting}) is deprecated");
|
{
|
||||||
|
Deprecation::notice("4.0", "getSetting({$setting}) is deprecated");
|
||||||
|
|
||||||
$settings = $this->getSettings();
|
$settings = $this->getSettings();
|
||||||
if(isset($settings) && count($settings) > 0) {
|
if (isset($settings) && count($settings) > 0) {
|
||||||
if(isset($settings[$setting])) {
|
if (isset($settings[$setting])) {
|
||||||
return $settings[$setting];
|
return $settings[$setting];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the path to the icon for this field type, relative to the site root.
|
* Get the path to the icon for this field type, relative to the site root.
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getIcon() {
|
public function getIcon()
|
||||||
return USERFORMS_DIR . '/images/' . strtolower($this->class) . '.png';
|
{
|
||||||
}
|
return USERFORMS_DIR . '/images/' . strtolower($this->class) . '.png';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return whether or not this field has addable options
|
* Return whether or not this field has addable options
|
||||||
* such as a dropdown field or radio set
|
* such as a dropdown field or radio set
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function getHasAddableOptions() {
|
public function getHasAddableOptions()
|
||||||
return false;
|
{
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return whether or not this field needs to show the extra
|
* Return whether or not this field needs to show the extra
|
||||||
* options dropdown list
|
* options dropdown list
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function showExtraOptions() {
|
public function showExtraOptions()
|
||||||
return true;
|
{
|
||||||
}
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the Title for rendering in the front-end (with XML values escaped)
|
* Returns the Title for rendering in the front-end (with XML values escaped)
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getEscapedTitle() {
|
public function getEscapedTitle()
|
||||||
return Convert::raw2xml($this->Title);
|
{
|
||||||
}
|
return Convert::raw2xml($this->Title);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find the numeric indicator (1.1.2) that represents it's nesting value
|
* Find the numeric indicator (1.1.2) that represents it's nesting value
|
||||||
*
|
*
|
||||||
* Only useful for fields attached to a current page, and that contain other fields such as pages
|
* Only useful for fields attached to a current page, and that contain other fields such as pages
|
||||||
* or groups
|
* or groups
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getFieldNumber() {
|
public function getFieldNumber()
|
||||||
// Check if exists
|
{
|
||||||
if(!$this->exists()) {
|
// Check if exists
|
||||||
return null;
|
if (!$this->exists()) {
|
||||||
}
|
return null;
|
||||||
// Check parent
|
}
|
||||||
$form = $this->Parent();
|
// Check parent
|
||||||
if(!$form || !$form->exists() || !($fields = $form->Fields())) {
|
$form = $this->Parent();
|
||||||
return null;
|
if (!$form || !$form->exists() || !($fields = $form->Fields())) {
|
||||||
}
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
$prior = 0; // Number of prior group at this level
|
$prior = 0; // Number of prior group at this level
|
||||||
$stack = array(); // Current stack of nested groups, where the top level = the page
|
$stack = array(); // Current stack of nested groups, where the top level = the page
|
||||||
foreach($fields->map('ID', 'ClassName') as $id => $className) {
|
foreach ($fields->map('ID', 'ClassName') as $id => $className) {
|
||||||
if($className === 'EditableFormStep') {
|
if ($className === 'EditableFormStep') {
|
||||||
$priorPage = empty($stack) ? $prior : $stack[0];
|
$priorPage = empty($stack) ? $prior : $stack[0];
|
||||||
$stack = array($priorPage + 1);
|
$stack = array($priorPage + 1);
|
||||||
$prior = 0;
|
$prior = 0;
|
||||||
} elseif($className === 'EditableFieldGroup') {
|
} elseif ($className === 'EditableFieldGroup') {
|
||||||
$stack[] = $prior + 1;
|
$stack[] = $prior + 1;
|
||||||
$prior = 0;
|
$prior = 0;
|
||||||
} elseif($className === 'EditableFieldGroupEnd') {
|
} elseif ($className === 'EditableFieldGroupEnd') {
|
||||||
$prior = array_pop($stack);
|
$prior = array_pop($stack);
|
||||||
}
|
}
|
||||||
if($id == $this->ID) {
|
if ($id == $this->ID) {
|
||||||
return implode('.', $stack);
|
return implode('.', $stack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getCMSTitle() {
|
public function getCMSTitle()
|
||||||
return $this->i18n_singular_name() . ' (' . $this->Title . ')';
|
{
|
||||||
}
|
return $this->i18n_singular_name() . ' (' . $this->Title . ')';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated since version 4.0
|
* @deprecated since version 4.0
|
||||||
*/
|
*/
|
||||||
public function getFieldName($field = false) {
|
public function getFieldName($field = false)
|
||||||
Deprecation::notice('4.0', "getFieldName({$field}) is deprecated");
|
{
|
||||||
return ($field) ? "Fields[".$this->ID."][".$field."]" : "Fields[".$this->ID."]";
|
Deprecation::notice('4.0', "getFieldName({$field}) is deprecated");
|
||||||
}
|
return ($field) ? "Fields[".$this->ID."][".$field."]" : "Fields[".$this->ID."]";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated since version 4.0
|
* @deprecated since version 4.0
|
||||||
*/
|
*/
|
||||||
public function getSettingName($field) {
|
public function getSettingName($field)
|
||||||
Deprecation::notice('4.0', "getSettingName({$field}) is deprecated");
|
{
|
||||||
$name = $this->getFieldName('CustomSettings');
|
Deprecation::notice('4.0', "getSettingName({$field}) is deprecated");
|
||||||
|
$name = $this->getFieldName('CustomSettings');
|
||||||
|
|
||||||
return $name . '[' . $field .']';
|
return $name . '[' . $field .']';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Append custom validation fields to the default 'Validation'
|
* Append custom validation fields to the default 'Validation'
|
||||||
* section in the editable options view
|
* section in the editable options view
|
||||||
*
|
*
|
||||||
* @return FieldList
|
* @return FieldList
|
||||||
*/
|
*/
|
||||||
public function getFieldValidationOptions() {
|
public function getFieldValidationOptions()
|
||||||
$fields = new FieldList(
|
{
|
||||||
CheckboxField::create('Required', _t('EditableFormField.REQUIRED', 'Is this field Required?'))
|
$fields = new FieldList(
|
||||||
->setDescription(_t('EditableFormField.REQUIRED_DESCRIPTION', 'Please note that conditional fields can\'t be required')),
|
CheckboxField::create('Required', _t('EditableFormField.REQUIRED', 'Is this field Required?'))
|
||||||
TextField::create('CustomErrorMessage', _t('EditableFormField.CUSTOMERROR','Custom Error Message'))
|
->setDescription(_t('EditableFormField.REQUIRED_DESCRIPTION', 'Please note that conditional fields can\'t be required')),
|
||||||
);
|
TextField::create('CustomErrorMessage', _t('EditableFormField.CUSTOMERROR', 'Custom Error Message'))
|
||||||
|
);
|
||||||
|
|
||||||
$this->extend('updateFieldValidationOptions', $fields);
|
$this->extend('updateFieldValidationOptions', $fields);
|
||||||
|
|
||||||
return $fields;
|
return $fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a FormField to appear on the front end. Implement on
|
* Return a FormField to appear on the front end. Implement on
|
||||||
* your subclass.
|
* your subclass.
|
||||||
*
|
*
|
||||||
* @return FormField
|
* @return FormField
|
||||||
*/
|
*/
|
||||||
public function getFormField() {
|
public function getFormField()
|
||||||
user_error("Please implement a getFormField() on your EditableFormClass ". $this->ClassName, E_USER_ERROR);
|
{
|
||||||
}
|
user_error("Please implement a getFormField() on your EditableFormClass ". $this->ClassName, E_USER_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates a formfield with extensions
|
* Updates a formfield with extensions
|
||||||
*
|
*
|
||||||
* @param FormField $field
|
* @param FormField $field
|
||||||
*/
|
*/
|
||||||
public function doUpdateFormField($field) {
|
public function doUpdateFormField($field)
|
||||||
$this->extend('beforeUpdateFormField', $field);
|
{
|
||||||
$this->updateFormField($field);
|
$this->extend('beforeUpdateFormField', $field);
|
||||||
$this->extend('afterUpdateFormField', $field);
|
$this->updateFormField($field);
|
||||||
}
|
$this->extend('afterUpdateFormField', $field);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates a formfield with the additional metadata specified by this field
|
* Updates a formfield with the additional metadata specified by this field
|
||||||
*
|
*
|
||||||
* @param FormField $field
|
* @param FormField $field
|
||||||
*/
|
*/
|
||||||
protected function updateFormField($field) {
|
protected function updateFormField($field)
|
||||||
// set the error / formatting messages
|
{
|
||||||
$field->setCustomValidationMessage($this->getErrorMessage()->RAW());
|
// set the error / formatting messages
|
||||||
|
$field->setCustomValidationMessage($this->getErrorMessage()->RAW());
|
||||||
|
|
||||||
// set the right title on this field
|
// set the right title on this field
|
||||||
if($this->RightTitle) {
|
if ($this->RightTitle) {
|
||||||
// Since this field expects raw html, safely escape the user data prior
|
// Since this field expects raw html, safely escape the user data prior
|
||||||
$field->setRightTitle(Convert::raw2xml($this->RightTitle));
|
$field->setRightTitle(Convert::raw2xml($this->RightTitle));
|
||||||
}
|
}
|
||||||
|
|
||||||
// if this field is required add some
|
// if this field is required add some
|
||||||
if($this->Required) {
|
if ($this->Required) {
|
||||||
// Required validation can conflict so add the Required validation messages as input attributes
|
// Required validation can conflict so add the Required validation messages as input attributes
|
||||||
$errorMessage = $this->getErrorMessage()->HTML();
|
$errorMessage = $this->getErrorMessage()->HTML();
|
||||||
$field->addExtraClass('requiredField');
|
$field->addExtraClass('requiredField');
|
||||||
$field->setAttribute('data-rule-required', 'true');
|
$field->setAttribute('data-rule-required', 'true');
|
||||||
$field->setAttribute('data-msg-required', $errorMessage);
|
$field->setAttribute('data-msg-required', $errorMessage);
|
||||||
|
|
||||||
if($identifier = UserDefinedForm::config()->required_identifier) {
|
if ($identifier = UserDefinedForm::config()->required_identifier) {
|
||||||
$title = $field->Title() . " <span class='required-identifier'>". $identifier . "</span>";
|
$title = $field->Title() . " <span class='required-identifier'>". $identifier . "</span>";
|
||||||
$field->setTitle($title);
|
$field->setTitle($title);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if this field has an extra class
|
// if this field has an extra class
|
||||||
if($this->ExtraClass) {
|
if ($this->ExtraClass) {
|
||||||
$field->addExtraClass($this->ExtraClass);
|
$field->addExtraClass($this->ExtraClass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the instance of the submission field class
|
* Return the instance of the submission field class
|
||||||
*
|
*
|
||||||
* @return SubmittedFormField
|
* @return SubmittedFormField
|
||||||
*/
|
*/
|
||||||
public function getSubmittedFormField() {
|
public function getSubmittedFormField()
|
||||||
return new SubmittedFormField();
|
{
|
||||||
}
|
return new SubmittedFormField();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show this form field (and its related value) in the reports and in emails.
|
* Show this form field (and its related value) in the reports and in emails.
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function showInReports() {
|
public function showInReports()
|
||||||
return true;
|
{
|
||||||
}
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the error message for this field. Either uses the custom
|
* Return the error message for this field. Either uses the custom
|
||||||
* one (if provided) or the default SilverStripe message
|
* one (if provided) or the default SilverStripe message
|
||||||
*
|
*
|
||||||
* @return Varchar
|
* @return Varchar
|
||||||
*/
|
*/
|
||||||
public function getErrorMessage() {
|
public function getErrorMessage()
|
||||||
$title = strip_tags("'". ($this->Title ? $this->Title : $this->Name) . "'");
|
{
|
||||||
$standard = sprintf(_t('Form.FIELDISREQUIRED', '%s is required').'.', $title);
|
$title = strip_tags("'". ($this->Title ? $this->Title : $this->Name) . "'");
|
||||||
|
$standard = sprintf(_t('Form.FIELDISREQUIRED', '%s is required').'.', $title);
|
||||||
|
|
||||||
// only use CustomErrorMessage if it has a non empty value
|
// only use CustomErrorMessage if it has a non empty value
|
||||||
$errorMessage = (!empty($this->CustomErrorMessage)) ? $this->CustomErrorMessage : $standard;
|
$errorMessage = (!empty($this->CustomErrorMessage)) ? $this->CustomErrorMessage : $standard;
|
||||||
|
|
||||||
return DBField::create_field('Varchar', $errorMessage);
|
return DBField::create_field('Varchar', $errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoked by UserFormUpgradeService to migrate settings specific to this field from CustomSettings
|
* Invoked by UserFormUpgradeService to migrate settings specific to this field from CustomSettings
|
||||||
* to the field proper
|
* to the field proper
|
||||||
*
|
*
|
||||||
* @param array $data Unserialised data
|
* @param array $data Unserialised data
|
||||||
*/
|
*/
|
||||||
public function migrateSettings($data) {
|
public function migrateSettings($data)
|
||||||
// Map 'Show' / 'Hide' to boolean
|
{
|
||||||
if(isset($data['ShowOnLoad'])) {
|
// Map 'Show' / 'Hide' to boolean
|
||||||
$this->ShowOnLoad = $data['ShowOnLoad'] === '' || ($data['ShowOnLoad'] && $data['ShowOnLoad'] !== 'Hide');
|
if (isset($data['ShowOnLoad'])) {
|
||||||
unset($data['ShowOnLoad']);
|
$this->ShowOnLoad = $data['ShowOnLoad'] === '' || ($data['ShowOnLoad'] && $data['ShowOnLoad'] !== 'Hide');
|
||||||
}
|
unset($data['ShowOnLoad']);
|
||||||
|
}
|
||||||
|
|
||||||
// Migrate all other settings
|
// Migrate all other settings
|
||||||
foreach($data as $key => $value) {
|
foreach ($data as $key => $value) {
|
||||||
if($this->hasField($key)) {
|
if ($this->hasField($key)) {
|
||||||
$this->setField($key, $value);
|
$this->setField($key, $value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the formfield to use when editing this inline in gridfield
|
* Get the formfield to use when editing this inline in gridfield
|
||||||
*
|
*
|
||||||
* @param string $column name of column
|
* @param string $column name of column
|
||||||
* @param array $fieldClasses List of allowed classnames if this formfield has a selectable class
|
* @param array $fieldClasses List of allowed classnames if this formfield has a selectable class
|
||||||
* @return FormField
|
* @return FormField
|
||||||
*/
|
*/
|
||||||
public function getInlineClassnameField($column, $fieldClasses) {
|
public function getInlineClassnameField($column, $fieldClasses)
|
||||||
return DropdownField::create($column, false, $fieldClasses);
|
{
|
||||||
}
|
return DropdownField::create($column, false, $fieldClasses);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the formfield to use when editing the title inline
|
* Get the formfield to use when editing the title inline
|
||||||
*
|
*
|
||||||
* @param string $column
|
* @param string $column
|
||||||
* @return FormField
|
* @return FormField
|
||||||
*/
|
*/
|
||||||
public function getInlineTitleField($column) {
|
public function getInlineTitleField($column)
|
||||||
return TextField::create($column, false)
|
{
|
||||||
->setAttribute('placeholder', _t('EditableFormField.TITLE', 'Title'))
|
return TextField::create($column, false)
|
||||||
->setAttribute('data-placeholder', _t('EditableFormField.TITLE', 'Title'));
|
->setAttribute('placeholder', _t('EditableFormField.TITLE', 'Title'))
|
||||||
}
|
->setAttribute('data-placeholder', _t('EditableFormField.TITLE', 'Title'));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the JS expression for selecting the holder for this field
|
* Get the JS expression for selecting the holder for this field
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getSelectorHolder() {
|
public function getSelectorHolder()
|
||||||
return "$(\"#{$this->Name}\")";
|
{
|
||||||
}
|
return "$(\"#{$this->Name}\")";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the JS expression for selecting the value for this field
|
* Gets the JS expression for selecting the value for this field
|
||||||
*
|
*
|
||||||
* @param EditableCustomRule $rule Custom rule this selector will be used with
|
* @param EditableCustomRule $rule Custom rule this selector will be used with
|
||||||
* @param bool $forOnLoad Set to true if this will be invoked on load
|
* @param bool $forOnLoad Set to true if this will be invoked on load
|
||||||
*/
|
*/
|
||||||
public function getSelectorField(EditableCustomRule $rule, $forOnLoad = false) {
|
public function getSelectorField(EditableCustomRule $rule, $forOnLoad = false)
|
||||||
return "$(\"input[name='{$this->Name}']\")";
|
{
|
||||||
}
|
return "$(\"input[name='{$this->Name}']\")";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the list of classes that can be selected and used as data-values
|
* Get the list of classes that can be selected and used as data-values
|
||||||
*
|
*
|
||||||
* @param $includeLiterals Set to false to exclude non-data fields
|
* @param $includeLiterals Set to false to exclude non-data fields
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function getEditableFieldClasses($includeLiterals = true) {
|
public function getEditableFieldClasses($includeLiterals = true)
|
||||||
$classes = ClassInfo::getValidSubClasses('EditableFormField');
|
{
|
||||||
|
$classes = ClassInfo::getValidSubClasses('EditableFormField');
|
||||||
|
|
||||||
// Remove classes we don't want to display in the dropdown.
|
// Remove classes we don't want to display in the dropdown.
|
||||||
$editableFieldClasses = array();
|
$editableFieldClasses = array();
|
||||||
foreach ($classes as $class) {
|
foreach ($classes as $class) {
|
||||||
// Skip abstract / hidden classes
|
// Skip abstract / hidden classes
|
||||||
if(Config::inst()->get($class, 'abstract', Config::UNINHERITED) || Config::inst()->get($class, 'hidden')
|
if (Config::inst()->get($class, 'abstract', Config::UNINHERITED) || Config::inst()->get($class, 'hidden')
|
||||||
) {
|
) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!$includeLiterals && Config::inst()->get($class, 'literal')) {
|
if (!$includeLiterals && Config::inst()->get($class, 'literal')) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$singleton = singleton($class);
|
$singleton = singleton($class);
|
||||||
if(!$singleton->canCreate()) {
|
if (!$singleton->canCreate()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$editableFieldClasses[$class] = $singleton->i18n_singular_name();
|
$editableFieldClasses[$class] = $singleton->i18n_singular_name();
|
||||||
}
|
}
|
||||||
|
|
||||||
asort($editableFieldClasses);
|
asort($editableFieldClasses);
|
||||||
return $editableFieldClasses;
|
return $editableFieldClasses;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return EditableFormFieldValidator
|
* @return EditableFormFieldValidator
|
||||||
*/
|
*/
|
||||||
public function getCMSValidator() {
|
public function getCMSValidator()
|
||||||
return EditableFormFieldValidator::create()
|
{
|
||||||
->setRecord($this);
|
return EditableFormFieldValidator::create()
|
||||||
}
|
->setRecord($this);
|
||||||
|
}
|
||||||
/**
|
|
||||||
* Determine effective display rules for this field.
|
|
||||||
*
|
|
||||||
* @return SS_List
|
|
||||||
*/
|
|
||||||
public function EffectiveDisplayRules() {
|
|
||||||
if($this->Required) {
|
|
||||||
return new ArrayList();
|
|
||||||
}
|
|
||||||
return $this->DisplayRules();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine effective display rules for this field.
|
||||||
|
*
|
||||||
|
* @return SS_List
|
||||||
|
*/
|
||||||
|
public function EffectiveDisplayRules()
|
||||||
|
{
|
||||||
|
if ($this->Required) {
|
||||||
|
return new ArrayList();
|
||||||
|
}
|
||||||
|
return $this->DisplayRules();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,61 +1,65 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
class EditableFormFieldValidator extends RequiredFields {
|
class EditableFormFieldValidator extends RequiredFields
|
||||||
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @var EditableFormField
|
* @var EditableFormField
|
||||||
*/
|
*/
|
||||||
protected $record = null;
|
protected $record = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param EditableFormField $record
|
* @param EditableFormField $record
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function setRecord($record) {
|
public function setRecord($record)
|
||||||
$this->record = $record;
|
{
|
||||||
return $this;
|
$this->record = $record;
|
||||||
}
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @return EditableFormField
|
* @return EditableFormField
|
||||||
*/
|
*/
|
||||||
public function getRecord() {
|
public function getRecord()
|
||||||
return $this->record;
|
{
|
||||||
}
|
return $this->record;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public function php($data) {
|
public function php($data)
|
||||||
if(!parent::php($data)) {
|
{
|
||||||
return false;
|
if (!parent::php($data)) {
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Skip unsaved records
|
// Skip unsaved records
|
||||||
if(!$this->record || !$this->record->exists()) {
|
if (!$this->record || !$this->record->exists()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip validation if not required
|
// Skip validation if not required
|
||||||
if(empty($data['Required'])) {
|
if (empty($data['Required'])) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip validation if no rules
|
// Skip validation if no rules
|
||||||
$count = EditableCustomRule::get()->filter('ParentID', $this->record->ID)->count();
|
$count = EditableCustomRule::get()->filter('ParentID', $this->record->ID)->count();
|
||||||
if($count == 0) {
|
if ($count == 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Both required = true and rules > 0 should error
|
// Both required = true and rules > 0 should error
|
||||||
$this->validationError(
|
$this->validationError(
|
||||||
'Required_Error',
|
'Required_Error',
|
||||||
_t(
|
_t(
|
||||||
"EditableFormFieldValidator.REQUIRED_ERROR",
|
"EditableFormFieldValidator.REQUIRED_ERROR",
|
||||||
"Form fields cannot be required and have conditional display rules."
|
"Form fields cannot be required and have conditional display rules."
|
||||||
),
|
),
|
||||||
'error'
|
'error'
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,89 +5,97 @@
|
|||||||
* @package userforms
|
* @package userforms
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class EditableFormHeading extends EditableFormField {
|
class EditableFormHeading extends EditableFormField
|
||||||
|
{
|
||||||
|
|
||||||
private static $singular_name = 'Heading';
|
private static $singular_name = 'Heading';
|
||||||
|
|
||||||
private static $plural_name = 'Headings';
|
private static $plural_name = 'Headings';
|
||||||
|
|
||||||
private static $literal = true;
|
private static $literal = true;
|
||||||
|
|
||||||
private static $db = array(
|
private static $db = array(
|
||||||
'Level' => 'Int(3)', // From CustomSettings
|
'Level' => 'Int(3)', // From CustomSettings
|
||||||
'HideFromReports' => 'Boolean(0)' // from CustomSettings
|
'HideFromReports' => 'Boolean(0)' // from CustomSettings
|
||||||
);
|
);
|
||||||
|
|
||||||
private static $defaults = array(
|
private static $defaults = array(
|
||||||
'Level' => 3,
|
'Level' => 3,
|
||||||
'HideFromReports' => false
|
'HideFromReports' => false
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return FieldList
|
* @return FieldList
|
||||||
*/
|
*/
|
||||||
public function getCMSFields() {
|
public function getCMSFields()
|
||||||
$fields = parent::getCMSFields();
|
{
|
||||||
|
$fields = parent::getCMSFields();
|
||||||
|
|
||||||
$fields->removeByName(array('Default', 'Validation', 'RightTitle'));
|
$fields->removeByName(array('Default', 'Validation', 'RightTitle'));
|
||||||
|
|
||||||
$levels = array(
|
$levels = array(
|
||||||
'1' => '1',
|
'1' => '1',
|
||||||
'2' => '2',
|
'2' => '2',
|
||||||
'3' => '3',
|
'3' => '3',
|
||||||
'4' => '4',
|
'4' => '4',
|
||||||
'5' => '5',
|
'5' => '5',
|
||||||
'6' => '6'
|
'6' => '6'
|
||||||
);
|
);
|
||||||
|
|
||||||
$fields->addFieldsToTab('Root.Main', array(
|
$fields->addFieldsToTab('Root.Main', array(
|
||||||
DropdownField::create(
|
DropdownField::create(
|
||||||
'Level',
|
'Level',
|
||||||
_t('EditableFormHeading.LEVEL', 'Select Heading Level'),
|
_t('EditableFormHeading.LEVEL', 'Select Heading Level'),
|
||||||
$levels
|
$levels
|
||||||
),
|
),
|
||||||
CheckboxField::create(
|
CheckboxField::create(
|
||||||
'HideFromReports',
|
'HideFromReports',
|
||||||
_t('EditableLiteralField.HIDEFROMREPORT', 'Hide from reports?')
|
_t('EditableLiteralField.HIDEFROMREPORT', 'Hide from reports?')
|
||||||
)
|
)
|
||||||
));
|
));
|
||||||
|
|
||||||
return $fields;
|
return $fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getFormField() {
|
public function getFormField()
|
||||||
$labelField = new HeaderField($this->Name, $this->EscapedTitle, $this->Level);
|
{
|
||||||
$labelField->addExtraClass('FormHeading');
|
$labelField = new HeaderField($this->Name, $this->EscapedTitle, $this->Level);
|
||||||
$labelField->setAttribute('data-id', $this->Name);
|
$labelField->addExtraClass('FormHeading');
|
||||||
$this->doUpdateFormField($labelField);
|
$labelField->setAttribute('data-id', $this->Name);
|
||||||
return $labelField;
|
$this->doUpdateFormField($labelField);
|
||||||
}
|
return $labelField;
|
||||||
|
}
|
||||||
|
|
||||||
protected function updateFormField($field) {
|
protected function updateFormField($field)
|
||||||
// set the right title on this field
|
{
|
||||||
if($this->RightTitle) {
|
// set the right title on this field
|
||||||
// Since this field expects raw html, safely escape the user data prior
|
if ($this->RightTitle) {
|
||||||
$field->setRightTitle(Convert::raw2xml($this->RightTitle));
|
// Since this field expects raw html, safely escape the user data prior
|
||||||
}
|
$field->setRightTitle(Convert::raw2xml($this->RightTitle));
|
||||||
// if this field has an extra class
|
}
|
||||||
if($this->ExtraClass) {
|
// if this field has an extra class
|
||||||
$field->addExtraClass($this->ExtraClass);
|
if ($this->ExtraClass) {
|
||||||
}
|
$field->addExtraClass($this->ExtraClass);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function showInReports() {
|
public function showInReports()
|
||||||
return !$this->HideFromReports;
|
{
|
||||||
}
|
return !$this->HideFromReports;
|
||||||
|
}
|
||||||
|
|
||||||
public function getFieldValidationOptions() {
|
public function getFieldValidationOptions()
|
||||||
return false;
|
{
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public function getSelectorHolder() {
|
public function getSelectorHolder()
|
||||||
return "$(\":header[data-id='{$this->Name}']\")";
|
{
|
||||||
}
|
return "$(\":header[data-id='{$this->Name}']\")";
|
||||||
|
}
|
||||||
|
|
||||||
public function getLevel() {
|
public function getLevel()
|
||||||
return $this->getField('Level') ?: 3;
|
{
|
||||||
}
|
return $this->getField('Level') ?: 3;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,83 +4,91 @@
|
|||||||
*
|
*
|
||||||
* @package userforms
|
* @package userforms
|
||||||
*/
|
*/
|
||||||
class EditableFormStep extends EditableFormField {
|
class EditableFormStep extends EditableFormField
|
||||||
|
{
|
||||||
|
|
||||||
private static $singular_name = 'Page Break';
|
private static $singular_name = 'Page Break';
|
||||||
|
|
||||||
private static $plural_name = 'Page Breaks';
|
private static $plural_name = 'Page Breaks';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disable selection of step class
|
* Disable selection of step class
|
||||||
*
|
*
|
||||||
* @config
|
* @config
|
||||||
* @var bool
|
* @var bool
|
||||||
*/
|
*/
|
||||||
private static $hidden = true;
|
private static $hidden = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return FieldList
|
* @return FieldList
|
||||||
*/
|
*/
|
||||||
public function getCMSFields() {
|
public function getCMSFields()
|
||||||
$fields = parent::getCMSFields();
|
{
|
||||||
|
$fields = parent::getCMSFields();
|
||||||
|
|
||||||
$fields->removeByName(array('MergeField', 'Default', 'Validation', 'RightTitle'));
|
$fields->removeByName(array('MergeField', 'Default', 'Validation', 'RightTitle'));
|
||||||
|
|
||||||
return $fields;
|
return $fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return FormField
|
* @return FormField
|
||||||
*/
|
*/
|
||||||
public function getFormField() {
|
public function getFormField()
|
||||||
$field = UserFormsStepField::create()
|
{
|
||||||
->setName($this->Name)
|
$field = UserFormsStepField::create()
|
||||||
->setTitle($this->EscapedTitle);
|
->setName($this->Name)
|
||||||
$this->doUpdateFormField($field);
|
->setTitle($this->EscapedTitle);
|
||||||
return $field;
|
$this->doUpdateFormField($field);
|
||||||
}
|
return $field;
|
||||||
|
}
|
||||||
|
|
||||||
protected function updateFormField($field) {
|
protected function updateFormField($field)
|
||||||
// if this field has an extra class
|
{
|
||||||
if($this->ExtraClass) {
|
// if this field has an extra class
|
||||||
$field->addExtraClass($this->ExtraClass);
|
if ($this->ExtraClass) {
|
||||||
}
|
$field->addExtraClass($this->ExtraClass);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function showInReports() {
|
public function showInReports()
|
||||||
return false;
|
{
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public function getInlineClassnameField($column, $fieldClasses) {
|
public function getInlineClassnameField($column, $fieldClasses)
|
||||||
return new LabelField(
|
{
|
||||||
$column,
|
return new LabelField(
|
||||||
$this->CMSTitle
|
$column,
|
||||||
);
|
$this->CMSTitle
|
||||||
}
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public function getCMSTitle() {
|
public function getCMSTitle()
|
||||||
$title = $this->getFieldNumber()
|
{
|
||||||
?: $this->Title
|
$title = $this->getFieldNumber()
|
||||||
?: '';
|
?: $this->Title
|
||||||
|
?: '';
|
||||||
|
|
||||||
return _t(
|
return _t(
|
||||||
'EditableFormStep.STEP_TITLE',
|
'EditableFormStep.STEP_TITLE',
|
||||||
'Page {page}',
|
'Page {page}',
|
||||||
array(
|
array(
|
||||||
'page' => $title
|
'page' => $title
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the JS expression for selecting the holder for this field
|
* Get the JS expression for selecting the holder for this field
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getSelectorHolder() {
|
public function getSelectorHolder()
|
||||||
return "$(\".step-button-wrapper[data-for='{$this->Name}']\")";
|
{
|
||||||
}
|
return "$(\".step-button-wrapper[data-for='{$this->Name}']\")";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,142 +7,154 @@
|
|||||||
* @package userforms
|
* @package userforms
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class EditableLiteralField extends EditableFormField {
|
class EditableLiteralField extends EditableFormField
|
||||||
|
{
|
||||||
|
|
||||||
private static $singular_name = 'HTML Block';
|
private static $singular_name = 'HTML Block';
|
||||||
|
|
||||||
private static $plural_name = 'HTML Blocks';
|
private static $plural_name = 'HTML Blocks';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mark as literal only
|
* Mark as literal only
|
||||||
*
|
*
|
||||||
* @config
|
* @config
|
||||||
* @var bool
|
* @var bool
|
||||||
*/
|
*/
|
||||||
private static $literal = true;
|
private static $literal = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the name of the editor config to use for HTML sanitisation. Defaults to the active config.
|
* Get the name of the editor config to use for HTML sanitisation. Defaults to the active config.
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
* @config
|
* @config
|
||||||
*/
|
*/
|
||||||
private static $editor_config = null;
|
private static $editor_config = null;
|
||||||
|
|
||||||
private static $db = array(
|
private static $db = array(
|
||||||
'Content' => 'HTMLText', // From CustomSettings
|
'Content' => 'HTMLText', // From CustomSettings
|
||||||
'HideFromReports' => 'Boolean(0)', // from CustomSettings
|
'HideFromReports' => 'Boolean(0)', // from CustomSettings
|
||||||
'HideLabel' => 'Boolean(0)'
|
'HideLabel' => 'Boolean(0)'
|
||||||
);
|
);
|
||||||
|
|
||||||
private static $defaults = array(
|
private static $defaults = array(
|
||||||
'HideFromReports' => false
|
'HideFromReports' => false
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the {@see HtmlEditorConfig} instance to use for sanitisation
|
* Returns the {@see HtmlEditorConfig} instance to use for sanitisation
|
||||||
*
|
*
|
||||||
* @return HtmlEditorConfig
|
* @return HtmlEditorConfig
|
||||||
*/
|
*/
|
||||||
protected function getEditorConfig() {
|
protected function getEditorConfig()
|
||||||
$editorConfig = $this->config()->editor_config;
|
{
|
||||||
if($editorConfig) return HtmlEditorConfig::get($editorConfig);
|
$editorConfig = $this->config()->editor_config;
|
||||||
return HtmlEditorConfig::get_active();
|
if ($editorConfig) {
|
||||||
}
|
return HtmlEditorConfig::get($editorConfig);
|
||||||
|
}
|
||||||
|
return HtmlEditorConfig::get_active();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Safely sanitise html content, if enabled
|
* Safely sanitise html content, if enabled
|
||||||
*
|
*
|
||||||
* @param string $content Raw html
|
* @param string $content Raw html
|
||||||
* @return string Safely sanitised html
|
* @return string Safely sanitised html
|
||||||
*/
|
*/
|
||||||
protected function sanitiseContent($content) {
|
protected function sanitiseContent($content)
|
||||||
// Check if sanitisation is enabled
|
{
|
||||||
if(!HtmlEditorField::config()->sanitise_server_side) return $content;
|
// Check if sanitisation is enabled
|
||||||
|
if (!HtmlEditorField::config()->sanitise_server_side) {
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
|
|
||||||
// Perform sanitisation
|
// Perform sanitisation
|
||||||
$htmlValue = Injector::inst()->create('HTMLValue', $content);
|
$htmlValue = Injector::inst()->create('HTMLValue', $content);
|
||||||
$santiser = Injector::inst()->create('HtmlEditorSanitiser', $this->getEditorConfig());
|
$santiser = Injector::inst()->create('HtmlEditorSanitiser', $this->getEditorConfig());
|
||||||
$santiser->sanitise($htmlValue);
|
$santiser->sanitise($htmlValue);
|
||||||
return $htmlValue->getContent();
|
return $htmlValue->getContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get HTML Content of this literal field
|
* Get HTML Content of this literal field
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getContent() {
|
public function getContent()
|
||||||
// Apply html editor sanitisation rules
|
{
|
||||||
$content = $this->getField('Content');
|
// Apply html editor sanitisation rules
|
||||||
return $this->sanitiseContent($content);
|
$content = $this->getField('Content');
|
||||||
}
|
return $this->sanitiseContent($content);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the content with the given value
|
* Set the content with the given value
|
||||||
*
|
*
|
||||||
* @param string $content
|
* @param string $content
|
||||||
*/
|
*/
|
||||||
public function setContent($content) {
|
public function setContent($content)
|
||||||
// Apply html editor sanitisation rules
|
{
|
||||||
$content = $this->sanitiseContent($content);
|
// Apply html editor sanitisation rules
|
||||||
$this->setField('Content', $content);
|
$content = $this->sanitiseContent($content);
|
||||||
}
|
$this->setField('Content', $content);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return FieldList
|
* @return FieldList
|
||||||
*/
|
*/
|
||||||
public function getCMSFields() {
|
public function getCMSFields()
|
||||||
$fields = parent::getCMSFields();
|
{
|
||||||
|
$fields = parent::getCMSFields();
|
||||||
|
|
||||||
$fields->removeByName(array('Default', 'Validation', 'RightTitle'));
|
$fields->removeByName(array('Default', 'Validation', 'RightTitle'));
|
||||||
|
|
||||||
$fields->addFieldsToTab('Root.Main', array(
|
$fields->addFieldsToTab('Root.Main', array(
|
||||||
HTMLEditorField::create('Content', _t('EditableLiteralField.CONTENT', 'HTML'))
|
HTMLEditorField::create('Content', _t('EditableLiteralField.CONTENT', 'HTML'))
|
||||||
->setRows(4)
|
->setRows(4)
|
||||||
->setColumns(20),
|
->setColumns(20),
|
||||||
CheckboxField::create(
|
CheckboxField::create(
|
||||||
'HideFromReports',
|
'HideFromReports',
|
||||||
_t('EditableLiteralField.HIDEFROMREPORT', 'Hide from reports?')
|
_t('EditableLiteralField.HIDEFROMREPORT', 'Hide from reports?')
|
||||||
),
|
),
|
||||||
CheckboxField::create(
|
CheckboxField::create(
|
||||||
'HideLabel',
|
'HideLabel',
|
||||||
_t('EditableLiteralField.HIDELABEL', "Hide 'Title' label on frontend?")
|
_t('EditableLiteralField.HIDELABEL', "Hide 'Title' label on frontend?")
|
||||||
)
|
)
|
||||||
));
|
));
|
||||||
|
|
||||||
return $fields;
|
return $fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getFormField() {
|
public function getFormField()
|
||||||
// Build label and css classes
|
{
|
||||||
$label = '';
|
// Build label and css classes
|
||||||
$classes = $this->ExtraClass;
|
$label = '';
|
||||||
if(empty($this->Title) || $this->HideLabel) {
|
$classes = $this->ExtraClass;
|
||||||
$classes .= " nolabel";
|
if (empty($this->Title) || $this->HideLabel) {
|
||||||
} else {
|
$classes .= " nolabel";
|
||||||
$label = "<label class='left'>{$this->EscapedTitle}</label>";
|
} else {
|
||||||
}
|
$label = "<label class='left'>{$this->EscapedTitle}</label>";
|
||||||
|
}
|
||||||
|
|
||||||
$field = new LiteralField(
|
$field = new LiteralField(
|
||||||
"LiteralField[{$this->ID}]",
|
"LiteralField[{$this->ID}]",
|
||||||
sprintf(
|
sprintf(
|
||||||
"<div id='%s' class='field text %s'>
|
"<div id='%s' class='field text %s'>
|
||||||
%s
|
%s
|
||||||
<div class='middleColumn literalFieldArea'>%s</div>".
|
<div class='middleColumn literalFieldArea'>%s</div>".
|
||||||
"</div>",
|
"</div>",
|
||||||
Convert::raw2htmlname($this->Name),
|
Convert::raw2htmlname($this->Name),
|
||||||
Convert::raw2att($classes),
|
Convert::raw2att($classes),
|
||||||
$label,
|
$label,
|
||||||
$this->Content
|
$this->Content
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
// When dealing with literal fields there is no further customisation that can be added at this point
|
// When dealing with literal fields there is no further customisation that can be added at this point
|
||||||
return $field;
|
return $field;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function showInReports() {
|
public function showInReports()
|
||||||
return ! $this->HideFromReports;
|
{
|
||||||
}
|
return ! $this->HideFromReports;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,55 +5,59 @@
|
|||||||
* @package userforms
|
* @package userforms
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class EditableMemberListField extends EditableFormField {
|
class EditableMemberListField extends EditableFormField
|
||||||
|
{
|
||||||
|
|
||||||
private static $singular_name = 'Member List Field';
|
private static $singular_name = 'Member List Field';
|
||||||
|
|
||||||
private static $plural_name = 'Member List Fields';
|
private static $plural_name = 'Member List Fields';
|
||||||
|
|
||||||
private static $has_one = array(
|
private static $has_one = array(
|
||||||
'Group' => 'Group'
|
'Group' => 'Group'
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return FieldList
|
* @return FieldList
|
||||||
*/
|
*/
|
||||||
public function getCMSFields() {
|
public function getCMSFields()
|
||||||
$fields = parent::getCMSFields();
|
{
|
||||||
|
$fields = parent::getCMSFields();
|
||||||
|
|
||||||
$fields->removeByName('Default');
|
$fields->removeByName('Default');
|
||||||
$fields->removeByName('Validation');
|
$fields->removeByName('Validation');
|
||||||
|
|
||||||
$fields->addFieldToTab(
|
$fields->addFieldToTab(
|
||||||
'Root.Main',
|
'Root.Main',
|
||||||
DropdownField::create(
|
DropdownField::create(
|
||||||
"GroupID",
|
"GroupID",
|
||||||
_t('EditableFormField.GROUP', 'Group'),
|
_t('EditableFormField.GROUP', 'Group'),
|
||||||
Group::get()->map()
|
Group::get()->map()
|
||||||
)->setEmptyString(' ')
|
)->setEmptyString(' ')
|
||||||
);
|
);
|
||||||
|
|
||||||
return $fields;
|
return $fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getFormField() {
|
public function getFormField()
|
||||||
if(empty($this->GroupID)) {
|
{
|
||||||
return false;
|
if (empty($this->GroupID)) {
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
$members = Member::map_in_groups($this->GroupID);
|
$members = Member::map_in_groups($this->GroupID);
|
||||||
$field = new DropdownField($this->Name, $this->EscapedTitle, $members);
|
$field = new DropdownField($this->Name, $this->EscapedTitle, $members);
|
||||||
$this->doUpdateFormField($field);
|
$this->doUpdateFormField($field);
|
||||||
return $field;
|
return $field;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getValueFromData($data) {
|
public function getValueFromData($data)
|
||||||
if(isset($data[$this->Name])) {
|
{
|
||||||
$memberID = $data[$this->Name];
|
if (isset($data[$this->Name])) {
|
||||||
$member = Member::get()->byID($memberID);
|
$memberID = $data[$this->Name];
|
||||||
return $member ? $member->getName() : "";
|
$member = Member::get()->byID($memberID);
|
||||||
}
|
return $member ? $member->getName() : "";
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,183 +13,192 @@
|
|||||||
* @package userforms
|
* @package userforms
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class EditableMultipleOptionField extends EditableFormField {
|
class EditableMultipleOptionField extends EditableFormField
|
||||||
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define this field as abstract (not inherited)
|
* Define this field as abstract (not inherited)
|
||||||
*
|
*
|
||||||
* @config
|
* @config
|
||||||
* @var bool
|
* @var bool
|
||||||
*/
|
*/
|
||||||
private static $abstract = true;
|
private static $abstract = true;
|
||||||
|
|
||||||
private static $has_many = array(
|
private static $has_many = array(
|
||||||
"Options" => "EditableOption"
|
"Options" => "EditableOption"
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return FieldList
|
* @return FieldList
|
||||||
*/
|
*/
|
||||||
public function getCMSFields() {
|
public function getCMSFields()
|
||||||
$fields = parent::getCMSFields();
|
{
|
||||||
|
$fields = parent::getCMSFields();
|
||||||
|
|
||||||
$editableColumns = new GridFieldEditableColumns();
|
$editableColumns = new GridFieldEditableColumns();
|
||||||
$editableColumns->setDisplayFields(array(
|
$editableColumns->setDisplayFields(array(
|
||||||
'Title' => array(
|
'Title' => array(
|
||||||
'title' => _t('EditableMultipleOptionField.TITLE', 'Title'),
|
'title' => _t('EditableMultipleOptionField.TITLE', 'Title'),
|
||||||
'callback' => function($record, $column, $grid) {
|
'callback' => function ($record, $column, $grid) {
|
||||||
return TextField::create($column);
|
|
||||||
}
|
|
||||||
),
|
|
||||||
'Value' => array(
|
|
||||||
'title' => _t('EditableMultipleOptionField.VALUE', 'Value'),
|
|
||||||
'callback' => function($record, $column, $grid) {
|
|
||||||
return TextField::create($column);
|
return TextField::create($column);
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
'Default' => array(
|
'Value' => array(
|
||||||
'title' => _t('EditableMultipleOptionField.DEFAULT', 'Selected by default?'),
|
'title' => _t('EditableMultipleOptionField.VALUE', 'Value'),
|
||||||
'callback' => function($record, $column, $grid) {
|
'callback' => function ($record, $column, $grid) {
|
||||||
return CheckboxField::create($column);
|
return TextField::create($column);
|
||||||
}
|
}
|
||||||
)
|
),
|
||||||
));
|
'Default' => array(
|
||||||
|
'title' => _t('EditableMultipleOptionField.DEFAULT', 'Selected by default?'),
|
||||||
|
'callback' => function ($record, $column, $grid) {
|
||||||
|
return CheckboxField::create($column);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
));
|
||||||
|
|
||||||
$optionsConfig = GridFieldConfig::create()
|
$optionsConfig = GridFieldConfig::create()
|
||||||
->addComponents(
|
->addComponents(
|
||||||
new GridFieldToolbarHeader(),
|
new GridFieldToolbarHeader(),
|
||||||
new GridFieldTitleHeader(),
|
new GridFieldTitleHeader(),
|
||||||
new GridFieldOrderableRows('Sort'),
|
new GridFieldOrderableRows('Sort'),
|
||||||
$editableColumns,
|
$editableColumns,
|
||||||
new GridFieldButtonRow(),
|
new GridFieldButtonRow(),
|
||||||
new GridFieldAddNewInlineButton(),
|
new GridFieldAddNewInlineButton(),
|
||||||
new GridFieldDeleteAction()
|
new GridFieldDeleteAction()
|
||||||
);
|
);
|
||||||
|
|
||||||
$optionsGrid = GridField::create(
|
$optionsGrid = GridField::create(
|
||||||
'Options',
|
'Options',
|
||||||
_t('EditableFormField.CUSTOMOPTIONS', 'Options'),
|
_t('EditableFormField.CUSTOMOPTIONS', 'Options'),
|
||||||
$this->Options(),
|
$this->Options(),
|
||||||
$optionsConfig
|
$optionsConfig
|
||||||
);
|
);
|
||||||
|
|
||||||
$fields->insertAfter(new Tab('Options', _t('EditableMultipleOptionField.OPTIONSTAB','Options')), 'Main');
|
$fields->insertAfter(new Tab('Options', _t('EditableMultipleOptionField.OPTIONSTAB', 'Options')), 'Main');
|
||||||
$fields->addFieldToTab('Root.Options', $optionsGrid);
|
$fields->addFieldToTab('Root.Options', $optionsGrid);
|
||||||
|
|
||||||
return $fields;
|
return $fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Publishing Versioning support.
|
* Publishing Versioning support.
|
||||||
*
|
*
|
||||||
* When publishing it needs to handle copying across / publishing
|
* When publishing it needs to handle copying across / publishing
|
||||||
* each of the individual field options
|
* each of the individual field options
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function doPublish($fromStage, $toStage, $createNewVersion = false) {
|
public function doPublish($fromStage, $toStage, $createNewVersion = false)
|
||||||
$live = Versioned::get_by_stage("EditableOption", "Live", "\"EditableOption\".\"ParentID\" = $this->ID");
|
{
|
||||||
|
$live = Versioned::get_by_stage("EditableOption", "Live", "\"EditableOption\".\"ParentID\" = $this->ID");
|
||||||
|
|
||||||
if($live) {
|
if ($live) {
|
||||||
foreach($live as $option) {
|
foreach ($live as $option) {
|
||||||
$option->delete();
|
$option->delete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if($this->Options()) {
|
if ($this->Options()) {
|
||||||
foreach($this->Options() as $option) {
|
foreach ($this->Options() as $option) {
|
||||||
$option->publish($fromStage, $toStage, $createNewVersion);
|
$option->publish($fromStage, $toStage, $createNewVersion);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parent::doPublish($fromStage, $toStage, $createNewVersion);
|
parent::doPublish($fromStage, $toStage, $createNewVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unpublishing Versioning support
|
* Unpublishing Versioning support
|
||||||
*
|
*
|
||||||
* When unpublishing the field it has to remove all options attached
|
* When unpublishing the field it has to remove all options attached
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function doDeleteFromStage($stage) {
|
public function doDeleteFromStage($stage)
|
||||||
// Remove options
|
{
|
||||||
$options = Versioned::get_by_stage('EditableOption', $stage)
|
// Remove options
|
||||||
->filter('ParentID', $this->ID);
|
$options = Versioned::get_by_stage('EditableOption', $stage)
|
||||||
foreach($options as $option) {
|
->filter('ParentID', $this->ID);
|
||||||
$option->deleteFromStage($stage);
|
foreach ($options as $option) {
|
||||||
}
|
$option->deleteFromStage($stage);
|
||||||
|
}
|
||||||
|
|
||||||
parent::doDeleteFromStage($stage);
|
parent::doDeleteFromStage($stage);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes all the options attached to this field before deleting the
|
* Deletes all the options attached to this field before deleting the
|
||||||
* field. Keeps stray options from floating around
|
* field. Keeps stray options from floating around
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function delete() {
|
public function delete()
|
||||||
$options = $this->Options();
|
{
|
||||||
|
$options = $this->Options();
|
||||||
|
|
||||||
if($options) {
|
if ($options) {
|
||||||
foreach($options as $option) {
|
foreach ($options as $option) {
|
||||||
$option->delete();
|
$option->delete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parent::delete();
|
parent::delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Duplicate a pages content. We need to make sure all the fields attached
|
* Duplicate a pages content. We need to make sure all the fields attached
|
||||||
* to that page go with it
|
* to that page go with it
|
||||||
*
|
*
|
||||||
* @return DataObject
|
* @return DataObject
|
||||||
*/
|
*/
|
||||||
public function duplicate($doWrite = true) {
|
public function duplicate($doWrite = true)
|
||||||
$clonedNode = parent::duplicate();
|
{
|
||||||
|
$clonedNode = parent::duplicate();
|
||||||
|
|
||||||
foreach($this->Options() as $field) {
|
foreach ($this->Options() as $field) {
|
||||||
$newField = $field->duplicate(false);
|
$newField = $field->duplicate(false);
|
||||||
$newField->ParentID = $clonedNode->ID;
|
$newField->ParentID = $clonedNode->ID;
|
||||||
$newField->Version = 0;
|
$newField->Version = 0;
|
||||||
$newField->write();
|
$newField->write();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $clonedNode;
|
return $clonedNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return whether or not this field has addable options such as a
|
* Return whether or not this field has addable options such as a
|
||||||
* {@link EditableDropdownField} or {@link EditableRadioField}
|
* {@link EditableDropdownField} or {@link EditableRadioField}
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function getHasAddableOptions() {
|
public function getHasAddableOptions()
|
||||||
return true;
|
{
|
||||||
}
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets map of field options suitable for use in a form
|
* Gets map of field options suitable for use in a form
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
protected function getOptionsMap() {
|
protected function getOptionsMap()
|
||||||
$optionSet = $this->Options();
|
{
|
||||||
$optionMap = $optionSet->map('Value', 'Title');
|
$optionSet = $this->Options();
|
||||||
if($optionMap instanceof SS_Map) {
|
$optionMap = $optionSet->map('Value', 'Title');
|
||||||
return $optionMap->toArray();
|
if ($optionMap instanceof SS_Map) {
|
||||||
}
|
return $optionMap->toArray();
|
||||||
return $optionMap;
|
}
|
||||||
}
|
return $optionMap;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all default options
|
* Returns all default options
|
||||||
*
|
*
|
||||||
* @return SS_List
|
* @return SS_List
|
||||||
*/
|
*/
|
||||||
protected function getDefaultOptions() {
|
protected function getDefaultOptions()
|
||||||
return $this->Options()->filter('Default', 1);
|
{
|
||||||
}
|
return $this->Options()->filter('Default', 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,81 +7,87 @@
|
|||||||
* @package userforms
|
* @package userforms
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class EditableNumericField extends EditableFormField {
|
class EditableNumericField extends EditableFormField
|
||||||
|
{
|
||||||
|
|
||||||
private static $singular_name = 'Numeric Field';
|
private static $singular_name = 'Numeric Field';
|
||||||
|
|
||||||
private static $plural_name = 'Numeric Fields';
|
private static $plural_name = 'Numeric Fields';
|
||||||
|
|
||||||
private static $db = array(
|
private static $db = array(
|
||||||
'MinValue' => 'Int',
|
'MinValue' => 'Int',
|
||||||
'MaxValue' => 'Int',
|
'MaxValue' => 'Int',
|
||||||
'Placeholder' => 'Varchar(255)'
|
'Placeholder' => 'Varchar(255)'
|
||||||
);
|
);
|
||||||
|
|
||||||
public function getSetsOwnError() {
|
public function getSetsOwnError()
|
||||||
return true;
|
{
|
||||||
}
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public function getCMSFields() {
|
public function getCMSFields()
|
||||||
$this->beforeUpdateCMSFields(function($fields) {
|
{
|
||||||
$fields->addFieldToTab(
|
$this->beforeUpdateCMSFields(function ($fields) {
|
||||||
'Root.Main',
|
$fields->addFieldToTab(
|
||||||
TextField::create(
|
'Root.Main',
|
||||||
'Placeholder',
|
TextField::create(
|
||||||
_t('EditableTextField.PLACEHOLDER', 'Placeholder')
|
'Placeholder',
|
||||||
)
|
_t('EditableTextField.PLACEHOLDER', 'Placeholder')
|
||||||
);
|
)
|
||||||
});
|
);
|
||||||
|
});
|
||||||
|
|
||||||
return parent::getCMSFields();
|
return parent::getCMSFields();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return NumericField
|
* @return NumericField
|
||||||
*/
|
*/
|
||||||
public function getFormField() {
|
public function getFormField()
|
||||||
$field = NumericField::create($this->Name, $this->EscapedTitle, $this->Default)
|
{
|
||||||
->setFieldHolderTemplate('UserFormsField_holder')
|
$field = NumericField::create($this->Name, $this->EscapedTitle, $this->Default)
|
||||||
->setTemplate('UserFormsField')
|
->setFieldHolderTemplate('UserFormsField_holder')
|
||||||
->addExtraClass('number');
|
->setTemplate('UserFormsField')
|
||||||
|
->addExtraClass('number');
|
||||||
|
|
||||||
$this->doUpdateFormField($field);
|
$this->doUpdateFormField($field);
|
||||||
|
|
||||||
return $field;
|
return $field;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getFieldValidationOptions() {
|
public function getFieldValidationOptions()
|
||||||
$fields = parent::getFieldValidationOptions();
|
{
|
||||||
$fields->push(FieldGroup::create(
|
$fields = parent::getFieldValidationOptions();
|
||||||
_t("EditableNumericField.RANGE", "Allowed numeric range"),
|
$fields->push(FieldGroup::create(
|
||||||
array(
|
_t("EditableNumericField.RANGE", "Allowed numeric range"),
|
||||||
new NumericField('MinValue', false),
|
array(
|
||||||
new LiteralField('RangeValue', _t("EditableNumericField.RANGE_TO", "to")),
|
new NumericField('MinValue', false),
|
||||||
new NumericField('MaxValue', false)
|
new LiteralField('RangeValue', _t("EditableNumericField.RANGE_TO", "to")),
|
||||||
)
|
new NumericField('MaxValue', false)
|
||||||
));
|
)
|
||||||
return $fields;
|
));
|
||||||
}
|
return $fields;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates a formfield with the additional metadata specified by this field
|
* Updates a formfield with the additional metadata specified by this field
|
||||||
*
|
*
|
||||||
* @param FormField $field
|
* @param FormField $field
|
||||||
*/
|
*/
|
||||||
protected function updateFormField($field) {
|
protected function updateFormField($field)
|
||||||
parent::updateFormField($field);
|
{
|
||||||
|
parent::updateFormField($field);
|
||||||
|
|
||||||
if($this->MinValue) {
|
if ($this->MinValue) {
|
||||||
$field->setAttribute('data-rule-min', $this->MinValue);
|
$field->setAttribute('data-rule-min', $this->MinValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
if($this->MaxValue) {
|
if ($this->MaxValue) {
|
||||||
$field->setAttribute('data-rule-max', $this->MaxValue);
|
$field->setAttribute('data-rule-max', $this->MaxValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
if($this->Placeholder) {
|
if ($this->Placeholder) {
|
||||||
$field->setAttribute('placeholder', $this->Placeholder);
|
$field->setAttribute('placeholder', $this->Placeholder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,30 +7,31 @@
|
|||||||
* @method EditableMultipleOptionField Parent()
|
* @method EditableMultipleOptionField Parent()
|
||||||
* @package userforms
|
* @package userforms
|
||||||
*/
|
*/
|
||||||
class EditableOption extends DataObject {
|
class EditableOption extends DataObject
|
||||||
|
{
|
||||||
|
|
||||||
private static $default_sort = "Sort";
|
private static $default_sort = "Sort";
|
||||||
|
|
||||||
private static $db = array(
|
private static $db = array(
|
||||||
"Name" => "Varchar(255)",
|
"Name" => "Varchar(255)",
|
||||||
"Title" => "Varchar(255)",
|
"Title" => "Varchar(255)",
|
||||||
"Default" => "Boolean",
|
"Default" => "Boolean",
|
||||||
"Sort" => "Int",
|
"Sort" => "Int",
|
||||||
"Value" => "Varchar(255)",
|
"Value" => "Varchar(255)",
|
||||||
);
|
);
|
||||||
|
|
||||||
private static $has_one = array(
|
private static $has_one = array(
|
||||||
"Parent" => "EditableMultipleOptionField",
|
"Parent" => "EditableMultipleOptionField",
|
||||||
);
|
);
|
||||||
|
|
||||||
private static $extensions = array(
|
private static $extensions = array(
|
||||||
"Versioned('Stage', 'Live')"
|
"Versioned('Stage', 'Live')"
|
||||||
);
|
);
|
||||||
|
|
||||||
private static $summary_fields = array(
|
private static $summary_fields = array(
|
||||||
'Title',
|
'Title',
|
||||||
'Default'
|
'Default'
|
||||||
);
|
);
|
||||||
|
|
||||||
protected static $allow_empty_values = false;
|
protected static $allow_empty_values = false;
|
||||||
|
|
||||||
@ -39,7 +40,8 @@ class EditableOption extends DataObject {
|
|||||||
*
|
*
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public static function allow_empty_values() {
|
public static function allow_empty_values()
|
||||||
|
{
|
||||||
return (bool) self::$allow_empty_values;
|
return (bool) self::$allow_empty_values;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,57 +50,63 @@ class EditableOption extends DataObject {
|
|||||||
*
|
*
|
||||||
* @param boolean $allow
|
* @param boolean $allow
|
||||||
*/
|
*/
|
||||||
public static function set_allow_empty_values($allow) {
|
public static function set_allow_empty_values($allow)
|
||||||
|
{
|
||||||
self::$allow_empty_values = (bool) $allow;
|
self::$allow_empty_values = (bool) $allow;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Member $member
|
* @param Member $member
|
||||||
*
|
*
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function canEdit($member = null) {
|
public function canEdit($member = null)
|
||||||
return $this->Parent()->canEdit($member);
|
{
|
||||||
}
|
return $this->Parent()->canEdit($member);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Member $member
|
* @param Member $member
|
||||||
*
|
*
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function canDelete($member = null) {
|
public function canDelete($member = null)
|
||||||
return $this->canEdit($member);
|
{
|
||||||
}
|
return $this->canEdit($member);
|
||||||
|
}
|
||||||
|
|
||||||
public function getEscapedTitle() {
|
public function getEscapedTitle()
|
||||||
return Convert::raw2att($this->Title);
|
{
|
||||||
}
|
return Convert::raw2att($this->Title);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Member $member
|
* @param Member $member
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function canView($member = null) {
|
public function canView($member = null)
|
||||||
return $this->Parent()->canView($member);
|
{
|
||||||
}
|
return $this->Parent()->canView($member);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return whether a user can create an object of this type
|
* Return whether a user can create an object of this type
|
||||||
*
|
*
|
||||||
* @param Member $member
|
* @param Member $member
|
||||||
* @param array $context Virtual parameter to allow context to be passed in to check
|
* @param array $context Virtual parameter to allow context to be passed in to check
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function canCreate($member = null) {
|
public function canCreate($member = null)
|
||||||
// Check parent page
|
{
|
||||||
|
// Check parent page
|
||||||
$parent = $this->getCanCreateContext(func_get_args());
|
$parent = $this->getCanCreateContext(func_get_args());
|
||||||
if($parent) {
|
if ($parent) {
|
||||||
return $parent->canEdit($member);
|
return $parent->canEdit($member);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fall back to secure admin permissions
|
// Fall back to secure admin permissions
|
||||||
return parent::canCreate($member);
|
return parent::canCreate($member);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to check the parent for this object
|
* Helper method to check the parent for this object
|
||||||
@ -106,13 +114,14 @@ class EditableOption extends DataObject {
|
|||||||
* @param array $args List of arguments passed to canCreate
|
* @param array $args List of arguments passed to canCreate
|
||||||
* @return DataObject Some parent dataobject to inherit permissions from
|
* @return DataObject Some parent dataobject to inherit permissions from
|
||||||
*/
|
*/
|
||||||
protected function getCanCreateContext($args) {
|
protected function getCanCreateContext($args)
|
||||||
|
{
|
||||||
// Inspect second parameter to canCreate for a 'Parent' context
|
// Inspect second parameter to canCreate for a 'Parent' context
|
||||||
if(isset($args[1]['Parent'])) {
|
if (isset($args[1]['Parent'])) {
|
||||||
return $args[1]['Parent'];
|
return $args[1]['Parent'];
|
||||||
}
|
}
|
||||||
// Hack in currently edited page if context is missing
|
// Hack in currently edited page if context is missing
|
||||||
if(Controller::has_curr() && Controller::curr() instanceof CMSMain) {
|
if (Controller::has_curr() && Controller::curr() instanceof CMSMain) {
|
||||||
return Controller::curr()->currentPage();
|
return Controller::curr()->currentPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,7 +133,8 @@ class EditableOption extends DataObject {
|
|||||||
* @param Member $member
|
* @param Member $member
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function canPublish($member = null) {
|
public function canPublish($member = null)
|
||||||
|
{
|
||||||
return $this->canEdit($member);
|
return $this->canEdit($member);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,7 +142,8 @@ class EditableOption extends DataObject {
|
|||||||
* @param Member $member
|
* @param Member $member
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function canUnpublish($member = null) {
|
public function canUnpublish($member = null)
|
||||||
|
{
|
||||||
return $this->canDelete($member);
|
return $this->canDelete($member);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,7 +156,7 @@ class EditableOption extends DataObject {
|
|||||||
public function getValue()
|
public function getValue()
|
||||||
{
|
{
|
||||||
$value = $this->getField('Value');
|
$value = $this->getField('Value');
|
||||||
if(empty($value) && !self::allow_empty_values()) {
|
if (empty($value) && !self::allow_empty_values()) {
|
||||||
return $this->Title;
|
return $this->Title;
|
||||||
}
|
}
|
||||||
return $value;
|
return $value;
|
||||||
|
@ -7,39 +7,43 @@
|
|||||||
* @package userforms
|
* @package userforms
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class EditableRadioField extends EditableMultipleOptionField {
|
class EditableRadioField extends EditableMultipleOptionField
|
||||||
|
{
|
||||||
|
|
||||||
private static $singular_name = 'Radio Group';
|
private static $singular_name = 'Radio Group';
|
||||||
|
|
||||||
private static $plural_name = 'Radio Groups';
|
private static $plural_name = 'Radio Groups';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return FieldList
|
* @return FieldList
|
||||||
*/
|
*/
|
||||||
public function getCMSFields() {
|
public function getCMSFields()
|
||||||
$fields = parent::getCMSFields();
|
{
|
||||||
|
$fields = parent::getCMSFields();
|
||||||
|
|
||||||
$fields->removeByName('Default');
|
$fields->removeByName('Default');
|
||||||
|
|
||||||
return $fields;
|
return $fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getFormField() {
|
public function getFormField()
|
||||||
$field = OptionsetField::create($this->Name, $this->EscapedTitle, $this->getOptionsMap());
|
{
|
||||||
$field->setFieldHolderTemplate('UserFormsMultipleOptionField_holder');
|
$field = OptionsetField::create($this->Name, $this->EscapedTitle, $this->getOptionsMap());
|
||||||
|
$field->setFieldHolderTemplate('UserFormsMultipleOptionField_holder');
|
||||||
|
|
||||||
// Set default item
|
// Set default item
|
||||||
$defaultOption = $this->getDefaultOptions()->first();
|
$defaultOption = $this->getDefaultOptions()->first();
|
||||||
if($defaultOption) {
|
if ($defaultOption) {
|
||||||
$field->setValue($defaultOption->EscapedTitle);
|
$field->setValue($defaultOption->EscapedTitle);
|
||||||
}
|
}
|
||||||
$this->doUpdateFormField($field);
|
$this->doUpdateFormField($field);
|
||||||
return $field;
|
return $field;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSelectorField(EditableCustomRule $rule, $forOnLoad = false) {
|
public function getSelectorField(EditableCustomRule $rule, $forOnLoad = false)
|
||||||
// We only want to trigger on load once for the radio group - hence we focus on the first option only.
|
{
|
||||||
$first = $forOnLoad ? ':first' : '';
|
// We only want to trigger on load once for the radio group - hence we focus on the first option only.
|
||||||
return "$(\"input[name='{$this->Name}']{$first}\")";
|
$first = $forOnLoad ? ':first' : '';
|
||||||
}
|
return "$(\"input[name='{$this->Name}']{$first}\")";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,109 +7,114 @@
|
|||||||
* @package userforms
|
* @package userforms
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class EditableTextField extends EditableFormField {
|
class EditableTextField extends EditableFormField
|
||||||
|
{
|
||||||
|
|
||||||
private static $singular_name = 'Text Field';
|
private static $singular_name = 'Text Field';
|
||||||
|
|
||||||
private static $plural_name = 'Text Fields';
|
private static $plural_name = 'Text Fields';
|
||||||
|
|
||||||
private static $db = array(
|
private static $db = array(
|
||||||
'MinLength' => 'Int',
|
'MinLength' => 'Int',
|
||||||
'MaxLength' => 'Int',
|
'MaxLength' => 'Int',
|
||||||
'Rows' => 'Int(1)',
|
'Rows' => 'Int(1)',
|
||||||
'Placeholder' => 'Varchar(255)'
|
'Placeholder' => 'Varchar(255)'
|
||||||
);
|
);
|
||||||
|
|
||||||
private static $defaults = array(
|
private static $defaults = array(
|
||||||
'Rows' => 1
|
'Rows' => 1
|
||||||
);
|
);
|
||||||
|
|
||||||
public function getCMSFields() {
|
public function getCMSFields()
|
||||||
$this->beforeUpdateCMSFields(function($fields) {
|
{
|
||||||
$fields->addFieldToTab(
|
$this->beforeUpdateCMSFields(function ($fields) {
|
||||||
'Root.Main',
|
$fields->addFieldToTab(
|
||||||
NumericField::create(
|
'Root.Main',
|
||||||
'Rows',
|
NumericField::create(
|
||||||
_t('EditableTextField.NUMBERROWS', 'Number of rows')
|
'Rows',
|
||||||
)->setDescription(_t(
|
_t('EditableTextField.NUMBERROWS', 'Number of rows')
|
||||||
'EditableTextField.NUMBERROWS_DESCRIPTION',
|
)->setDescription(_t(
|
||||||
'Fields with more than one row will be generated as a textarea'
|
'EditableTextField.NUMBERROWS_DESCRIPTION',
|
||||||
))
|
'Fields with more than one row will be generated as a textarea'
|
||||||
);
|
))
|
||||||
|
);
|
||||||
|
|
||||||
$fields->addFieldToTab(
|
$fields->addFieldToTab(
|
||||||
'Root.Main',
|
'Root.Main',
|
||||||
TextField::create(
|
TextField::create(
|
||||||
'Placeholder',
|
'Placeholder',
|
||||||
_t('EditableTextField.PLACEHOLDER', 'Placeholder')
|
_t('EditableTextField.PLACEHOLDER', 'Placeholder')
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
return parent::getCMSFields();
|
return parent::getCMSFields();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return FieldList
|
* @return FieldList
|
||||||
*/
|
*/
|
||||||
public function getFieldValidationOptions() {
|
public function getFieldValidationOptions()
|
||||||
$fields = parent::getFieldValidationOptions();
|
{
|
||||||
|
$fields = parent::getFieldValidationOptions();
|
||||||
|
|
||||||
$fields->merge(array(
|
$fields->merge(array(
|
||||||
FieldGroup::create(
|
FieldGroup::create(
|
||||||
_t('EditableTextField.TEXTLENGTH', 'Allowed text length'),
|
_t('EditableTextField.TEXTLENGTH', 'Allowed text length'),
|
||||||
array(
|
array(
|
||||||
NumericField::create('MinLength', false),
|
NumericField::create('MinLength', false),
|
||||||
LiteralField::create('RangeLength', _t("EditableTextField.RANGE_TO", "to")),
|
LiteralField::create('RangeLength', _t("EditableTextField.RANGE_TO", "to")),
|
||||||
NumericField::create('MaxLength', false)
|
NumericField::create('MaxLength', false)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
));
|
));
|
||||||
|
|
||||||
return $fields;
|
return $fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return TextareaField|TextField
|
* @return TextareaField|TextField
|
||||||
*/
|
*/
|
||||||
public function getFormField() {
|
public function getFormField()
|
||||||
if($this->Rows > 1) {
|
{
|
||||||
$field = TextareaField::create($this->Name, $this->EscapedTitle, $this->Default)
|
if ($this->Rows > 1) {
|
||||||
->setFieldHolderTemplate('UserFormsField_holder')
|
$field = TextareaField::create($this->Name, $this->EscapedTitle, $this->Default)
|
||||||
->setTemplate('UserFormsTextareaField')
|
->setFieldHolderTemplate('UserFormsField_holder')
|
||||||
->setRows($this->Rows);
|
->setTemplate('UserFormsTextareaField')
|
||||||
} else {
|
->setRows($this->Rows);
|
||||||
$field = TextField::create($this->Name, $this->EscapedTitle, $this->Default)
|
} else {
|
||||||
->setFieldHolderTemplate('UserFormsField_holder')
|
$field = TextField::create($this->Name, $this->EscapedTitle, $this->Default)
|
||||||
->setTemplate('UserFormsField');
|
->setFieldHolderTemplate('UserFormsField_holder')
|
||||||
}
|
->setTemplate('UserFormsField');
|
||||||
|
}
|
||||||
|
|
||||||
$this->doUpdateFormField($field);
|
$this->doUpdateFormField($field);
|
||||||
|
|
||||||
return $field;
|
return $field;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates a formfield with the additional metadata specified by this field
|
* Updates a formfield with the additional metadata specified by this field
|
||||||
*
|
*
|
||||||
* @param FormField $field
|
* @param FormField $field
|
||||||
*/
|
*/
|
||||||
protected function updateFormField($field) {
|
protected function updateFormField($field)
|
||||||
parent::updateFormField($field);
|
{
|
||||||
|
parent::updateFormField($field);
|
||||||
|
|
||||||
if(is_numeric($this->MinLength) && $this->MinLength > 0) {
|
if (is_numeric($this->MinLength) && $this->MinLength > 0) {
|
||||||
$field->setAttribute('data-rule-minlength', intval($this->MinLength));
|
$field->setAttribute('data-rule-minlength', intval($this->MinLength));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(is_numeric($this->MaxLength) && $this->MaxLength > 0) {
|
if (is_numeric($this->MaxLength) && $this->MaxLength > 0) {
|
||||||
if($field instanceof TextField) {
|
if ($field instanceof TextField) {
|
||||||
$field->setMaxLength(intval($this->MaxLength));
|
$field->setMaxLength(intval($this->MaxLength));
|
||||||
}
|
}
|
||||||
$field->setAttribute('data-rule-maxlength', intval($this->MaxLength));
|
$field->setAttribute('data-rule-maxlength', intval($this->MaxLength));
|
||||||
}
|
}
|
||||||
|
|
||||||
if($this->Placeholder) {
|
if ($this->Placeholder) {
|
||||||
$field->setAttribute('placeholder', $this->Placeholder);
|
$field->setAttribute('placeholder', $this->Placeholder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,305 +7,312 @@
|
|||||||
*
|
*
|
||||||
* @package userforms
|
* @package userforms
|
||||||
*/
|
*/
|
||||||
class UserDefinedForm_EmailRecipient extends DataObject {
|
class UserDefinedForm_EmailRecipient extends DataObject
|
||||||
|
{
|
||||||
|
|
||||||
private static $db = array(
|
private static $db = array(
|
||||||
'EmailAddress' => 'Varchar(200)',
|
'EmailAddress' => 'Varchar(200)',
|
||||||
'EmailSubject' => 'Varchar(200)',
|
'EmailSubject' => 'Varchar(200)',
|
||||||
'EmailFrom' => 'Varchar(200)',
|
'EmailFrom' => 'Varchar(200)',
|
||||||
'EmailReplyTo' => 'Varchar(200)',
|
'EmailReplyTo' => 'Varchar(200)',
|
||||||
'EmailBody' => 'Text',
|
'EmailBody' => 'Text',
|
||||||
'EmailBodyHtml' => 'HTMLText',
|
'EmailBodyHtml' => 'HTMLText',
|
||||||
'EmailTemplate' => 'Varchar',
|
'EmailTemplate' => 'Varchar',
|
||||||
'SendPlain' => 'Boolean',
|
'SendPlain' => 'Boolean',
|
||||||
'HideFormData' => 'Boolean',
|
'HideFormData' => 'Boolean',
|
||||||
'CustomRulesCondition' => 'Enum("And,Or")'
|
'CustomRulesCondition' => 'Enum("And,Or")'
|
||||||
);
|
);
|
||||||
|
|
||||||
private static $has_one = array(
|
private static $has_one = array(
|
||||||
'Form' => 'UserDefinedForm',
|
'Form' => 'UserDefinedForm',
|
||||||
'SendEmailFromField' => 'EditableFormField',
|
'SendEmailFromField' => 'EditableFormField',
|
||||||
'SendEmailToField' => 'EditableFormField',
|
'SendEmailToField' => 'EditableFormField',
|
||||||
'SendEmailSubjectField' => 'EditableFormField'
|
'SendEmailSubjectField' => 'EditableFormField'
|
||||||
);
|
);
|
||||||
|
|
||||||
private static $has_many = array(
|
private static $has_many = array(
|
||||||
'CustomRules' => 'UserDefinedForm_EmailRecipientCondition'
|
'CustomRules' => 'UserDefinedForm_EmailRecipientCondition'
|
||||||
);
|
);
|
||||||
|
|
||||||
private static $summary_fields = array(
|
private static $summary_fields = array(
|
||||||
'EmailAddress',
|
'EmailAddress',
|
||||||
'EmailSubject',
|
'EmailSubject',
|
||||||
'EmailFrom'
|
'EmailFrom'
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setting this to true will allow you to select "risky" fields as
|
* Setting this to true will allow you to select "risky" fields as
|
||||||
* email recipient, such as free-text entry fields.
|
* email recipient, such as free-text entry fields.
|
||||||
*
|
*
|
||||||
* It's advisable to leave this off.
|
* It's advisable to leave this off.
|
||||||
*
|
*
|
||||||
* @config
|
* @config
|
||||||
* @var bool
|
* @var bool
|
||||||
*/
|
*/
|
||||||
private static $allow_unbound_recipient_fields = false;
|
private static $allow_unbound_recipient_fields = false;
|
||||||
|
|
||||||
public function summaryFields() {
|
public function summaryFields()
|
||||||
$fields = parent::summaryFields();
|
{
|
||||||
if(isset($fields['EmailAddress'])) {
|
$fields = parent::summaryFields();
|
||||||
$fields['EmailAddress'] = _t('UserDefinedForm.EMAILADDRESS', 'Email');
|
if (isset($fields['EmailAddress'])) {
|
||||||
}
|
$fields['EmailAddress'] = _t('UserDefinedForm.EMAILADDRESS', 'Email');
|
||||||
if(isset($fields['EmailSubject'])) {
|
}
|
||||||
$fields['EmailSubject'] = _t('UserDefinedForm.EMAILSUBJECT', 'Subject');
|
if (isset($fields['EmailSubject'])) {
|
||||||
}
|
$fields['EmailSubject'] = _t('UserDefinedForm.EMAILSUBJECT', 'Subject');
|
||||||
if(isset($fields['EmailFrom'])) {
|
}
|
||||||
$fields['EmailFrom'] = _t('UserDefinedForm.EMAILFROM', 'From');
|
if (isset($fields['EmailFrom'])) {
|
||||||
}
|
$fields['EmailFrom'] = _t('UserDefinedForm.EMAILFROM', 'From');
|
||||||
return $fields;
|
}
|
||||||
}
|
return $fields;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get instance of UserDefinedForm when editing in getCMSFields
|
* Get instance of UserDefinedForm when editing in getCMSFields
|
||||||
*
|
*
|
||||||
* @return UserDefinedFrom
|
* @return UserDefinedFrom
|
||||||
*/
|
*/
|
||||||
protected function getFormParent() {
|
protected function getFormParent()
|
||||||
$formID = $this->FormID
|
{
|
||||||
? $this->FormID
|
$formID = $this->FormID
|
||||||
: Session::get('CMSMain.currentPage');
|
? $this->FormID
|
||||||
return UserDefinedForm::get()->byID($formID);
|
: Session::get('CMSMain.currentPage');
|
||||||
}
|
return UserDefinedForm::get()->byID($formID);
|
||||||
|
}
|
||||||
|
|
||||||
public function getTitle() {
|
public function getTitle()
|
||||||
if($this->EmailAddress) {
|
{
|
||||||
return $this->EmailAddress;
|
if ($this->EmailAddress) {
|
||||||
}
|
return $this->EmailAddress;
|
||||||
if($this->EmailSubject) {
|
}
|
||||||
return $this->EmailSubject;
|
if ($this->EmailSubject) {
|
||||||
}
|
return $this->EmailSubject;
|
||||||
return parent::getTitle();
|
}
|
||||||
}
|
return parent::getTitle();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a gridfield config for editing filter rules
|
* Generate a gridfield config for editing filter rules
|
||||||
*
|
*
|
||||||
* @return GridFieldConfig
|
* @return GridFieldConfig
|
||||||
*/
|
*/
|
||||||
protected function getRulesConfig() {
|
protected function getRulesConfig()
|
||||||
$formFields = $this->getFormParent()->Fields();
|
{
|
||||||
|
$formFields = $this->getFormParent()->Fields();
|
||||||
|
|
||||||
$config = GridFieldConfig::create()
|
$config = GridFieldConfig::create()
|
||||||
->addComponents(
|
->addComponents(
|
||||||
new GridFieldButtonRow('before'),
|
new GridFieldButtonRow('before'),
|
||||||
new GridFieldToolbarHeader(),
|
new GridFieldToolbarHeader(),
|
||||||
new GridFieldAddNewInlineButton(),
|
new GridFieldAddNewInlineButton(),
|
||||||
new GridFieldDeleteAction(),
|
new GridFieldDeleteAction(),
|
||||||
$columns = new GridFieldEditableColumns()
|
$columns = new GridFieldEditableColumns()
|
||||||
);
|
);
|
||||||
|
|
||||||
$columns->setDisplayFields(array(
|
$columns->setDisplayFields(array(
|
||||||
'ConditionFieldID' => function($record, $column, $grid) use ($formFields) {
|
'ConditionFieldID' => function ($record, $column, $grid) use ($formFields) {
|
||||||
return DropdownField::create($column, false, $formFields->map('ID', 'Title'));
|
return DropdownField::create($column, false, $formFields->map('ID', 'Title'));
|
||||||
},
|
},
|
||||||
'ConditionOption' => function($record, $column, $grid) {
|
'ConditionOption' => function ($record, $column, $grid) {
|
||||||
$options = UserDefinedForm_EmailRecipientCondition::config()->condition_options;
|
$options = UserDefinedForm_EmailRecipientCondition::config()->condition_options;
|
||||||
return DropdownField::create($column, false, $options);
|
return DropdownField::create($column, false, $options);
|
||||||
},
|
},
|
||||||
'ConditionValue' => function($record, $column, $grid) {
|
'ConditionValue' => function ($record, $column, $grid) {
|
||||||
return TextField::create($column);
|
return TextField::create($column);
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
|
|
||||||
return $config;
|
return $config;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return FieldList
|
* @return FieldList
|
||||||
*/
|
*/
|
||||||
public function getCMSFields() {
|
public function getCMSFields()
|
||||||
Requirements::javascript(USERFORMS_DIR . '/javascript/Recipient.js');
|
{
|
||||||
|
Requirements::javascript(USERFORMS_DIR . '/javascript/Recipient.js');
|
||||||
|
|
||||||
// Determine optional field values
|
// Determine optional field values
|
||||||
$form = $this->getFormParent();
|
$form = $this->getFormParent();
|
||||||
|
|
||||||
// predefined choices are also candidates
|
// predefined choices are also candidates
|
||||||
$multiOptionFields = EditableMultipleOptionField::get()->filter('ParentID', $form->ID);
|
$multiOptionFields = EditableMultipleOptionField::get()->filter('ParentID', $form->ID);
|
||||||
|
|
||||||
// if they have email fields then we could send from it
|
// if they have email fields then we could send from it
|
||||||
$validEmailFromFields = EditableEmailField::get()->filter('ParentID', $form->ID);
|
$validEmailFromFields = EditableEmailField::get()->filter('ParentID', $form->ID);
|
||||||
|
|
||||||
// For the subject, only one-line entry boxes make sense
|
// For the subject, only one-line entry boxes make sense
|
||||||
$validSubjectFields = ArrayList::create(
|
$validSubjectFields = ArrayList::create(
|
||||||
EditableTextField::get()
|
EditableTextField::get()
|
||||||
->filter('ParentID', $form->ID)
|
->filter('ParentID', $form->ID)
|
||||||
->exclude('Rows:GreaterThan', 1)
|
->exclude('Rows:GreaterThan', 1)
|
||||||
->toArray()
|
->toArray()
|
||||||
);
|
);
|
||||||
$validSubjectFields->merge($multiOptionFields);
|
$validSubjectFields->merge($multiOptionFields);
|
||||||
|
|
||||||
|
|
||||||
// Check valid email-recipient fields
|
// Check valid email-recipient fields
|
||||||
if($this->config()->allow_unbound_recipient_fields) {
|
if ($this->config()->allow_unbound_recipient_fields) {
|
||||||
// To address can only be email fields or multi option fields
|
// To address can only be email fields or multi option fields
|
||||||
$validEmailToFields = ArrayList::create($validEmailFromFields->toArray());
|
$validEmailToFields = ArrayList::create($validEmailFromFields->toArray());
|
||||||
$validEmailToFields->merge($multiOptionFields);
|
$validEmailToFields->merge($multiOptionFields);
|
||||||
} else {
|
} else {
|
||||||
// To address cannot be unbound, so restrict to pre-defined lists
|
// To address cannot be unbound, so restrict to pre-defined lists
|
||||||
$validEmailToFields = $multiOptionFields;
|
$validEmailToFields = $multiOptionFields;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build fieldlist
|
// Build fieldlist
|
||||||
$fields = FieldList::create(Tabset::create('Root')->addExtraClass('EmailRecipientForm'));
|
$fields = FieldList::create(Tabset::create('Root')->addExtraClass('EmailRecipientForm'));
|
||||||
|
|
||||||
// Configuration fields
|
// Configuration fields
|
||||||
$fields->addFieldsToTab('Root.EmailDetails', array(
|
$fields->addFieldsToTab('Root.EmailDetails', array(
|
||||||
// Subject
|
// Subject
|
||||||
FieldGroup::create(
|
FieldGroup::create(
|
||||||
TextField::create('EmailSubject', _t('UserDefinedForm.TYPESUBJECT', 'Type subject'))
|
TextField::create('EmailSubject', _t('UserDefinedForm.TYPESUBJECT', 'Type subject'))
|
||||||
->setAttribute('style', 'min-width: 400px;'),
|
->setAttribute('style', 'min-width: 400px;'),
|
||||||
DropdownField::create(
|
DropdownField::create(
|
||||||
'SendEmailSubjectFieldID',
|
'SendEmailSubjectFieldID',
|
||||||
_t('UserDefinedForm.SELECTAFIELDTOSETSUBJECT', '.. or select a field to use as the subject'),
|
_t('UserDefinedForm.SELECTAFIELDTOSETSUBJECT', '.. or select a field to use as the subject'),
|
||||||
$validSubjectFields->map('ID', 'Title')
|
$validSubjectFields->map('ID', 'Title')
|
||||||
)->setEmptyString('')
|
)->setEmptyString('')
|
||||||
)
|
)
|
||||||
->setTitle(_t('UserDefinedForm.EMAILSUBJECT', 'Email subject')),
|
->setTitle(_t('UserDefinedForm.EMAILSUBJECT', 'Email subject')),
|
||||||
|
|
||||||
// To
|
// To
|
||||||
FieldGroup::create(
|
FieldGroup::create(
|
||||||
TextField::create('EmailAddress', _t('UserDefinedForm.TYPETO', 'Type to address'))
|
TextField::create('EmailAddress', _t('UserDefinedForm.TYPETO', 'Type to address'))
|
||||||
->setAttribute('style', 'min-width: 400px;'),
|
->setAttribute('style', 'min-width: 400px;'),
|
||||||
DropdownField::create(
|
DropdownField::create(
|
||||||
'SendEmailToFieldID',
|
'SendEmailToFieldID',
|
||||||
_t('UserDefinedForm.ORSELECTAFIELDTOUSEASTO', '.. or select a field to use as the to address'),
|
_t('UserDefinedForm.ORSELECTAFIELDTOUSEASTO', '.. or select a field to use as the to address'),
|
||||||
$validEmailToFields->map('ID', 'Title')
|
$validEmailToFields->map('ID', 'Title')
|
||||||
)->setEmptyString(' ')
|
)->setEmptyString(' ')
|
||||||
)
|
)
|
||||||
->setTitle(_t('UserDefinedForm.SENDEMAILTO','Send email to'))
|
->setTitle(_t('UserDefinedForm.SENDEMAILTO', 'Send email to'))
|
||||||
->setDescription(_t(
|
->setDescription(_t(
|
||||||
'UserDefinedForm.SENDEMAILTO_DESCRIPTION',
|
'UserDefinedForm.SENDEMAILTO_DESCRIPTION',
|
||||||
'You may enter multiple email addresses as a comma separated list.'
|
'You may enter multiple email addresses as a comma separated list.'
|
||||||
)),
|
)),
|
||||||
|
|
||||||
|
|
||||||
// From
|
// From
|
||||||
TextField::create('EmailFrom', _t('UserDefinedForm.FROMADDRESS','Send email from'))
|
TextField::create('EmailFrom', _t('UserDefinedForm.FROMADDRESS', 'Send email from'))
|
||||||
->setDescription(_t(
|
->setDescription(_t(
|
||||||
'UserDefinedForm.EmailFromContent',
|
'UserDefinedForm.EmailFromContent',
|
||||||
"The from address allows you to set who the email comes from. On most servers this ".
|
"The from address allows you to set who the email comes from. On most servers this ".
|
||||||
"will need to be set to an email address on the same domain name as your site. ".
|
"will need to be set to an email address on the same domain name as your site. ".
|
||||||
"For example on yoursite.com the from address may need to be something@yoursite.com. ".
|
"For example on yoursite.com the from address may need to be something@yoursite.com. ".
|
||||||
"You can however, set any email address you wish as the reply to address."
|
"You can however, set any email address you wish as the reply to address."
|
||||||
)),
|
)),
|
||||||
|
|
||||||
|
|
||||||
// Reply-To
|
// Reply-To
|
||||||
FieldGroup::create(
|
FieldGroup::create(
|
||||||
TextField::create('EmailReplyTo', _t('UserDefinedForm.TYPEREPLY', 'Type reply address'))
|
TextField::create('EmailReplyTo', _t('UserDefinedForm.TYPEREPLY', 'Type reply address'))
|
||||||
->setAttribute('style', 'min-width: 400px;'),
|
->setAttribute('style', 'min-width: 400px;'),
|
||||||
DropdownField::create(
|
DropdownField::create(
|
||||||
'SendEmailFromFieldID',
|
'SendEmailFromFieldID',
|
||||||
_t('UserDefinedForm.ORSELECTAFIELDTOUSEASFROM', '.. or select a field to use as reply to address'),
|
_t('UserDefinedForm.ORSELECTAFIELDTOUSEASFROM', '.. or select a field to use as reply to address'),
|
||||||
$validEmailFromFields->map('ID', 'Title')
|
$validEmailFromFields->map('ID', 'Title')
|
||||||
)->setEmptyString(' ')
|
)->setEmptyString(' ')
|
||||||
)
|
)
|
||||||
->setTitle(_t('UserDefinedForm.REPLYADDRESS', 'Email for reply to'))
|
->setTitle(_t('UserDefinedForm.REPLYADDRESS', 'Email for reply to'))
|
||||||
->setDescription(_t(
|
->setDescription(_t(
|
||||||
'UserDefinedForm.REPLYADDRESS_DESCRIPTION',
|
'UserDefinedForm.REPLYADDRESS_DESCRIPTION',
|
||||||
'The email address which the recipient is able to \'reply\' to.'
|
'The email address which the recipient is able to \'reply\' to.'
|
||||||
))
|
))
|
||||||
));
|
));
|
||||||
|
|
||||||
|
$fields->fieldByName('Root.EmailDetails')->setTitle(_t('UserDefinedForm_EmailRecipient.EMAILDETAILSTAB', 'Email Details'));
|
||||||
|
|
||||||
$fields->fieldByName('Root.EmailDetails')->setTitle(_t('UserDefinedForm_EmailRecipient.EMAILDETAILSTAB', 'Email Details'));
|
// Only show the preview link if the recipient has been saved.
|
||||||
|
if (!empty($this->EmailTemplate)) {
|
||||||
|
$preview = sprintf(
|
||||||
|
'<p><a href="%s" target="_blank" class="ss-ui-button">%s</a></p><em>%s</em>',
|
||||||
|
"admin/pages/edit/EditForm/field/EmailRecipients/item/{$this->ID}/preview",
|
||||||
|
_t('UserDefinedForm.PREVIEW_EMAIL', 'Preview email'),
|
||||||
|
_t('UserDefinedForm.PREVIEW_EMAIL_DESCRIPTION', 'Note: Unsaved changes will not appear in the preview.')
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$preview = sprintf(
|
||||||
|
'<em>%s</em>',
|
||||||
|
_t(
|
||||||
|
'UserDefinedForm.PREVIEW_EMAIL_UNAVAILABLE',
|
||||||
|
'You can preview this email once you have saved the Recipient.'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Only show the preview link if the recipient has been saved.
|
// Email templates
|
||||||
if (!empty($this->EmailTemplate)) {
|
$fields->addFieldsToTab('Root.EmailContent', array(
|
||||||
$preview = sprintf(
|
CheckboxField::create('HideFormData', _t('UserDefinedForm.HIDEFORMDATA', 'Hide form data from email?')),
|
||||||
'<p><a href="%s" target="_blank" class="ss-ui-button">%s</a></p><em>%s</em>',
|
CheckboxField::create(
|
||||||
"admin/pages/edit/EditForm/field/EmailRecipients/item/{$this->ID}/preview",
|
'SendPlain',
|
||||||
_t('UserDefinedForm.PREVIEW_EMAIL', 'Preview email'),
|
_t('UserDefinedForm.SENDPLAIN', 'Send email as plain text? (HTML will be stripped)')
|
||||||
_t('UserDefinedForm.PREVIEW_EMAIL_DESCRIPTION', 'Note: Unsaved changes will not appear in the preview.')
|
),
|
||||||
);
|
DropdownField::create(
|
||||||
} else {
|
'EmailTemplate',
|
||||||
$preview = sprintf(
|
_t('UserDefinedForm.EMAILTEMPLATE', 'Email template'),
|
||||||
'<em>%s</em>',
|
$this->getEmailTemplateDropdownValues()
|
||||||
_t(
|
)->addExtraClass('toggle-html-only'),
|
||||||
'UserDefinedForm.PREVIEW_EMAIL_UNAVAILABLE',
|
HTMLEditorField::create('EmailBodyHtml', _t('UserDefinedForm.EMAILBODYHTML', 'Body'))
|
||||||
'You can preview this email once you have saved the Recipient.'
|
->addExtraClass('toggle-html-only'),
|
||||||
)
|
TextareaField::create('EmailBody', _t('UserDefinedForm.EMAILBODY', 'Body'))
|
||||||
);
|
->addExtraClass('toggle-plain-only'),
|
||||||
}
|
LiteralField::create(
|
||||||
|
'EmailPreview',
|
||||||
|
'<div id="EmailPreview" class="field toggle-html-only">' . $preview . '</div>'
|
||||||
|
)
|
||||||
|
));
|
||||||
|
|
||||||
|
$fields->fieldByName('Root.EmailContent')->setTitle(_t('UserDefinedForm_EmailRecipient.EMAILCONTENTTAB', 'Email Content'));
|
||||||
|
|
||||||
// Email templates
|
// Custom rules for sending this field
|
||||||
$fields->addFieldsToTab('Root.EmailContent', array(
|
$grid = new GridField(
|
||||||
CheckboxField::create('HideFormData', _t('UserDefinedForm.HIDEFORMDATA', 'Hide form data from email?')),
|
"CustomRules",
|
||||||
CheckboxField::create(
|
_t('EditableFormField.CUSTOMRULES', 'Custom Rules'),
|
||||||
'SendPlain',
|
$this->CustomRules(),
|
||||||
_t('UserDefinedForm.SENDPLAIN', 'Send email as plain text? (HTML will be stripped)')
|
$this->getRulesConfig()
|
||||||
),
|
);
|
||||||
DropdownField::create(
|
$grid->setDescription(_t(
|
||||||
'EmailTemplate',
|
'UserDefinedForm.RulesDescription',
|
||||||
_t('UserDefinedForm.EMAILTEMPLATE', 'Email template'),
|
'Emails will only be sent to the recipient if the custom rules are met. If no rules are defined, this receipient will receive notifications for every submission.'
|
||||||
$this->getEmailTemplateDropdownValues()
|
));
|
||||||
)->addExtraClass('toggle-html-only'),
|
$fields->addFieldsToTab('Root.CustomRules', array(
|
||||||
HTMLEditorField::create('EmailBodyHtml', _t('UserDefinedForm.EMAILBODYHTML','Body'))
|
new DropdownField(
|
||||||
->addExtraClass('toggle-html-only'),
|
'CustomRulesCondition',
|
||||||
TextareaField::create('EmailBody', _t('UserDefinedForm.EMAILBODY','Body'))
|
_t('UserDefinedForm.SENDIF', 'Send condition'),
|
||||||
->addExtraClass('toggle-plain-only'),
|
array(
|
||||||
LiteralField::create(
|
'Or' => _t('UserDefinedForm.SENDIFOR', 'Any conditions are true'),
|
||||||
'EmailPreview',
|
'And' => _t('UserDefinedForm.SENDIFAND', 'All conditions are true')
|
||||||
'<div id="EmailPreview" class="field toggle-html-only">' . $preview . '</div>'
|
)
|
||||||
)
|
),
|
||||||
));
|
$grid
|
||||||
|
));
|
||||||
|
|
||||||
|
$fields->fieldByName('Root.CustomRules')->setTitle(_t('UserDefinedForm_EmailRecipient.CUSTOMRULESTAB', 'Custom Rules'));
|
||||||
|
|
||||||
$fields->fieldByName('Root.EmailContent')->setTitle(_t('UserDefinedForm_EmailRecipient.EMAILCONTENTTAB', 'Email Content'));
|
$this->extend('updateCMSFields', $fields);
|
||||||
|
return $fields;
|
||||||
|
}
|
||||||
|
|
||||||
// Custom rules for sending this field
|
/**
|
||||||
$grid = new GridField(
|
* Return whether a user can create an object of this type
|
||||||
"CustomRules",
|
*
|
||||||
_t('EditableFormField.CUSTOMRULES', 'Custom Rules'),
|
|
||||||
$this->CustomRules(),
|
|
||||||
$this->getRulesConfig()
|
|
||||||
);
|
|
||||||
$grid->setDescription(_t(
|
|
||||||
'UserDefinedForm.RulesDescription',
|
|
||||||
'Emails will only be sent to the recipient if the custom rules are met. If no rules are defined, this receipient will receive notifications for every submission.'
|
|
||||||
));
|
|
||||||
$fields->addFieldsToTab('Root.CustomRules', array(
|
|
||||||
new DropdownField(
|
|
||||||
'CustomRulesCondition',
|
|
||||||
_t('UserDefinedForm.SENDIF', 'Send condition'),
|
|
||||||
array(
|
|
||||||
'Or' => _t('UserDefinedForm.SENDIFOR', 'Any conditions are true'),
|
|
||||||
'And' => _t('UserDefinedForm.SENDIFAND', 'All conditions are true')
|
|
||||||
)
|
|
||||||
),
|
|
||||||
$grid
|
|
||||||
));
|
|
||||||
|
|
||||||
$fields->fieldByName('Root.CustomRules')->setTitle(_t('UserDefinedForm_EmailRecipient.CUSTOMRULESTAB', 'Custom Rules'));
|
|
||||||
|
|
||||||
$this->extend('updateCMSFields', $fields);
|
|
||||||
return $fields;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return whether a user can create an object of this type
|
|
||||||
*
|
|
||||||
* @param Member $member
|
* @param Member $member
|
||||||
* @param array $context Virtual parameter to allow context to be passed in to check
|
* @param array $context Virtual parameter to allow context to be passed in to check
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function canCreate($member = null) {
|
public function canCreate($member = null)
|
||||||
// Check parent page
|
{
|
||||||
|
// Check parent page
|
||||||
$parent = $this->getCanCreateContext(func_get_args());
|
$parent = $this->getCanCreateContext(func_get_args());
|
||||||
if($parent) {
|
if ($parent) {
|
||||||
return $parent->canEdit($member);
|
return $parent->canEdit($member);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fall back to secure admin permissions
|
// Fall back to secure admin permissions
|
||||||
return parent::canCreate($member);
|
return parent::canCreate($member);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to check the parent for this object
|
* Helper method to check the parent for this object
|
||||||
@ -313,13 +320,14 @@ class UserDefinedForm_EmailRecipient extends DataObject {
|
|||||||
* @param array $args List of arguments passed to canCreate
|
* @param array $args List of arguments passed to canCreate
|
||||||
* @return SiteTree Parent page instance
|
* @return SiteTree Parent page instance
|
||||||
*/
|
*/
|
||||||
protected function getCanCreateContext($args) {
|
protected function getCanCreateContext($args)
|
||||||
|
{
|
||||||
// Inspect second parameter to canCreate for a 'Parent' context
|
// Inspect second parameter to canCreate for a 'Parent' context
|
||||||
if(isset($args[1]['Form'])) {
|
if (isset($args[1]['Form'])) {
|
||||||
return $args[1]['Form'];
|
return $args[1]['Form'];
|
||||||
}
|
}
|
||||||
// Hack in currently edited page if context is missing
|
// Hack in currently edited page if context is missing
|
||||||
if(Controller::has_curr() && Controller::curr() instanceof CMSMain) {
|
if (Controller::has_curr() && Controller::curr() instanceof CMSMain) {
|
||||||
return Controller::curr()->currentPage();
|
return Controller::curr()->currentPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -327,104 +335,111 @@ class UserDefinedForm_EmailRecipient extends DataObject {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Member
|
* @param Member
|
||||||
*
|
*
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function canView($member = null) {
|
public function canView($member = null)
|
||||||
return $this->Form()->canView($member);
|
{
|
||||||
}
|
return $this->Form()->canView($member);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Member
|
* @param Member
|
||||||
*
|
*
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function canEdit($member = null) {
|
public function canEdit($member = null)
|
||||||
return $this->Form()->canEdit($member);
|
{
|
||||||
}
|
return $this->Form()->canEdit($member);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Member
|
* @param Member
|
||||||
*
|
*
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function canDelete($member = null) {
|
public function canDelete($member = null)
|
||||||
return $this->canEdit($member);
|
{
|
||||||
}
|
return $this->canEdit($member);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Determine if this recipient may receive notifications for this submission
|
* Determine if this recipient may receive notifications for this submission
|
||||||
*
|
*
|
||||||
* @param array $data
|
* @param array $data
|
||||||
* @param Form $form
|
* @param Form $form
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function canSend($data, $form) {
|
public function canSend($data, $form)
|
||||||
// Skip if no rules configured
|
{
|
||||||
$customRules = $this->CustomRules();
|
// Skip if no rules configured
|
||||||
if(!$customRules->count()) {
|
$customRules = $this->CustomRules();
|
||||||
return true;
|
if (!$customRules->count()) {
|
||||||
}
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Check all rules
|
// Check all rules
|
||||||
$isAnd = $this->CustomRulesCondition === 'And';
|
$isAnd = $this->CustomRulesCondition === 'And';
|
||||||
foreach($customRules as $customRule) {
|
foreach ($customRules as $customRule) {
|
||||||
$matches = $customRule->matches($data, $form);
|
$matches = $customRule->matches($data, $form);
|
||||||
if($isAnd && !$matches) {
|
if ($isAnd && !$matches) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if(!$isAnd && $matches) {
|
if (!$isAnd && $matches) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Once all rules are checked
|
// Once all rules are checked
|
||||||
return $isAnd;
|
return $isAnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make sure the email template saved against the recipient exists on the file system.
|
* Make sure the email template saved against the recipient exists on the file system.
|
||||||
*
|
*
|
||||||
* @param string
|
* @param string
|
||||||
*
|
*
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function emailTemplateExists($template = '') {
|
public function emailTemplateExists($template = '')
|
||||||
$t = ($template ? $template : $this->EmailTemplate);
|
{
|
||||||
|
$t = ($template ? $template : $this->EmailTemplate);
|
||||||
|
|
||||||
return in_array($t, $this->getEmailTemplateDropdownValues());
|
return in_array($t, $this->getEmailTemplateDropdownValues());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the email body for the current email format
|
* Get the email body for the current email format
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getEmailBodyContent() {
|
public function getEmailBodyContent()
|
||||||
return $this->SendPlain ? $this->EmailBody : $this->EmailBodyHtml;
|
{
|
||||||
}
|
return $this->SendPlain ? $this->EmailBody : $this->EmailBodyHtml;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a list of email templates suitable for populating the email template dropdown.
|
* Gets a list of email templates suitable for populating the email template dropdown.
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function getEmailTemplateDropdownValues() {
|
public function getEmailTemplateDropdownValues()
|
||||||
$templates = array();
|
{
|
||||||
|
$templates = array();
|
||||||
|
|
||||||
$finder = new SS_FileFinder();
|
$finder = new SS_FileFinder();
|
||||||
$finder->setOption('name_regex', '/^.*\.ss$/');
|
$finder->setOption('name_regex', '/^.*\.ss$/');
|
||||||
|
|
||||||
$found = $finder->find(BASE_PATH . '/' . UserDefinedForm::config()->email_template_directory);
|
$found = $finder->find(BASE_PATH . '/' . UserDefinedForm::config()->email_template_directory);
|
||||||
|
|
||||||
foreach ($found as $key => $value) {
|
foreach ($found as $key => $value) {
|
||||||
$template = pathinfo($value);
|
$template = pathinfo($value);
|
||||||
|
|
||||||
$templates[$template['filename']] = $template['filename'];
|
$templates[$template['filename']] = $template['filename'];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $templates;
|
return $templates;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,71 +6,74 @@
|
|||||||
*
|
*
|
||||||
* @method UserDefinedForm_EmailRecipient Parent()
|
* @method UserDefinedForm_EmailRecipient Parent()
|
||||||
*/
|
*/
|
||||||
class UserDefinedForm_EmailRecipientCondition extends DataObject {
|
class UserDefinedForm_EmailRecipientCondition extends DataObject
|
||||||
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of options
|
* List of options
|
||||||
*
|
*
|
||||||
* @config
|
* @config
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
private static $condition_options = array(
|
private static $condition_options = array(
|
||||||
"IsBlank" => "Is blank",
|
"IsBlank" => "Is blank",
|
||||||
"IsNotBlank" => "Is not blank",
|
"IsNotBlank" => "Is not blank",
|
||||||
"Equals" => "Equals",
|
"Equals" => "Equals",
|
||||||
"NotEquals" => "Doesn't equal"
|
"NotEquals" => "Doesn't equal"
|
||||||
);
|
);
|
||||||
|
|
||||||
private static $db = array(
|
private static $db = array(
|
||||||
'ConditionOption' => 'Enum("IsBlank,IsNotBlank,Equals,NotEquals")',
|
'ConditionOption' => 'Enum("IsBlank,IsNotBlank,Equals,NotEquals")',
|
||||||
'ConditionValue' => 'Varchar'
|
'ConditionValue' => 'Varchar'
|
||||||
);
|
);
|
||||||
|
|
||||||
private static $has_one = array(
|
private static $has_one = array(
|
||||||
'Parent' => 'UserDefinedForm_EmailRecipient',
|
'Parent' => 'UserDefinedForm_EmailRecipient',
|
||||||
'ConditionField' => 'EditableFormField'
|
'ConditionField' => 'EditableFormField'
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if this rule matches the given condition
|
* Determine if this rule matches the given condition
|
||||||
*
|
*
|
||||||
* @param array $data
|
* @param array $data
|
||||||
* @param Form $form
|
* @param Form $form
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function matches($data, $form) {
|
public function matches($data, $form)
|
||||||
$fieldName = $this->ConditionField()->Name;
|
{
|
||||||
$fieldValue = isset($data[$fieldName]) ? $data[$fieldName] : null;
|
$fieldName = $this->ConditionField()->Name;
|
||||||
switch($this->ConditionOption) {
|
$fieldValue = isset($data[$fieldName]) ? $data[$fieldName] : null;
|
||||||
case 'IsBlank':
|
switch ($this->ConditionOption) {
|
||||||
return empty($fieldValue);
|
case 'IsBlank':
|
||||||
case 'IsNotBlank':
|
return empty($fieldValue);
|
||||||
return !empty($fieldValue);
|
case 'IsNotBlank':
|
||||||
default:
|
return !empty($fieldValue);
|
||||||
$matches = is_array($fieldValue)
|
default:
|
||||||
? in_array($this->ConditionValue, $fieldValue)
|
$matches = is_array($fieldValue)
|
||||||
: $this->ConditionValue === (string) $fieldValue;
|
? in_array($this->ConditionValue, $fieldValue)
|
||||||
return ($this->ConditionOption === 'Equals') === (bool)$matches;
|
: $this->ConditionValue === (string) $fieldValue;
|
||||||
}
|
return ($this->ConditionOption === 'Equals') === (bool)$matches;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return whether a user can create an object of this type
|
* Return whether a user can create an object of this type
|
||||||
*
|
*
|
||||||
* @param Member $member
|
* @param Member $member
|
||||||
* @param array $context Virtual parameter to allow context to be passed in to check
|
* @param array $context Virtual parameter to allow context to be passed in to check
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function canCreate($member = null) {
|
public function canCreate($member = null)
|
||||||
// Check parent page
|
{
|
||||||
|
// Check parent page
|
||||||
$parent = $this->getCanCreateContext(func_get_args());
|
$parent = $this->getCanCreateContext(func_get_args());
|
||||||
if($parent) {
|
if ($parent) {
|
||||||
return $parent->canEdit($member);
|
return $parent->canEdit($member);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fall back to secure admin permissions
|
// Fall back to secure admin permissions
|
||||||
return parent::canCreate($member);
|
return parent::canCreate($member);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to check the parent for this object
|
* Helper method to check the parent for this object
|
||||||
@ -78,13 +81,14 @@ class UserDefinedForm_EmailRecipientCondition extends DataObject {
|
|||||||
* @param array $args List of arguments passed to canCreate
|
* @param array $args List of arguments passed to canCreate
|
||||||
* @return SiteTree Parent page instance
|
* @return SiteTree Parent page instance
|
||||||
*/
|
*/
|
||||||
protected function getCanCreateContext($args) {
|
protected function getCanCreateContext($args)
|
||||||
|
{
|
||||||
// Inspect second parameter to canCreate for a 'Parent' context
|
// Inspect second parameter to canCreate for a 'Parent' context
|
||||||
if(isset($args[1]['Parent'])) {
|
if (isset($args[1]['Parent'])) {
|
||||||
return $args[1]['Parent'];
|
return $args[1]['Parent'];
|
||||||
}
|
}
|
||||||
// Hack in currently edited page if context is missing
|
// Hack in currently edited page if context is missing
|
||||||
if(Controller::has_curr() && Controller::curr() instanceof CMSMain) {
|
if (Controller::has_curr() && Controller::curr() instanceof CMSMain) {
|
||||||
return Controller::curr()->currentPage();
|
return Controller::curr()->currentPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,30 +96,33 @@ class UserDefinedForm_EmailRecipientCondition extends DataObject {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Member
|
* @param Member
|
||||||
*
|
*
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function canView($member = null) {
|
public function canView($member = null)
|
||||||
return $this->Parent()->canView($member);
|
{
|
||||||
}
|
return $this->Parent()->canView($member);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Member
|
* @param Member
|
||||||
*
|
*
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function canEdit($member = null) {
|
public function canEdit($member = null)
|
||||||
return $this->Parent()->canEdit($member);
|
{
|
||||||
}
|
return $this->Parent()->canEdit($member);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Member
|
* @param Member
|
||||||
*
|
*
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function canDelete($member = null) {
|
public function canDelete($member = null)
|
||||||
return $this->canEdit($member);
|
{
|
||||||
}
|
return $this->canEdit($member);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,23 +8,26 @@
|
|||||||
* @package userforms
|
* @package userforms
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class UserFormRecipientEmail extends Email {
|
class UserFormRecipientEmail extends Email
|
||||||
|
{
|
||||||
|
|
||||||
protected $ss_template = "SubmittedFormEmail";
|
protected $ss_template = "SubmittedFormEmail";
|
||||||
|
|
||||||
protected $data;
|
protected $data;
|
||||||
|
|
||||||
public function __construct($submittedFields = null) {
|
public function __construct($submittedFields = null)
|
||||||
parent::__construct($submittedFields = null);
|
{
|
||||||
}
|
parent::__construct($submittedFields = null);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the "Reply-To" header with an email address rather than append as
|
* Set the "Reply-To" header with an email address rather than append as
|
||||||
* {@link Email::replyTo} does.
|
* {@link Email::replyTo} does.
|
||||||
*
|
*
|
||||||
* @param string $email The email address to set the "Reply-To" header to
|
* @param string $email The email address to set the "Reply-To" header to
|
||||||
*/
|
*/
|
||||||
public function setReplyTo($email) {
|
public function setReplyTo($email)
|
||||||
$this->customHeaders['Reply-To'] = $email;
|
{
|
||||||
}
|
$this->customHeaders['Reply-To'] = $email;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,47 +5,50 @@
|
|||||||
*
|
*
|
||||||
* @package userforms
|
* @package userforms
|
||||||
*/
|
*/
|
||||||
class UserFormRecipientItemRequest extends GridFieldDetailForm_ItemRequest {
|
class UserFormRecipientItemRequest extends GridFieldDetailForm_ItemRequest
|
||||||
|
{
|
||||||
|
|
||||||
private static $allowed_actions = array(
|
private static $allowed_actions = array(
|
||||||
'edit',
|
'edit',
|
||||||
'view',
|
'view',
|
||||||
'ItemEditForm',
|
'ItemEditForm',
|
||||||
'preview'
|
'preview'
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders a preview of the recipient email.
|
* Renders a preview of the recipient email.
|
||||||
*/
|
*/
|
||||||
public function preview() {
|
public function preview()
|
||||||
return $this->customise(new ArrayData(array(
|
{
|
||||||
'Body' => $this->record->getEmailBodyContent(),
|
return $this->customise(new ArrayData(array(
|
||||||
'HideFormData' => $this->record->HideFormData,
|
'Body' => $this->record->getEmailBodyContent(),
|
||||||
'Fields' => $this->getPreviewFieldData()
|
'HideFormData' => $this->record->HideFormData,
|
||||||
)))->renderWith($this->record->EmailTemplate);
|
'Fields' => $this->getPreviewFieldData()
|
||||||
}
|
)))->renderWith($this->record->EmailTemplate);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get some placeholder field values to display in the preview
|
* Get some placeholder field values to display in the preview
|
||||||
* @return ArrayList
|
* @return ArrayList
|
||||||
*/
|
*/
|
||||||
private function getPreviewFieldData() {
|
private function getPreviewFieldData()
|
||||||
$data = new ArrayList();
|
{
|
||||||
|
$data = new ArrayList();
|
||||||
|
|
||||||
$fields = $this->record->Form()->Fields()->filter(array(
|
$fields = $this->record->Form()->Fields()->filter(array(
|
||||||
'ClassName:not' => 'EditableLiteralField',
|
'ClassName:not' => 'EditableLiteralField',
|
||||||
'ClassName:not' => 'EditableFormHeading'
|
'ClassName:not' => 'EditableFormHeading'
|
||||||
));
|
));
|
||||||
|
|
||||||
foreach ($fields as $field) {
|
foreach ($fields as $field) {
|
||||||
$data->push(new ArrayData(array(
|
$data->push(new ArrayData(array(
|
||||||
'Name' => $field->Name,
|
'Name' => $field->Name,
|
||||||
'Title' => $field->Title,
|
'Title' => $field->Title,
|
||||||
'Value' => '$' . $field->Name,
|
'Value' => '$' . $field->Name,
|
||||||
'FormattedValue' => '$' . $field->Name
|
'FormattedValue' => '$' . $field->Name
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,63 +7,68 @@
|
|||||||
* @package userforms
|
* @package userforms
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class SubmittedFileField extends SubmittedFormField {
|
class SubmittedFileField extends SubmittedFormField
|
||||||
|
{
|
||||||
|
|
||||||
private static $has_one = array(
|
private static $has_one = array(
|
||||||
"UploadedFile" => "File"
|
"UploadedFile" => "File"
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the value of this field for inclusion into things such as
|
* Return the value of this field for inclusion into things such as
|
||||||
* reports.
|
* reports.
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getFormattedValue() {
|
public function getFormattedValue()
|
||||||
$name = $this->getFileName();
|
{
|
||||||
$link = $this->getLink();
|
$name = $this->getFileName();
|
||||||
$title = _t('SubmittedFileField.DOWNLOADFILE', 'Download File');
|
$link = $this->getLink();
|
||||||
|
$title = _t('SubmittedFileField.DOWNLOADFILE', 'Download File');
|
||||||
|
|
||||||
if($link) {
|
if ($link) {
|
||||||
return DBField::create_field('HTMLText', sprintf(
|
return DBField::create_field('HTMLText', sprintf(
|
||||||
'%s - <a href="%s" target="_blank">%s</a>',
|
'%s - <a href="%s" target="_blank">%s</a>',
|
||||||
$name, $link, $title
|
$name, $link, $title
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the value for this field in the CSV export.
|
* Return the value for this field in the CSV export.
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getExportValue() {
|
public function getExportValue()
|
||||||
return ($link = $this->getLink()) ? $link : "";
|
{
|
||||||
}
|
return ($link = $this->getLink()) ? $link : "";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the link for the file attached to this submitted form field.
|
* Return the link for the file attached to this submitted form field.
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getLink() {
|
public function getLink()
|
||||||
if($file = $this->UploadedFile()) {
|
{
|
||||||
if(trim($file->getFilename(), '/') != trim(ASSETS_DIR,'/')) {
|
if ($file = $this->UploadedFile()) {
|
||||||
return $this->UploadedFile()->URL;
|
if (trim($file->getFilename(), '/') != trim(ASSETS_DIR, '/')) {
|
||||||
}
|
return $this->UploadedFile()->URL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the name of the file, if present
|
* Return the name of the file, if present
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getFileName() {
|
public function getFileName()
|
||||||
if($this->UploadedFile()) {
|
{
|
||||||
return $this->UploadedFile()->Name;
|
if ($this->UploadedFile()) {
|
||||||
}
|
return $this->UploadedFile()->Name;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,143 +5,150 @@
|
|||||||
* @package userforms
|
* @package userforms
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class SubmittedForm extends DataObject {
|
class SubmittedForm extends DataObject
|
||||||
|
{
|
||||||
|
|
||||||
private static $has_one = array(
|
private static $has_one = array(
|
||||||
"SubmittedBy" => "Member",
|
"SubmittedBy" => "Member",
|
||||||
"Parent" => "UserDefinedForm",
|
"Parent" => "UserDefinedForm",
|
||||||
);
|
);
|
||||||
|
|
||||||
private static $has_many = array(
|
private static $has_many = array(
|
||||||
"Values" => "SubmittedFormField"
|
"Values" => "SubmittedFormField"
|
||||||
);
|
);
|
||||||
|
|
||||||
private static $summary_fields = array(
|
private static $summary_fields = array(
|
||||||
'ID',
|
'ID',
|
||||||
'Created'
|
'Created'
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the value of a relation or, in the case of this form, the value
|
* Returns the value of a relation or, in the case of this form, the value
|
||||||
* of a given child {@link SubmittedFormField}
|
* of a given child {@link SubmittedFormField}
|
||||||
*
|
*
|
||||||
* @param string
|
* @param string
|
||||||
*
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function relField($fieldName) {
|
public function relField($fieldName)
|
||||||
// default case
|
{
|
||||||
if($value = parent::relField($fieldName)) {
|
// default case
|
||||||
return $value;
|
if ($value = parent::relField($fieldName)) {
|
||||||
}
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
// check values for a form field with the matching name.
|
// check values for a form field with the matching name.
|
||||||
$formField = SubmittedFormField::get()->filter(array(
|
$formField = SubmittedFormField::get()->filter(array(
|
||||||
'ParentID' => $this->ID,
|
'ParentID' => $this->ID,
|
||||||
'Name' => $fieldName
|
'Name' => $fieldName
|
||||||
))->first();
|
))->first();
|
||||||
|
|
||||||
if($formField) {
|
if ($formField) {
|
||||||
return $formField->getFormattedValue();
|
return $formField->getFormattedValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return FieldList
|
* @return FieldList
|
||||||
*/
|
*/
|
||||||
public function getCMSFields() {
|
public function getCMSFields()
|
||||||
|
{
|
||||||
|
$self = $this;
|
||||||
|
|
||||||
$self = $this;
|
$this->beforeUpdateCMSFields(function ($fields) use ($self) {
|
||||||
|
$fields->removeByName('Values');
|
||||||
|
$fields->dataFieldByName('SubmittedByID')->setDisabled(true);
|
||||||
|
|
||||||
$this->beforeUpdateCMSFields(function($fields) use ($self) {
|
$values = new GridField(
|
||||||
$fields->removeByName('Values');
|
'Values',
|
||||||
$fields->dataFieldByName('SubmittedByID')->setDisabled(true);
|
'SubmittedFormField',
|
||||||
|
$self->Values()->sort('Created', 'ASC')
|
||||||
|
);
|
||||||
|
|
||||||
$values = new GridField(
|
$config = new GridFieldConfig();
|
||||||
'Values',
|
$config->addComponent(new GridFieldDataColumns());
|
||||||
'SubmittedFormField',
|
$config->addComponent(new GridFieldExportButton());
|
||||||
$self->Values()->sort('Created', 'ASC')
|
$config->addComponent(new GridFieldPrintButton());
|
||||||
);
|
$values->setConfig($config);
|
||||||
|
|
||||||
$config = new GridFieldConfig();
|
$fields->addFieldToTab('Root.Main', $values);
|
||||||
$config->addComponent(new GridFieldDataColumns());
|
});
|
||||||
$config->addComponent(new GridFieldExportButton());
|
|
||||||
$config->addComponent(new GridFieldPrintButton());
|
|
||||||
$values->setConfig($config);
|
|
||||||
|
|
||||||
$fields->addFieldToTab('Root.Main', $values);
|
$fields = parent::getCMSFields();
|
||||||
});
|
|
||||||
|
|
||||||
$fields = parent::getCMSFields();
|
return $fields;
|
||||||
|
}
|
||||||
|
|
||||||
return $fields;
|
/**
|
||||||
}
|
* @param Member
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function canCreate($member = null)
|
||||||
|
{
|
||||||
|
$extended = $this->extendedCan(__FUNCTION__, $member);
|
||||||
|
if ($extended !== null) {
|
||||||
|
return $extended;
|
||||||
|
}
|
||||||
|
return $this->Parent()->canCreate();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Member
|
* @param Member
|
||||||
*
|
*
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function canCreate($member = null) {
|
public function canView($member = null)
|
||||||
$extended = $this->extendedCan(__FUNCTION__, $member);
|
{
|
||||||
if($extended !== null) {
|
$extended = $this->extendedCan(__FUNCTION__, $member);
|
||||||
return $extended;
|
if ($extended !== null) {
|
||||||
}
|
return $extended;
|
||||||
return $this->Parent()->canCreate();
|
}
|
||||||
}
|
return $this->Parent()->canView();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Member
|
* @param Member
|
||||||
*
|
*
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function canView($member = null) {
|
public function canEdit($member = null)
|
||||||
$extended = $this->extendedCan(__FUNCTION__, $member);
|
{
|
||||||
if($extended !== null) {
|
$extended = $this->extendedCan(__FUNCTION__, $member);
|
||||||
return $extended;
|
if ($extended !== null) {
|
||||||
}
|
return $extended;
|
||||||
return $this->Parent()->canView();
|
}
|
||||||
}
|
return $this->Parent()->canEdit();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Member
|
* @param Member
|
||||||
*
|
*
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function canEdit($member = null) {
|
public function canDelete($member = null)
|
||||||
$extended = $this->extendedCan(__FUNCTION__, $member);
|
{
|
||||||
if($extended !== null) {
|
$extended = $this->extendedCan(__FUNCTION__, $member);
|
||||||
return $extended;
|
if ($extended !== null) {
|
||||||
}
|
return $extended;
|
||||||
return $this->Parent()->canEdit();
|
}
|
||||||
}
|
return $this->Parent()->canDelete();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Member
|
* Before we delete this form make sure we delete all the
|
||||||
*
|
* field values so that we don't leave old data round
|
||||||
* @return boolean
|
*
|
||||||
*/
|
* @return void
|
||||||
public function canDelete($member = null) {
|
*/
|
||||||
$extended = $this->extendedCan(__FUNCTION__, $member);
|
protected function onBeforeDelete()
|
||||||
if($extended !== null) {
|
{
|
||||||
return $extended;
|
if ($this->Values()) {
|
||||||
}
|
foreach ($this->Values() as $value) {
|
||||||
return $this->Parent()->canDelete();
|
$value->delete();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
parent::onBeforeDelete();
|
||||||
* Before we delete this form make sure we delete all the
|
}
|
||||||
* field values so that we don't leave old data round
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function onBeforeDelete() {
|
|
||||||
if($this->Values()) {
|
|
||||||
foreach($this->Values() as $value) {
|
|
||||||
$value->delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
parent::onBeforeDelete();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -5,93 +5,101 @@
|
|||||||
* @package userforms
|
* @package userforms
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class SubmittedFormField extends DataObject {
|
class SubmittedFormField extends DataObject
|
||||||
|
{
|
||||||
|
|
||||||
private static $db = array(
|
private static $db = array(
|
||||||
"Name" => "Varchar",
|
"Name" => "Varchar",
|
||||||
"Value" => "Text",
|
"Value" => "Text",
|
||||||
"Title" => "Varchar(255)"
|
"Title" => "Varchar(255)"
|
||||||
);
|
);
|
||||||
|
|
||||||
private static $has_one = array(
|
private static $has_one = array(
|
||||||
"Parent" => "SubmittedForm"
|
"Parent" => "SubmittedForm"
|
||||||
);
|
);
|
||||||
|
|
||||||
private static $summary_fields = array(
|
private static $summary_fields = array(
|
||||||
'Title' => 'Title',
|
'Title' => 'Title',
|
||||||
'FormattedValue' => 'Value'
|
'FormattedValue' => 'Value'
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Member
|
* @param Member
|
||||||
*
|
*
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function canCreate($member = null) {
|
public function canCreate($member = null)
|
||||||
return $this->Parent()->canCreate();
|
{
|
||||||
}
|
return $this->Parent()->canCreate();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Member
|
* @param Member
|
||||||
*
|
*
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function canView($member = null) {
|
public function canView($member = null)
|
||||||
return $this->Parent()->canView();
|
{
|
||||||
}
|
return $this->Parent()->canView();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Member
|
* @param Member
|
||||||
*
|
*
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function canEdit($member = null) {
|
public function canEdit($member = null)
|
||||||
return $this->Parent()->canEdit();
|
{
|
||||||
}
|
return $this->Parent()->canEdit();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Member
|
* @param Member
|
||||||
*
|
*
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function canDelete($member = null) {
|
public function canDelete($member = null)
|
||||||
return $this->Parent()->canDelete();
|
{
|
||||||
}
|
return $this->Parent()->canDelete();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a formatted value for the reports and email notifications.
|
* Generate a formatted value for the reports and email notifications.
|
||||||
* Converts new lines (which are stored in the database text field) as
|
* Converts new lines (which are stored in the database text field) as
|
||||||
* <brs> so they will output as newlines in the reports
|
* <brs> so they will output as newlines in the reports
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getFormattedValue() {
|
public function getFormattedValue()
|
||||||
return nl2br($this->dbObject('Value')->ATT());
|
{
|
||||||
}
|
return nl2br($this->dbObject('Value')->ATT());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the value of this submitted form field suitable for inclusion
|
* Return the value of this submitted form field suitable for inclusion
|
||||||
* into the CSV
|
* into the CSV
|
||||||
*
|
*
|
||||||
* @return Text
|
* @return Text
|
||||||
*/
|
*/
|
||||||
public function getExportValue() {
|
public function getExportValue()
|
||||||
return $this->Value;
|
{
|
||||||
}
|
return $this->Value;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find equivalent editable field for this submission.
|
* Find equivalent editable field for this submission.
|
||||||
*
|
*
|
||||||
* Note the field may have been modified or deleted from the original form
|
* Note the field may have been modified or deleted from the original form
|
||||||
* so this may not always return the data you expect. If you need to save
|
* so this may not always return the data you expect. If you need to save
|
||||||
* a particular state of editable form field at time of submission, copy
|
* a particular state of editable form field at time of submission, copy
|
||||||
* that value to the submission.
|
* that value to the submission.
|
||||||
*
|
*
|
||||||
* @return EditableFormField
|
* @return EditableFormField
|
||||||
*/
|
*/
|
||||||
public function getEditableField() {
|
public function getEditableField()
|
||||||
return $this->Parent()->Parent()->Fields()->filter(array(
|
{
|
||||||
'Name' => $this->Name
|
return $this->Parent()->Parent()->Fields()->filter(array(
|
||||||
))->First();
|
'Name' => $this->Name
|
||||||
}
|
))->First();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,53 +2,56 @@
|
|||||||
|
|
||||||
use SilverStripe\Forms\SegmentFieldModifier\AbstractSegmentFieldModifier;
|
use SilverStripe\Forms\SegmentFieldModifier\AbstractSegmentFieldModifier;
|
||||||
|
|
||||||
class DisambiguationSegmentFieldModifier extends AbstractSegmentFieldModifier {
|
class DisambiguationSegmentFieldModifier extends AbstractSegmentFieldModifier
|
||||||
/**
|
{
|
||||||
* @inheritdoc
|
/**
|
||||||
*
|
* @inheritdoc
|
||||||
* @param string $value
|
*
|
||||||
*
|
* @param string $value
|
||||||
* @return string
|
*
|
||||||
*/
|
* @return string
|
||||||
public function getPreview($value) {
|
*/
|
||||||
if($this->form instanceof Form && $record = $this->form->getRecord()) {
|
public function getPreview($value)
|
||||||
$parent = $record->Parent();
|
{
|
||||||
|
if ($this->form instanceof Form && $record = $this->form->getRecord()) {
|
||||||
|
$parent = $record->Parent();
|
||||||
|
|
||||||
$try = $value;
|
$try = $value;
|
||||||
|
|
||||||
$sibling = EditableformField::get()
|
$sibling = EditableformField::get()
|
||||||
->filter('ParentID', $parent->ID)
|
->filter('ParentID', $parent->ID)
|
||||||
->filter('Name', $try)
|
->filter('Name', $try)
|
||||||
->where('"ID" != ' . $record->ID)
|
->where('"ID" != ' . $record->ID)
|
||||||
->first();
|
->first();
|
||||||
|
|
||||||
$counter = 1;
|
$counter = 1;
|
||||||
|
|
||||||
while($sibling !== null) {
|
while ($sibling !== null) {
|
||||||
$try = $value . '_' . $counter++;
|
$try = $value . '_' . $counter++;
|
||||||
|
|
||||||
$sibling = EditableformField::get()
|
$sibling = EditableformField::get()
|
||||||
->filter('ParentID', $parent->ID)
|
->filter('ParentID', $parent->ID)
|
||||||
->filter('Name', $try)
|
->filter('Name', $try)
|
||||||
->first();
|
->first();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($try !== $value) {
|
if ($try !== $value) {
|
||||||
return $try;
|
return $try;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*
|
*
|
||||||
* @param string $value
|
* @param string $value
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getSuggestion($value) {
|
public function getSuggestion($value)
|
||||||
return $this->getPreview($value);
|
{
|
||||||
}
|
return $this->getPreview($value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,26 +2,29 @@
|
|||||||
|
|
||||||
use SilverStripe\Forms\SegmentFieldModifier\SlugSegmentFieldModifier;
|
use SilverStripe\Forms\SegmentFieldModifier\SlugSegmentFieldModifier;
|
||||||
|
|
||||||
class UnderscoreSegmentFieldModifier extends SlugSegmentFieldModifier {
|
class UnderscoreSegmentFieldModifier extends SlugSegmentFieldModifier
|
||||||
/**
|
{
|
||||||
* @inheritdoc
|
/**
|
||||||
*
|
* @inheritdoc
|
||||||
* @param string $value
|
*
|
||||||
*
|
* @param string $value
|
||||||
* @return string
|
*
|
||||||
*/
|
* @return string
|
||||||
public function getPreview($value) {
|
*/
|
||||||
return str_replace('-', '_', parent::getPreview($value));
|
public function getPreview($value)
|
||||||
}
|
{
|
||||||
|
return str_replace('-', '_', parent::getPreview($value));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*
|
*
|
||||||
* @param string $value
|
* @param string $value
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getSuggestion($value) {
|
public function getSuggestion($value)
|
||||||
return str_replace('-', '_', parent::getSuggestion($value));
|
{
|
||||||
}
|
return str_replace('-', '_', parent::getSuggestion($value));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,54 +8,54 @@
|
|||||||
* @package userforms
|
* @package userforms
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class UserFormsColumnCleanTask extends MigrationTask {
|
class UserFormsColumnCleanTask extends MigrationTask
|
||||||
|
{
|
||||||
|
|
||||||
protected $title = "UserForms EditableFormField Column Clean task";
|
protected $title = "UserForms EditableFormField Column Clean task";
|
||||||
|
|
||||||
protected $description = "Removes unused columns from EditableFormField for MySQL databases;";
|
protected $description = "Removes unused columns from EditableFormField for MySQL databases;";
|
||||||
|
|
||||||
protected $tables = array('EditableFormField');
|
protected $tables = array('EditableFormField');
|
||||||
|
|
||||||
protected $keepColumns = array('ID');
|
protected $keepColumns = array('ID');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Publish the existing forms.
|
* Publish the existing forms.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public function run($request) {
|
public function run($request)
|
||||||
foreach ($this->tables as $db) {
|
{
|
||||||
$obj = new $db();
|
foreach ($this->tables as $db) {
|
||||||
$columns = $obj->database_fields($db);
|
$obj = new $db();
|
||||||
$query = "SHOW COLUMNS FROM $db";
|
$columns = $obj->database_fields($db);
|
||||||
$liveColumns = DB::query($query)->column();
|
$query = "SHOW COLUMNS FROM $db";
|
||||||
$backedUp = 0;
|
$liveColumns = DB::query($query)->column();
|
||||||
$query = "SHOW TABLES LIKE 'Backup_$db'";
|
$backedUp = 0;
|
||||||
$tableExists = DB::query($query)->value();
|
$query = "SHOW TABLES LIKE 'Backup_$db'";
|
||||||
if ($tableExists != null) {
|
$tableExists = DB::query($query)->value();
|
||||||
echo "Tasks run already on $db exiting";
|
if ($tableExists != null) {
|
||||||
return;
|
echo "Tasks run already on $db exiting";
|
||||||
}
|
return;
|
||||||
$backedUp = 0;
|
}
|
||||||
foreach ($liveColumns as $index => $column) {
|
$backedUp = 0;
|
||||||
if ($backedUp == 0) {
|
foreach ($liveColumns as $index => $column) {
|
||||||
echo "Backing up $db <br />";
|
if ($backedUp == 0) {
|
||||||
echo "Creating Backup_$db <br />";
|
echo "Backing up $db <br />";
|
||||||
// backup table
|
echo "Creating Backup_$db <br />";
|
||||||
$query = "CREATE TABLE Backup_$db LIKE $db";
|
// backup table
|
||||||
DB::query($query);
|
$query = "CREATE TABLE Backup_$db LIKE $db";
|
||||||
echo "Populating Backup_$db <br />";
|
DB::query($query);
|
||||||
$query = "INSERT Backup_$db SELECT * FROM $db";
|
echo "Populating Backup_$db <br />";
|
||||||
DB::query($query);
|
$query = "INSERT Backup_$db SELECT * FROM $db";
|
||||||
$backedUp = 1;
|
DB::query($query);
|
||||||
}
|
$backedUp = 1;
|
||||||
if (!isset($columns[$column]) && !in_array($column, $this->keepColumns)) {
|
}
|
||||||
echo "Dropping $column from $db <br />";
|
if (!isset($columns[$column]) && !in_array($column, $this->keepColumns)) {
|
||||||
$query = "ALTER TABLE $db DROP COLUMN $column";
|
echo "Dropping $column from $db <br />";
|
||||||
DB::query($query);
|
$query = "ALTER TABLE $db DROP COLUMN $column";
|
||||||
}
|
DB::query($query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,216 +3,225 @@
|
|||||||
/**
|
/**
|
||||||
* Service to support upgrade of userforms module
|
* Service to support upgrade of userforms module
|
||||||
*/
|
*/
|
||||||
class UserFormsUpgradeService {
|
class UserFormsUpgradeService
|
||||||
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var bool
|
* @var bool
|
||||||
*/
|
*/
|
||||||
protected $quiet;
|
protected $quiet;
|
||||||
|
|
||||||
public function run() {
|
public function run()
|
||||||
$this->log("Upgrading formfield rules and custom settings");
|
{
|
||||||
|
$this->log("Upgrading formfield rules and custom settings");
|
||||||
|
|
||||||
// List of rules that have been created in all stages
|
// List of rules that have been created in all stages
|
||||||
$fields = Versioned::get_including_deleted('EditableFormField');
|
$fields = Versioned::get_including_deleted('EditableFormField');
|
||||||
foreach($fields as $field) {
|
foreach ($fields as $field) {
|
||||||
$this->upgradeField($field);
|
$this->upgradeField($field);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Migrate a versioned field in all stages
|
* Migrate a versioned field in all stages
|
||||||
*
|
*
|
||||||
* @param EditableFormField $field
|
* @param EditableFormField $field
|
||||||
*/
|
*/
|
||||||
protected function upgradeField(EditableFormField $field) {
|
protected function upgradeField(EditableFormField $field)
|
||||||
$this->log("Upgrading formfield ID = ".$field->ID);
|
{
|
||||||
|
$this->log("Upgrading formfield ID = ".$field->ID);
|
||||||
|
|
||||||
// Check versions this field exists on
|
// Check versions this field exists on
|
||||||
$filter = sprintf('"EditableFormField"."ID" = \'%d\' AND "Migrated" = 0', $field->ID);
|
$filter = sprintf('"EditableFormField"."ID" = \'%d\' AND "Migrated" = 0', $field->ID);
|
||||||
$stageField = Versioned::get_one_by_stage('EditableFormField', 'Stage', $filter);
|
$stageField = Versioned::get_one_by_stage('EditableFormField', 'Stage', $filter);
|
||||||
$liveField = Versioned::get_one_by_stage('EditableFormField', 'Live', $filter);
|
$liveField = Versioned::get_one_by_stage('EditableFormField', 'Live', $filter);
|
||||||
|
|
||||||
if($stageField) {
|
if ($stageField) {
|
||||||
$this->upgradeFieldInStage($stageField, 'Stage');
|
$this->upgradeFieldInStage($stageField, 'Stage');
|
||||||
}
|
}
|
||||||
|
|
||||||
if($liveField) {
|
if ($liveField) {
|
||||||
$this->upgradeFieldInStage($liveField, 'Live');
|
$this->upgradeFieldInStage($liveField, 'Live');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Migrate a versioned field in a single stage
|
* Migrate a versioned field in a single stage
|
||||||
*
|
*
|
||||||
* @param EditableFormField $field
|
* @param EditableFormField $field
|
||||||
* @param stage $stage
|
* @param stage $stage
|
||||||
*/
|
*/
|
||||||
protected function upgradeFieldInStage(EditableFormField $field, $stage) {
|
protected function upgradeFieldInStage(EditableFormField $field, $stage)
|
||||||
Versioned::reading_stage($stage);
|
{
|
||||||
|
Versioned::reading_stage($stage);
|
||||||
|
|
||||||
// Migrate field rules
|
// Migrate field rules
|
||||||
$this->migrateRules($field, $stage);
|
$this->migrateRules($field, $stage);
|
||||||
|
|
||||||
// Migrate custom settings
|
// Migrate custom settings
|
||||||
$this->migrateCustomSettings($field, $stage);
|
$this->migrateCustomSettings($field, $stage);
|
||||||
|
|
||||||
// Flag as migrated
|
// Flag as migrated
|
||||||
$field->Migrated = true;
|
$field->Migrated = true;
|
||||||
$field->write();
|
$field->write();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Migrate custom rules for the given field
|
* Migrate custom rules for the given field
|
||||||
*
|
*
|
||||||
* @param EditableFormField $field
|
* @param EditableFormField $field
|
||||||
* @param string $stage
|
* @param string $stage
|
||||||
*/
|
*/
|
||||||
protected function migrateRules(EditableFormField $field, $stage) {
|
protected function migrateRules(EditableFormField $field, $stage)
|
||||||
$rulesData = $field->CustomRules
|
{
|
||||||
? unserialize($field->CustomRules)
|
$rulesData = $field->CustomRules
|
||||||
: array();
|
? unserialize($field->CustomRules)
|
||||||
|
: array();
|
||||||
|
|
||||||
// Skip blank rules or fields with custom rules already
|
// Skip blank rules or fields with custom rules already
|
||||||
if(empty($rulesData) || $field->DisplayRules()->count()) {
|
if (empty($rulesData) || $field->DisplayRules()->count()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check value of this condition
|
// Check value of this condition
|
||||||
foreach($rulesData as $ruleDataItem) {
|
foreach ($rulesData as $ruleDataItem) {
|
||||||
if(empty($ruleDataItem['ConditionOption']) || empty($ruleDataItem['Display'])) {
|
if (empty($ruleDataItem['ConditionOption']) || empty($ruleDataItem['Display'])) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get data for this rule
|
// Get data for this rule
|
||||||
$conditionOption = $ruleDataItem['ConditionOption'];
|
$conditionOption = $ruleDataItem['ConditionOption'];
|
||||||
$display = $ruleDataItem['Display'];
|
$display = $ruleDataItem['Display'];
|
||||||
$conditionFieldName = empty($ruleDataItem['ConditionField']) ? null : $ruleDataItem['ConditionField'];
|
$conditionFieldName = empty($ruleDataItem['ConditionField']) ? null : $ruleDataItem['ConditionField'];
|
||||||
$value = isset($ruleDataItem['Value'])
|
$value = isset($ruleDataItem['Value'])
|
||||||
? $ruleDataItem['Value']
|
? $ruleDataItem['Value']
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
// Create rule
|
// Create rule
|
||||||
$rule = $this->findOrCreateRule($field, $stage, $conditionOption, $display, $conditionFieldName, $value);
|
$rule = $this->findOrCreateRule($field, $stage, $conditionOption, $display, $conditionFieldName, $value);
|
||||||
$this->log("Upgrading rule ID = " . $rule->ID);
|
$this->log("Upgrading rule ID = " . $rule->ID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Migrate custom settings for the given field
|
* Migrate custom settings for the given field
|
||||||
*
|
*
|
||||||
* @param EditableFormField $field
|
* @param EditableFormField $field
|
||||||
* @param string $stage
|
* @param string $stage
|
||||||
*/
|
*/
|
||||||
protected function migrateCustomSettings(EditableFormField $field, $stage) {
|
protected function migrateCustomSettings(EditableFormField $field, $stage)
|
||||||
// Custom settings include:
|
{
|
||||||
// - ExtraClass
|
// Custom settings include:
|
||||||
// - RightTitle
|
// - ExtraClass
|
||||||
// - ShowOnLoad (show or '' are treated as true)
|
// - RightTitle
|
||||||
//
|
// - ShowOnLoad (show or '' are treated as true)
|
||||||
// - CheckedDefault (new field on EditableCheckbox - should be read from old "default" value)
|
//
|
||||||
// - Default (EditableCheckbox)
|
// - CheckedDefault (new field on EditableCheckbox - should be read from old "default" value)
|
||||||
// - DefaultToToday (EditableDateField)
|
// - Default (EditableCheckbox)
|
||||||
// - Folder (EditableFileField)
|
// - DefaultToToday (EditableDateField)
|
||||||
// - Level (EditableFormHeading)
|
// - Folder (EditableFileField)
|
||||||
// - HideFromReports (EditableFormHeading / EditableLiteralField)
|
// - Level (EditableFormHeading)
|
||||||
// - Content (EditableLiteralField)
|
// - HideFromReports (EditableFormHeading / EditableLiteralField)
|
||||||
// - GroupID (EditableMemberListField)
|
// - Content (EditableLiteralField)
|
||||||
// - MinValue (EditableNumericField)
|
// - GroupID (EditableMemberListField)
|
||||||
// - MaxValue (EditableNumericField)
|
// - MinValue (EditableNumericField)
|
||||||
// - MinLength (EditableTextField)
|
// - MaxValue (EditableNumericField)
|
||||||
// - MaxLength (EditableTextField)
|
// - MinLength (EditableTextField)
|
||||||
// - Rows (EditableTextField)
|
// - MaxLength (EditableTextField)
|
||||||
|
// - Rows (EditableTextField)
|
||||||
|
|
||||||
$customSettings = $field->CustomSettings
|
$customSettings = $field->CustomSettings
|
||||||
? unserialize($field->CustomSettings)
|
? unserialize($field->CustomSettings)
|
||||||
: array();
|
: array();
|
||||||
|
|
||||||
// Skip blank rules or fields with custom rules already
|
// Skip blank rules or fields with custom rules already
|
||||||
if(empty($customSettings)) {
|
if (empty($customSettings)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$field->migrateSettings($customSettings);
|
$field->migrateSettings($customSettings);
|
||||||
$field->write();
|
$field->write();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create or find an existing field with the matched specification
|
* Create or find an existing field with the matched specification
|
||||||
*
|
*
|
||||||
* @param EditableFormField $field
|
* @param EditableFormField $field
|
||||||
* @param string $stage
|
* @param string $stage
|
||||||
* @param string $conditionOption
|
* @param string $conditionOption
|
||||||
* @param string $display
|
* @param string $display
|
||||||
* @param string $conditionFieldName
|
* @param string $conditionFieldName
|
||||||
* @param string $value
|
* @param string $value
|
||||||
* @return EditableCustomRule
|
* @return EditableCustomRule
|
||||||
*/
|
*/
|
||||||
protected function findOrCreateRule(EditableFormField $field, $stage, $conditionOption, $display, $conditionFieldName, $value) {
|
protected function findOrCreateRule(EditableFormField $field, $stage, $conditionOption, $display, $conditionFieldName, $value)
|
||||||
// Get id of field
|
{
|
||||||
$conditionField = $conditionFieldName
|
// Get id of field
|
||||||
? EditableFormField::get()->filter('Name', $conditionFieldName)->first()
|
$conditionField = $conditionFieldName
|
||||||
: null;
|
? EditableFormField::get()->filter('Name', $conditionFieldName)->first()
|
||||||
|
: null;
|
||||||
|
|
||||||
// If live, search stage record for matching one
|
// If live, search stage record for matching one
|
||||||
if($stage === 'Live') {
|
if ($stage === 'Live') {
|
||||||
$list = Versioned::get_by_stage('EditableCustomRule', 'Stage')
|
$list = Versioned::get_by_stage('EditableCustomRule', 'Stage')
|
||||||
->filter(array(
|
->filter(array(
|
||||||
'ParentID' => $field->ID,
|
'ParentID' => $field->ID,
|
||||||
'ConditionFieldID' => $conditionField ? $conditionField->ID : 0,
|
'ConditionFieldID' => $conditionField ? $conditionField->ID : 0,
|
||||||
'Display' => $display,
|
'Display' => $display,
|
||||||
'ConditionOption' => $conditionOption
|
'ConditionOption' => $conditionOption
|
||||||
));
|
));
|
||||||
if($value) {
|
if ($value) {
|
||||||
$list = $list->filter('FieldValue', $value);
|
$list = $list->filter('FieldValue', $value);
|
||||||
} else {
|
} else {
|
||||||
$list = $list->where('"FieldValue" IS NULL OR "FieldValue" = \'\'');
|
$list = $list->where('"FieldValue" IS NULL OR "FieldValue" = \'\'');
|
||||||
}
|
}
|
||||||
$rule = $list->first();
|
$rule = $list->first();
|
||||||
if($rule) {
|
if ($rule) {
|
||||||
$rule->write();
|
$rule->write();
|
||||||
$rule->publish("Stage", "Live");
|
$rule->publish("Stage", "Live");
|
||||||
return $rule;
|
return $rule;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If none found, or in stage, create new record
|
// If none found, or in stage, create new record
|
||||||
$rule = new EditableCustomRule();
|
$rule = new EditableCustomRule();
|
||||||
$rule->ParentID = $field->ID;
|
$rule->ParentID = $field->ID;
|
||||||
$rule->ConditionFieldID = $conditionField ? $conditionField->ID : 0;
|
$rule->ConditionFieldID = $conditionField ? $conditionField->ID : 0;
|
||||||
$rule->Display = $display;
|
$rule->Display = $display;
|
||||||
$rule->ConditionOption = $conditionOption;
|
$rule->ConditionOption = $conditionOption;
|
||||||
$rule->FieldValue = $value;
|
$rule->FieldValue = $value;
|
||||||
$rule->write();
|
$rule->write();
|
||||||
return $rule;
|
return $rule;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function log($message) {
|
public function log($message)
|
||||||
if($this->getQuiet()) {
|
{
|
||||||
return;
|
if ($this->getQuiet()) {
|
||||||
}
|
return;
|
||||||
if(Director::is_cli()) {
|
}
|
||||||
echo "{$message}\n";
|
if (Director::is_cli()) {
|
||||||
} else {
|
echo "{$message}\n";
|
||||||
echo "{$message}<br />";
|
} else {
|
||||||
}
|
echo "{$message}<br />";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set if this service should be quiet
|
* Set if this service should be quiet
|
||||||
*
|
*
|
||||||
* @param bool $quiet
|
* @param bool $quiet
|
||||||
* @return $ths
|
* @return $ths
|
||||||
*/
|
*/
|
||||||
public function setQuiet($quiet) {
|
public function setQuiet($quiet)
|
||||||
$this->quiet = $quiet;
|
{
|
||||||
return $this;
|
$this->quiet = $quiet;
|
||||||
}
|
return $this;
|
||||||
|
}
|
||||||
public function getQuiet() {
|
|
||||||
return $this->quiet;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public function getQuiet()
|
||||||
|
{
|
||||||
|
return $this->quiet;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,17 +5,19 @@
|
|||||||
*
|
*
|
||||||
* @author dmooyman
|
* @author dmooyman
|
||||||
*/
|
*/
|
||||||
class UserFormsUpgradeTask extends BuildTask {
|
class UserFormsUpgradeTask extends BuildTask
|
||||||
|
{
|
||||||
|
|
||||||
protected $title = "UserForms 3.0 Migration Tool";
|
protected $title = "UserForms 3.0 Migration Tool";
|
||||||
|
|
||||||
protected $description = "Upgrade tool for sites upgrading to userforms 3.0";
|
protected $description = "Upgrade tool for sites upgrading to userforms 3.0";
|
||||||
|
|
||||||
public function run($request) {
|
public function run($request)
|
||||||
$service = Injector::inst()->create('UserFormsUpgradeService');
|
{
|
||||||
$service->log("Upgrading userforms module");
|
$service = Injector::inst()->create('UserFormsUpgradeService');
|
||||||
$service->setQuiet(false)
|
$service->log("Upgrading userforms module");
|
||||||
->run();
|
$service->setQuiet(false)
|
||||||
$service->log("Done");
|
->run();
|
||||||
}
|
$service->log("Done");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,30 +10,29 @@
|
|||||||
* @package userforms
|
* @package userforms
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class UserFormsVersionedTask extends MigrationTask {
|
class UserFormsVersionedTask extends MigrationTask
|
||||||
|
{
|
||||||
|
|
||||||
protected $title = "UserForms Versioned Initial Migration";
|
protected $title = "UserForms Versioned Initial Migration";
|
||||||
|
|
||||||
protected $description = "Publishes the existing forms";
|
protected $description = "Publishes the existing forms";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Publish the existing forms.
|
* Publish the existing forms.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public function run($request) {
|
public function run($request)
|
||||||
$forms = Versioned::get_by_stage('UserDefinedForm', 'Live');
|
{
|
||||||
|
$forms = Versioned::get_by_stage('UserDefinedForm', 'Live');
|
||||||
|
|
||||||
if($forms) {
|
if ($forms) {
|
||||||
foreach($forms as $form) {
|
foreach ($forms as $form) {
|
||||||
echo "Publishing $form->Title <br />";
|
echo "Publishing $form->Title <br />";
|
||||||
$form->doPublish();
|
$form->doPublish();
|
||||||
}
|
}
|
||||||
echo "Complete";
|
echo "Complete";
|
||||||
}
|
} else {
|
||||||
else {
|
echo "No Forms Found";
|
||||||
echo "No Forms Found";
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,167 +4,178 @@
|
|||||||
* @package userforms
|
* @package userforms
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class EditableFormFieldTest extends FunctionalTest {
|
class EditableFormFieldTest extends FunctionalTest
|
||||||
|
{
|
||||||
|
|
||||||
static $fixture_file = 'userforms/tests/EditableFormFieldTest.yml';
|
public static $fixture_file = 'userforms/tests/EditableFormFieldTest.yml';
|
||||||
|
|
||||||
function testFormFieldPermissions() {
|
public function testFormFieldPermissions()
|
||||||
$text = $this->objFromFixture('EditableTextField', 'basic-text');
|
{
|
||||||
|
$text = $this->objFromFixture('EditableTextField', 'basic-text');
|
||||||
|
|
||||||
$this->logInWithPermission('ADMIN');
|
$this->logInWithPermission('ADMIN');
|
||||||
$this->assertTrue($text->canCreate());
|
$this->assertTrue($text->canCreate());
|
||||||
$this->assertTrue($text->canView());
|
$this->assertTrue($text->canView());
|
||||||
$this->assertTrue($text->canEdit());
|
$this->assertTrue($text->canEdit());
|
||||||
$this->assertTrue($text->canDelete());
|
$this->assertTrue($text->canDelete());
|
||||||
|
|
||||||
$text->setReadonly(true);
|
$text->setReadonly(true);
|
||||||
$this->assertTrue($text->canView());
|
$this->assertTrue($text->canView());
|
||||||
$this->assertFalse($text->canEdit());
|
$this->assertFalse($text->canEdit());
|
||||||
$this->assertFalse($text->canDelete());
|
$this->assertFalse($text->canDelete());
|
||||||
|
|
||||||
$text->setReadonly(false);
|
$text->setReadonly(false);
|
||||||
$this->assertTrue($text->canView());
|
$this->assertTrue($text->canView());
|
||||||
$this->assertTrue($text->canEdit());
|
$this->assertTrue($text->canEdit());
|
||||||
$this->assertTrue($text->canDelete());
|
$this->assertTrue($text->canDelete());
|
||||||
|
|
||||||
$member = Member::currentUser();
|
$member = Member::currentUser();
|
||||||
$member->logout();
|
$member->logout();
|
||||||
|
|
||||||
$this->logInWithPermission('SITETREE_VIEW_ALL');
|
$this->logInWithPermission('SITETREE_VIEW_ALL');
|
||||||
$this->assertFalse($text->canCreate());
|
$this->assertFalse($text->canCreate());
|
||||||
|
|
||||||
$text->setReadonly(false);
|
$text->setReadonly(false);
|
||||||
$this->assertTrue($text->canView());
|
$this->assertTrue($text->canView());
|
||||||
$this->assertFalse($text->canEdit());
|
$this->assertFalse($text->canEdit());
|
||||||
$this->assertFalse($text->canDelete());
|
$this->assertFalse($text->canDelete());
|
||||||
|
|
||||||
$text->setReadonly(true);
|
$text->setReadonly(true);
|
||||||
$this->assertTrue($text->canView());
|
$this->assertTrue($text->canView());
|
||||||
$this->assertFalse($text->canEdit());
|
$this->assertFalse($text->canEdit());
|
||||||
$this->assertFalse($text->canDelete());
|
$this->assertFalse($text->canDelete());
|
||||||
}
|
}
|
||||||
|
|
||||||
function testCustomRules() {
|
public function testCustomRules()
|
||||||
$this->logInWithPermission('ADMIN');
|
{
|
||||||
$form = $this->objFromFixture('UserDefinedForm', 'custom-rules-form');
|
$this->logInWithPermission('ADMIN');
|
||||||
|
$form = $this->objFromFixture('UserDefinedForm', 'custom-rules-form');
|
||||||
|
|
||||||
$checkbox = $form->Fields()->find('ClassName', 'EditableCheckbox');
|
$checkbox = $form->Fields()->find('ClassName', 'EditableCheckbox');
|
||||||
$field = $form->Fields()->find('ClassName', 'EditableTextField');
|
$field = $form->Fields()->find('ClassName', 'EditableTextField');
|
||||||
|
|
||||||
$rules = $checkbox->DisplayRules();
|
$rules = $checkbox->DisplayRules();
|
||||||
|
|
||||||
// form has 2 fields - a checkbox and a text field
|
// form has 2 fields - a checkbox and a text field
|
||||||
// it has 1 rule - when ticked the checkbox hides the text field
|
// it has 1 rule - when ticked the checkbox hides the text field
|
||||||
$this->assertEquals(1, $rules->Count());
|
$this->assertEquals(1, $rules->Count());
|
||||||
$this->assertEquals($rules, $checkbox->EffectiveDisplayRules());
|
$this->assertEquals($rules, $checkbox->EffectiveDisplayRules());
|
||||||
|
|
||||||
$checkboxRule = $rules->First();
|
$checkboxRule = $rules->First();
|
||||||
$checkboxRule->ConditionFieldID = $field->ID;
|
$checkboxRule->ConditionFieldID = $field->ID;
|
||||||
|
|
||||||
$this->assertEquals($checkboxRule->Display, 'Hide');
|
$this->assertEquals($checkboxRule->Display, 'Hide');
|
||||||
$this->assertEquals($checkboxRule->ConditionOption, 'HasValue');
|
$this->assertEquals($checkboxRule->ConditionOption, 'HasValue');
|
||||||
$this->assertEquals($checkboxRule->FieldValue, '6');
|
$this->assertEquals($checkboxRule->FieldValue, '6');
|
||||||
|
|
||||||
// If field is required then all custom rules are disabled
|
// If field is required then all custom rules are disabled
|
||||||
$checkbox->Required = true;
|
$checkbox->Required = true;
|
||||||
$this->assertEquals(0, $checkbox->EffectiveDisplayRules()->count());
|
$this->assertEquals(0, $checkbox->EffectiveDisplayRules()->count());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @covers EditableOption::getValue
|
* @covers EditableOption::getValue
|
||||||
*/
|
*/
|
||||||
public function testEditableOptionEmptyValue() {
|
public function testEditableOptionEmptyValue()
|
||||||
$option = $this->objFromFixture('EditableOption', 'option-1');
|
{
|
||||||
$option->Value = '';
|
$option = $this->objFromFixture('EditableOption', 'option-1');
|
||||||
|
$option->Value = '';
|
||||||
|
|
||||||
// Disallow empty values
|
// Disallow empty values
|
||||||
EditableOption::set_allow_empty_values(false);
|
EditableOption::set_allow_empty_values(false);
|
||||||
$this->assertEquals($option->Title, $option->Value);
|
$this->assertEquals($option->Title, $option->Value);
|
||||||
|
|
||||||
$option->Value = 'test';
|
$option->Value = 'test';
|
||||||
$this->assertEquals('test', $option->Value);
|
$this->assertEquals('test', $option->Value);
|
||||||
|
|
||||||
// Allow empty values
|
// Allow empty values
|
||||||
EditableOption::set_allow_empty_values(true);
|
EditableOption::set_allow_empty_values(true);
|
||||||
$option->Value = '';
|
$option->Value = '';
|
||||||
$this->assertEquals('', $option->Value);
|
$this->assertEquals('', $option->Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testEditableDropdownField() {
|
public function testEditableDropdownField()
|
||||||
$dropdown = $this->objFromFixture('EditableDropdown', 'basic-dropdown');
|
{
|
||||||
|
$dropdown = $this->objFromFixture('EditableDropdown', 'basic-dropdown');
|
||||||
|
|
||||||
$field = $dropdown->getFormField();
|
$field = $dropdown->getFormField();
|
||||||
|
|
||||||
|
|
||||||
$this->assertThat($field, $this->isInstanceOf('DropdownField'));
|
$this->assertThat($field, $this->isInstanceOf('DropdownField'));
|
||||||
$values = $field->getSource();
|
$values = $field->getSource();
|
||||||
|
|
||||||
$this->assertEquals(array('Option 1' => 'Option 1', 'Option 2' => 'Option 2'), $values);
|
$this->assertEquals(array('Option 1' => 'Option 1', 'Option 2' => 'Option 2'), $values);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testEditableRadioField() {
|
public function testEditableRadioField()
|
||||||
$radio = $this->objFromFixture('EditableRadioField', 'radio-field');
|
{
|
||||||
|
$radio = $this->objFromFixture('EditableRadioField', 'radio-field');
|
||||||
|
|
||||||
$field = $radio->getFormField();
|
$field = $radio->getFormField();
|
||||||
|
|
||||||
$this->assertThat($field, $this->isInstanceOf('OptionsetField'));
|
$this->assertThat($field, $this->isInstanceOf('OptionsetField'));
|
||||||
$values = $field->getSource();
|
$values = $field->getSource();
|
||||||
|
|
||||||
$this->assertEquals(array('Option 5' => 'Option 5', 'Option 6' => 'Option 6'), $values);
|
$this->assertEquals(array('Option 5' => 'Option 5', 'Option 6' => 'Option 6'), $values);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testMultipleOptionDuplication() {
|
public function testMultipleOptionDuplication()
|
||||||
$dropdown = $this->objFromFixture('EditableDropdown','basic-dropdown');
|
{
|
||||||
|
$dropdown = $this->objFromFixture('EditableDropdown', 'basic-dropdown');
|
||||||
|
|
||||||
$clone = $dropdown->duplicate();
|
$clone = $dropdown->duplicate();
|
||||||
|
|
||||||
$this->assertEquals($clone->Options()->Count(), $dropdown->Options()->Count());
|
$this->assertEquals($clone->Options()->Count(), $dropdown->Options()->Count());
|
||||||
|
|
||||||
foreach($clone->Options() as $option) {
|
foreach ($clone->Options() as $option) {
|
||||||
$orginal = $dropdown->Options()->find('Title', $option->Title);
|
$orginal = $dropdown->Options()->find('Title', $option->Title);
|
||||||
|
|
||||||
$this->assertEquals($orginal->Sort, $option->Sort);
|
$this->assertEquals($orginal->Sort, $option->Sort);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testFileField() {
|
public function testFileField()
|
||||||
$fileField = $this->objFromFixture('EditableFileField', 'file-field');
|
{
|
||||||
$formField = $fileField->getFormField();
|
$fileField = $this->objFromFixture('EditableFileField', 'file-field');
|
||||||
|
$formField = $fileField->getFormField();
|
||||||
|
|
||||||
$this->assertContains('jpg', $formField->getValidator()->getAllowedExtensions());
|
$this->assertContains('jpg', $formField->getValidator()->getAllowedExtensions());
|
||||||
$this->assertNotContains('notallowedextension', $formField->getValidator()->getAllowedExtensions());
|
$this->assertNotContains('notallowedextension', $formField->getValidator()->getAllowedExtensions());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testFileFieldAllowedExtensionsBlacklist() {
|
public function testFileFieldAllowedExtensionsBlacklist()
|
||||||
Config::inst()->update('EditableFileField', 'allowed_extensions_blacklist', array('jpg'));
|
{
|
||||||
$fileField = $this->objFromFixture('EditableFileField', 'file-field');
|
Config::inst()->update('EditableFileField', 'allowed_extensions_blacklist', array('jpg'));
|
||||||
$formField = $fileField->getFormField();
|
$fileField = $this->objFromFixture('EditableFileField', 'file-field');
|
||||||
|
$formField = $fileField->getFormField();
|
||||||
|
|
||||||
$this->assertNotContains('jpg', $formField->getValidator()->getAllowedExtensions());
|
$this->assertNotContains('jpg', $formField->getValidator()->getAllowedExtensions());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify that unique names are automatically generated for each formfield
|
* Verify that unique names are automatically generated for each formfield
|
||||||
*/
|
*/
|
||||||
public function testUniqueName() {
|
public function testUniqueName()
|
||||||
$textfield1 = new EditableTextField();
|
{
|
||||||
$this->assertEmpty($textfield1->Name);
|
$textfield1 = new EditableTextField();
|
||||||
|
$this->assertEmpty($textfield1->Name);
|
||||||
|
|
||||||
// Write values
|
// Write values
|
||||||
$textfield1->write();
|
$textfield1->write();
|
||||||
$textfield2 = new EditableTextField();
|
$textfield2 = new EditableTextField();
|
||||||
$textfield2->write();
|
$textfield2->write();
|
||||||
$checkboxField = new EditableCheckbox();
|
$checkboxField = new EditableCheckbox();
|
||||||
$checkboxField->write();
|
$checkboxField->write();
|
||||||
|
|
||||||
// Test values are in the expected format
|
// Test values are in the expected format
|
||||||
$this->assertRegExp('/^EditableTextField_.+/', $textfield1->Name);
|
$this->assertRegExp('/^EditableTextField_.+/', $textfield1->Name);
|
||||||
$this->assertRegExp('/^EditableTextField_.+/', $textfield2->Name);
|
$this->assertRegExp('/^EditableTextField_.+/', $textfield2->Name);
|
||||||
$this->assertRegExp('/^EditableCheckbox_.+/', $checkboxField->Name);
|
$this->assertRegExp('/^EditableCheckbox_.+/', $checkboxField->Name);
|
||||||
$this->assertNotEquals($textfield1->Name, $textfield2->Name);
|
$this->assertNotEquals($textfield1->Name, $textfield2->Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testLengthRange() {
|
public function testLengthRange()
|
||||||
|
{
|
||||||
/** @var EditableTextField $textField */
|
/** @var EditableTextField $textField */
|
||||||
$textField = $this->objFromFixture('EditableTextField', 'basic-text');
|
$textField = $this->objFromFixture('EditableTextField', 'basic-text');
|
||||||
|
|
||||||
@ -193,6 +204,4 @@ class EditableFormFieldTest extends FunctionalTest {
|
|||||||
$this->assertEquals(10, $attributes['data-rule-minlength']);
|
$this->assertEquals(10, $attributes['data-rule-minlength']);
|
||||||
$this->assertEquals(20, $attributes['data-rule-maxlength']);
|
$this->assertEquals(20, $attributes['data-rule-maxlength']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,40 +3,44 @@
|
|||||||
/**
|
/**
|
||||||
* Tests the {@see EditableLiteralField} class
|
* Tests the {@see EditableLiteralField} class
|
||||||
*/
|
*/
|
||||||
class EditableLiteralFieldTest extends SapphireTest {
|
class EditableLiteralFieldTest extends SapphireTest
|
||||||
|
{
|
||||||
|
|
||||||
public function setUp() {
|
public function setUp()
|
||||||
parent::setUp();
|
{
|
||||||
HtmlEditorConfig::set_active('cms');
|
parent::setUp();
|
||||||
}
|
HtmlEditorConfig::set_active('cms');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests the sanitisation of HTML content
|
* Tests the sanitisation of HTML content
|
||||||
*/
|
*/
|
||||||
public function testSanitisation() {
|
public function testSanitisation()
|
||||||
$rawContent = '<h1>Welcome</h1><script>alert("Hello!");</script><p>Giant Robots!</p>';
|
{
|
||||||
$safeContent = '<h1>Welcome</h1><p>Giant Robots!</p>';
|
$rawContent = '<h1>Welcome</h1><script>alert("Hello!");</script><p>Giant Robots!</p>';
|
||||||
$field = new EditableLiteralField();
|
$safeContent = '<h1>Welcome</h1><p>Giant Robots!</p>';
|
||||||
|
$field = new EditableLiteralField();
|
||||||
|
|
||||||
// Test with sanitisation enabled
|
// Test with sanitisation enabled
|
||||||
Config::inst()->update('HtmlEditorField', 'sanitise_server_side', true);
|
Config::inst()->update('HtmlEditorField', 'sanitise_server_side', true);
|
||||||
$field->setContent($rawContent);
|
$field->setContent($rawContent);
|
||||||
$this->assertEquals($safeContent, $field->getContent());
|
$this->assertEquals($safeContent, $field->getContent());
|
||||||
|
|
||||||
// Test with sanitisation disabled
|
// Test with sanitisation disabled
|
||||||
Config::inst()->remove('HtmlEditorField', 'sanitise_server_side');
|
Config::inst()->remove('HtmlEditorField', 'sanitise_server_side');
|
||||||
$field->setContent($rawContent);
|
$field->setContent($rawContent);
|
||||||
$this->assertEquals($rawContent, $field->getContent());
|
$this->assertEquals($rawContent, $field->getContent());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testHideLabel() {
|
public function testHideLabel()
|
||||||
$field = new EditableLiteralField(array(
|
{
|
||||||
'Title' => 'Test label'
|
$field = new EditableLiteralField(array(
|
||||||
));
|
'Title' => 'Test label'
|
||||||
|
));
|
||||||
|
|
||||||
$this->assertContains('Test label', $field->getFormField()->Field());
|
$this->assertContains('Test label', $field->getFormField()->Field());
|
||||||
|
|
||||||
$field->HideLabel = true;
|
$field->HideLabel = true;
|
||||||
$this->assertNotContains('Test label', $field->getFormField()->Field());
|
$this->assertNotContains('Test label', $field->getFormField()->Field());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,79 +5,85 @@
|
|||||||
*
|
*
|
||||||
* @author dmooyman
|
* @author dmooyman
|
||||||
*/
|
*/
|
||||||
class SecureEditableFileFieldTest extends SapphireTest {
|
class SecureEditableFileFieldTest extends SapphireTest
|
||||||
|
{
|
||||||
|
|
||||||
protected $usesDatabase = true;
|
protected $usesDatabase = true;
|
||||||
|
|
||||||
public function setUp() {
|
public function setUp()
|
||||||
parent::setUp();
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
if(!class_exists('SecureFileExtension')) {
|
if (!class_exists('SecureFileExtension')) {
|
||||||
$this->skipTest = true;
|
$this->skipTest = true;
|
||||||
$this->markTestSkipped(get_class() . ' skipped unless running with securefiles');
|
$this->markTestSkipped(get_class() . ' skipped unless running with securefiles');
|
||||||
}
|
}
|
||||||
Config::inst()->update('EditableFileField', 'secure_folder_name', 'SecureEditableFileFieldTest/SecureUploads');
|
Config::inst()->update('EditableFileField', 'secure_folder_name', 'SecureEditableFileFieldTest/SecureUploads');
|
||||||
$this->clearPath();
|
$this->clearPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function tearDown() {
|
public function tearDown()
|
||||||
$this->clearPath();
|
{
|
||||||
parent::tearDown();
|
$this->clearPath();
|
||||||
}
|
parent::tearDown();
|
||||||
|
}
|
||||||
|
|
||||||
protected function clearPath() {
|
protected function clearPath()
|
||||||
if(file_exists(ASSETS_PATH . '/SecureEditableFileFieldTest')) {
|
{
|
||||||
Filesystem::removeFolder(ASSETS_PATH . '/SecureEditableFileFieldTest');
|
if (file_exists(ASSETS_PATH . '/SecureEditableFileFieldTest')) {
|
||||||
}
|
Filesystem::removeFolder(ASSETS_PATH . '/SecureEditableFileFieldTest');
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test that newly created folders are secure
|
* Test that newly created folders are secure
|
||||||
*/
|
*/
|
||||||
public function testCreateFolder() {
|
public function testCreateFolder()
|
||||||
$field = new EditableFileField();
|
{
|
||||||
$field->write();
|
$field = new EditableFileField();
|
||||||
$this->assertTrue($field->getIsSecure());
|
$field->write();
|
||||||
$this->assertTrue($field->Folder()->exists());
|
$this->assertTrue($field->getIsSecure());
|
||||||
$this->assertEquals('assets/SecureEditableFileFieldTest/SecureUploads/', $field->Folder()->Filename);
|
$this->assertTrue($field->Folder()->exists());
|
||||||
$this->assertEquals('OnlyTheseUsers', $field->Folder()->CanViewType);
|
$this->assertEquals('assets/SecureEditableFileFieldTest/SecureUploads/', $field->Folder()->Filename);
|
||||||
$this->assertEquals(1, $field->Folder()->ViewerGroups()->first()->Permissions()->filter('code', 'ADMIN')->count());
|
$this->assertEquals('OnlyTheseUsers', $field->Folder()->CanViewType);
|
||||||
}
|
$this->assertEquals(1, $field->Folder()->ViewerGroups()->first()->Permissions()->filter('code', 'ADMIN')->count());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test new folders that are created without security enabled
|
* Test new folders that are created without security enabled
|
||||||
*/
|
*/
|
||||||
public function testCreateInsecure() {
|
public function testCreateInsecure()
|
||||||
Config::inst()->update('EditableFileField', 'disable_security', true);
|
{
|
||||||
|
Config::inst()->update('EditableFileField', 'disable_security', true);
|
||||||
|
|
||||||
// Esure folder is created without a folder
|
// Esure folder is created without a folder
|
||||||
$field = new EditableFileField();
|
$field = new EditableFileField();
|
||||||
$field->write();
|
$field->write();
|
||||||
$this->assertFalse($field->getIsSecure());
|
$this->assertFalse($field->getIsSecure());
|
||||||
$this->assertFalse($field->Folder()->exists());
|
$this->assertFalse($field->Folder()->exists());
|
||||||
|
|
||||||
// Assigning a non-secure folder doesn't secure this
|
// Assigning a non-secure folder doesn't secure this
|
||||||
$folder = Folder::find_or_make('SecureEditableFileFieldTest/PublicFolder');
|
$folder = Folder::find_or_make('SecureEditableFileFieldTest/PublicFolder');
|
||||||
$field->FolderID = $folder->ID;
|
$field->FolderID = $folder->ID;
|
||||||
$field->write();
|
$field->write();
|
||||||
|
|
||||||
$this->assertFalse($field->getIsSecure());
|
$this->assertFalse($field->getIsSecure());
|
||||||
$this->assertTrue($field->Folder()->exists());
|
$this->assertTrue($field->Folder()->exists());
|
||||||
$this->assertEquals('assets/SecureEditableFileFieldTest/PublicFolder/', $field->Folder()->Filename);
|
$this->assertEquals('assets/SecureEditableFileFieldTest/PublicFolder/', $field->Folder()->Filename);
|
||||||
$this->assertEquals('Inherit', $field->Folder()->CanViewType);
|
$this->assertEquals('Inherit', $field->Folder()->CanViewType);
|
||||||
|
|
||||||
// Enabling security and re-saving will force this field to be made secure (but not changed)
|
// Enabling security and re-saving will force this field to be made secure (but not changed)
|
||||||
Config::inst()->update('EditableFileField', 'disable_security', false);
|
Config::inst()->update('EditableFileField', 'disable_security', false);
|
||||||
singleton('EditableFileField')->requireDefaultRecords();
|
singleton('EditableFileField')->requireDefaultRecords();
|
||||||
|
|
||||||
// Reload record from DB
|
// Reload record from DB
|
||||||
$field = EditableFileField::get()->byID($field->ID);
|
$field = EditableFileField::get()->byID($field->ID);
|
||||||
|
|
||||||
// Existing folder is now secured (retro-actively secures any old uploads)
|
// Existing folder is now secured (retro-actively secures any old uploads)
|
||||||
$this->assertTrue($field->getIsSecure());
|
$this->assertTrue($field->getIsSecure());
|
||||||
$this->assertTrue($field->Folder()->exists());
|
$this->assertTrue($field->Folder()->exists());
|
||||||
$this->assertEquals('assets/SecureEditableFileFieldTest/PublicFolder/', $field->Folder()->Filename);
|
$this->assertEquals('assets/SecureEditableFileFieldTest/PublicFolder/', $field->Folder()->Filename);
|
||||||
$this->assertEquals('OnlyTheseUsers', $field->Folder()->CanViewType);
|
$this->assertEquals('OnlyTheseUsers', $field->Folder()->CanViewType);
|
||||||
$this->assertEquals(1, $field->Folder()->ViewerGroups()->first()->Permissions()->filter('code', 'ADMIN')->count());
|
$this->assertEquals(1, $field->Folder()->ViewerGroups()->first()->Permissions()->filter('code', 'ADMIN')->count());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,282 +4,296 @@
|
|||||||
* @package userforms
|
* @package userforms
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class UserDefinedFormControllerTest extends FunctionalTest {
|
class UserDefinedFormControllerTest extends FunctionalTest
|
||||||
|
{
|
||||||
|
|
||||||
static $fixture_file = 'UserDefinedFormTest.yml';
|
public static $fixture_file = 'UserDefinedFormTest.yml';
|
||||||
|
|
||||||
public function testProcess() {
|
public function testProcess()
|
||||||
$form = $this->setupFormFrontend();
|
{
|
||||||
|
$form = $this->setupFormFrontend();
|
||||||
|
|
||||||
$controller = new UserDefinedFormControllerTest_Controller($form);
|
$controller = new UserDefinedFormControllerTest_Controller($form);
|
||||||
|
|
||||||
$this->autoFollowRedirection = false;
|
$this->autoFollowRedirection = false;
|
||||||
$this->clearEmails();
|
$this->clearEmails();
|
||||||
|
|
||||||
// load the form
|
// load the form
|
||||||
$this->get($form->URLSegment);
|
$this->get($form->URLSegment);
|
||||||
|
|
||||||
$field = $this->objFromFixture('EditableTextField', 'basic-text');
|
$field = $this->objFromFixture('EditableTextField', 'basic-text');
|
||||||
|
|
||||||
$response = $this->submitForm('UserForm_Form', null, array($field->Name => 'Basic Value'));
|
$response = $this->submitForm('UserForm_Form', null, array($field->Name => 'Basic Value'));
|
||||||
|
|
||||||
// should have a submitted form field now
|
// should have a submitted form field now
|
||||||
$submitted = DataObject::get('SubmittedFormField', "\"Name\" = 'basic-text-name'");
|
$submitted = DataObject::get('SubmittedFormField', "\"Name\" = 'basic-text-name'");
|
||||||
$this->assertDOSAllMatch(array('Name' => 'basic-text-name', 'Value' => 'Basic Value', 'Title' => 'Basic Text Field'), $submitted);
|
$this->assertDOSAllMatch(array('Name' => 'basic-text-name', 'Value' => 'Basic Value', 'Title' => 'Basic Text Field'), $submitted);
|
||||||
|
|
||||||
// check emails
|
// check emails
|
||||||
$this->assertEmailSent('test@example.com', 'no-reply@example.com', 'Email Subject');
|
$this->assertEmailSent('test@example.com', 'no-reply@example.com', 'Email Subject');
|
||||||
$email = $this->findEmail('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
|
// assert that the email has the field title and the value html email
|
||||||
$parser = new CSSContentParser($email['content']);
|
$parser = new CSSContentParser($email['content']);
|
||||||
$title = $parser->getBySelector('strong');
|
$title = $parser->getBySelector('strong');
|
||||||
|
|
||||||
$this->assertEquals('Basic Text Field', (string) $title[0], 'Email contains the field name');
|
$this->assertEquals('Basic Text Field', (string) $title[0], 'Email contains the field name');
|
||||||
|
|
||||||
$value = $parser->getBySelector('dd');
|
$value = $parser->getBySelector('dd');
|
||||||
$this->assertEquals('Basic Value', (string) $value[0], 'Email contains the value');
|
$this->assertEquals('Basic Value', (string) $value[0], 'Email contains the value');
|
||||||
|
|
||||||
// no html
|
// no html
|
||||||
$this->assertEmailSent('nohtml@example.com', 'no-reply@example.com', 'Email Subject');
|
$this->assertEmailSent('nohtml@example.com', 'no-reply@example.com', 'Email Subject');
|
||||||
$nohtml = $this->findEmail('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');
|
$this->assertContains('Basic Text Field: Basic Value', $nohtml['content'], 'Email contains no html');
|
||||||
|
|
||||||
// no data
|
// no data
|
||||||
$this->assertEmailSent('nodata@example.com', 'no-reply@example.com', 'Email Subject');
|
$this->assertEmailSent('nodata@example.com', 'no-reply@example.com', 'Email Subject');
|
||||||
$nodata = $this->findEmail('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']);
|
$parser = new CSSContentParser($nodata['content']);
|
||||||
$list = $parser->getBySelector('dl');
|
$list = $parser->getBySelector('dl');
|
||||||
|
|
||||||
$this->assertFalse(isset($list[0]), 'Email contains no fields');
|
$this->assertFalse(isset($list[0]), 'Email contains no fields');
|
||||||
|
|
||||||
// check to see if the user was redirected (301)
|
// check to see if the user was redirected (301)
|
||||||
$this->assertEquals($response->getStatusCode(), 302);
|
$this->assertEquals($response->getStatusCode(), 302);
|
||||||
$this->assertStringEndsWith('finished#uff', $response->getHeader('Location'));
|
$this->assertStringEndsWith('finished#uff', $response->getHeader('Location'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testValidation() {
|
public function testValidation()
|
||||||
$form = $this->setupFormFrontend('email-form');
|
{
|
||||||
|
$form = $this->setupFormFrontend('email-form');
|
||||||
|
|
||||||
// Post with no fields
|
// Post with no fields
|
||||||
$this->get($form->URLSegment);
|
$this->get($form->URLSegment);
|
||||||
$response = $this->submitForm('UserForm_Form', null, array());
|
$response = $this->submitForm('UserForm_Form', null, array());
|
||||||
$this->assertPartialMatchBySelector(
|
$this->assertPartialMatchBySelector(
|
||||||
'.field .message',
|
'.field .message',
|
||||||
array('This field is required')
|
array('This field is required')
|
||||||
);
|
);
|
||||||
|
|
||||||
// Post with all fields, but invalid email
|
// Post with all fields, but invalid email
|
||||||
$this->get($form->URLSegment);
|
$this->get($form->URLSegment);
|
||||||
$this->submitForm('UserForm_Form', null, array(
|
$this->submitForm('UserForm_Form', null, array(
|
||||||
'required-email' => 'invalid',
|
'required-email' => 'invalid',
|
||||||
'required-text' => 'bob'
|
'required-text' => 'bob'
|
||||||
));
|
));
|
||||||
$this->assertPartialMatchBySelector(
|
$this->assertPartialMatchBySelector(
|
||||||
'.field .message',
|
'.field .message',
|
||||||
array('Please enter an email address')
|
array('Please enter an email address')
|
||||||
);
|
);
|
||||||
|
|
||||||
// Post with only required
|
// Post with only required
|
||||||
$this->get($form->URLSegment);
|
$this->get($form->URLSegment);
|
||||||
$this->submitForm('UserForm_Form', null, array(
|
$this->submitForm('UserForm_Form', null, array(
|
||||||
'required-text' => 'bob'
|
'required-text' => 'bob'
|
||||||
));
|
));
|
||||||
$this->assertPartialMatchBySelector(
|
$this->assertPartialMatchBySelector(
|
||||||
'p',
|
'p',
|
||||||
array("Thanks, we've received your submission.")
|
array("Thanks, we've received your submission.")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testFinished() {
|
public function testFinished()
|
||||||
$form = $this->setupFormFrontend();
|
{
|
||||||
|
$form = $this->setupFormFrontend();
|
||||||
|
|
||||||
// set formProcessed and SecurityID to replicate the form being filled out
|
// set formProcessed and SecurityID to replicate the form being filled out
|
||||||
$this->session()->inst_set('SecurityID', 1);
|
$this->session()->inst_set('SecurityID', 1);
|
||||||
$this->session()->inst_set('FormProcessed', 1);
|
$this->session()->inst_set('FormProcessed', 1);
|
||||||
|
|
||||||
$response = $this->get($form->URLSegment.'/finished');
|
$response = $this->get($form->URLSegment.'/finished');
|
||||||
|
|
||||||
$this->assertContains($form->OnCompleteMessage ,$response->getBody());
|
$this->assertContains($form->OnCompleteMessage, $response->getBody());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testAppendingFinished() {
|
public function testAppendingFinished()
|
||||||
$form = $this->setupFormFrontend();
|
{
|
||||||
|
$form = $this->setupFormFrontend();
|
||||||
|
|
||||||
// replicate finished being added to the end of the form URL without the form being filled out
|
// replicate finished being added to the end of the form URL without the form being filled out
|
||||||
$this->session()->inst_set('SecurityID', 1);
|
$this->session()->inst_set('SecurityID', 1);
|
||||||
$this->session()->inst_set('FormProcessed', null);
|
$this->session()->inst_set('FormProcessed', null);
|
||||||
|
|
||||||
$response = $this->get($form->URLSegment.'/finished');
|
$response = $this->get($form->URLSegment.'/finished');
|
||||||
|
|
||||||
$this->assertNotContains($form->OnCompleteMessage ,$response->getBody());
|
$this->assertNotContains($form->OnCompleteMessage, $response->getBody());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testForm() {
|
public function testForm()
|
||||||
$form = $this->objFromFixture('UserDefinedForm', 'basic-form-page');
|
{
|
||||||
|
$form = $this->objFromFixture('UserDefinedForm', 'basic-form-page');
|
||||||
|
|
||||||
$controller = new UserDefinedFormControllerTest_Controller($form);
|
$controller = new UserDefinedFormControllerTest_Controller($form);
|
||||||
|
|
||||||
// test form
|
// test form
|
||||||
$this->assertEquals($controller->Form()->getName(), 'Form', 'The form is referenced as Form');
|
$this->assertEquals($controller->Form()->getName(), 'Form', 'The form is referenced as Form');
|
||||||
$this->assertEquals($controller->Form()->Fields()->Count(), 1); // disabled SecurityID token fields
|
$this->assertEquals($controller->Form()->Fields()->Count(), 1); // disabled SecurityID token fields
|
||||||
$this->assertEquals($controller->Form()->Actions()->Count(), 1);
|
$this->assertEquals($controller->Form()->Actions()->Count(), 1);
|
||||||
$this->assertEquals(count($controller->Form()->getValidator()->getRequired()), 0);
|
$this->assertEquals(count($controller->Form()->getValidator()->getRequired()), 0);
|
||||||
|
|
||||||
$requiredForm = $this->objFromFixture('UserDefinedForm', 'validation-form');
|
$requiredForm = $this->objFromFixture('UserDefinedForm', 'validation-form');
|
||||||
$controller = new UserDefinedFormControllerTest_Controller($requiredForm);
|
$controller = new UserDefinedFormControllerTest_Controller($requiredForm);
|
||||||
|
|
||||||
$this->assertEquals($controller->Form()->Fields()->Count(), 1); // disabled SecurityID token fields
|
$this->assertEquals($controller->Form()->Fields()->Count(), 1); // disabled SecurityID token fields
|
||||||
$this->assertEquals($controller->Form()->Actions()->Count(), 1);
|
$this->assertEquals($controller->Form()->Actions()->Count(), 1);
|
||||||
$this->assertEquals(count($controller->Form()->getValidator()->getRequired()), 1);
|
$this->assertEquals(count($controller->Form()->getValidator()->getRequired()), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGetFormFields() {
|
public function testGetFormFields()
|
||||||
// generating the fieldset of fields
|
{
|
||||||
$form = $this->objFromFixture('UserDefinedForm', 'basic-form-page');
|
// generating the fieldset of fields
|
||||||
|
$form = $this->objFromFixture('UserDefinedForm', 'basic-form-page');
|
||||||
|
|
||||||
$controller = new UserDefinedFormControllerTest_Controller($form);
|
$controller = new UserDefinedFormControllerTest_Controller($form);
|
||||||
|
|
||||||
|
$formSteps = $controller->Form()->getFormFields();
|
||||||
|
$firstStep = $formSteps->first();
|
||||||
|
|
||||||
$formSteps = $controller->Form()->getFormFields();
|
$this->assertEquals($formSteps->Count(), 1);
|
||||||
$firstStep = $formSteps->first();
|
$this->assertEquals($firstStep->getChildren()->Count(), 1);
|
||||||
|
|
||||||
$this->assertEquals($formSteps->Count(), 1);
|
// custom error message on a form field
|
||||||
$this->assertEquals($firstStep->getChildren()->Count(), 1);
|
$requiredForm = $this->objFromFixture('UserDefinedForm', 'validation-form');
|
||||||
|
$controller = new UserDefinedFormControllerTest_Controller($requiredForm);
|
||||||
|
|
||||||
// custom error message on a form field
|
UserDefinedForm::config()->required_identifier = "*";
|
||||||
$requiredForm = $this->objFromFixture('UserDefinedForm', 'validation-form');
|
|
||||||
$controller = new UserDefinedFormControllerTest_Controller($requiredForm);
|
|
||||||
|
|
||||||
UserDefinedForm::config()->required_identifier = "*";
|
$formSteps = $controller->Form()->getFormFields();
|
||||||
|
$firstStep = $formSteps->first();
|
||||||
|
$firstField = $firstStep->getChildren()->first();
|
||||||
|
|
||||||
$formSteps = $controller->Form()->getFormFields();
|
$this->assertEquals('Custom Error Message', $firstField->getCustomValidationMessage());
|
||||||
$firstStep = $formSteps->first();
|
$this->assertEquals($firstField->Title(), 'Required Text Field <span class=\'required-identifier\'>*</span>');
|
||||||
$firstField = $firstStep->getChildren()->first();
|
|
||||||
|
|
||||||
$this->assertEquals('Custom Error Message', $firstField->getCustomValidationMessage());
|
// test custom right title
|
||||||
$this->assertEquals($firstField->Title(), 'Required Text Field <span class=\'required-identifier\'>*</span>');
|
$field = $form->Fields()->limit(1, 1)->First();
|
||||||
|
$field->RightTitle = 'Right Title';
|
||||||
|
$field->write();
|
||||||
|
|
||||||
// test custom right title
|
$controller = new UserDefinedFormControllerTest_Controller($form);
|
||||||
$field = $form->Fields()->limit(1, 1)->First();
|
$formSteps = $controller->Form()->getFormFields();
|
||||||
$field->RightTitle = 'Right Title';
|
$firstStep = $formSteps->first();
|
||||||
$field->write();
|
|
||||||
|
|
||||||
$controller = new UserDefinedFormControllerTest_Controller($form);
|
$this->assertEquals($firstStep->getChildren()->First()->RightTitle(), "Right Title");
|
||||||
$formSteps = $controller->Form()->getFormFields();
|
|
||||||
$firstStep = $formSteps->first();
|
|
||||||
|
|
||||||
$this->assertEquals($firstStep->getChildren()->First()->RightTitle(), "Right Title");
|
// test empty form
|
||||||
|
$emptyForm = $this->objFromFixture('UserDefinedForm', 'empty-form');
|
||||||
|
$controller = new UserDefinedFormControllerTest_Controller($emptyForm);
|
||||||
|
|
||||||
// test empty form
|
$this->assertFalse($controller->Form()->getFormFields()->exists());
|
||||||
$emptyForm = $this->objFromFixture('UserDefinedForm', 'empty-form');
|
}
|
||||||
$controller = new UserDefinedFormControllerTest_Controller($emptyForm);
|
|
||||||
|
|
||||||
$this->assertFalse($controller->Form()->getFormFields()->exists());
|
public function testGetFormActions()
|
||||||
}
|
{
|
||||||
|
// generating the fieldset of actions
|
||||||
|
$form = $this->objFromFixture('UserDefinedForm', 'basic-form-page');
|
||||||
|
|
||||||
public function testGetFormActions()
|
$controller = new UserDefinedFormControllerTest_Controller($form);
|
||||||
{
|
$actions = $controller->Form()->getFormActions();
|
||||||
// generating the fieldset of actions
|
|
||||||
$form = $this->objFromFixture('UserDefinedForm', 'basic-form-page');
|
|
||||||
|
|
||||||
$controller = new UserDefinedFormControllerTest_Controller($form);
|
// by default will have 1 submit button which links to process
|
||||||
$actions = $controller->Form()->getFormActions();
|
$expected = new FieldList(new FormAction('process', 'Submit'));
|
||||||
|
$expected->setForm($controller->Form());
|
||||||
|
|
||||||
// by default will have 1 submit button which links to process
|
$this->assertEquals($actions, $expected);
|
||||||
$expected = new FieldList(new FormAction('process', 'Submit'));
|
|
||||||
$expected->setForm($controller->Form());
|
|
||||||
|
|
||||||
$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 UserDefinedFormControllerTest_Controller($custom);
|
||||||
|
$actions = $controller->Form()->getFormActions();
|
||||||
|
|
||||||
// the custom popup should have a reset button and a custom text
|
$expected = new FieldList(new FormAction('process', 'Custom Button'));
|
||||||
$custom = $this->objFromFixture('UserDefinedForm', 'form-with-reset-and-custom-action');
|
$expected->push(new ResetFormAction("clearForm", "Clear"));
|
||||||
$controller = new UserDefinedFormControllerTest_Controller($custom);
|
$expected->setForm($controller->Form());
|
||||||
$actions = $controller->Form()->getFormActions();
|
|
||||||
|
|
||||||
$expected = new FieldList(new FormAction('process', 'Custom Button'));
|
$this->assertEquals($actions, $expected);
|
||||||
$expected->push(new ResetFormAction("clearForm", "Clear"));
|
}
|
||||||
$expected->setForm($controller->Form());
|
|
||||||
|
|
||||||
$this->assertEquals($actions, $expected);
|
public function testRenderingIntoFormTemplate()
|
||||||
}
|
{
|
||||||
|
$form = $this->setupFormFrontend();
|
||||||
|
|
||||||
public function testRenderingIntoFormTemplate() {
|
$form->Content = 'This is some content without a form nested between it';
|
||||||
$form = $this->setupFormFrontend();
|
$form->doPublish();
|
||||||
|
|
||||||
$form->Content = 'This is some content without a form nested between it';
|
$controller = new UserDefinedFormControllerTest_Controller($form);
|
||||||
$form->doPublish();
|
|
||||||
|
|
||||||
$controller = new UserDefinedFormControllerTest_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')));
|
||||||
|
|
||||||
// check to see if $Form is replaced to inside the content
|
$this->checkTemplateIsCorrect($parser);
|
||||||
$index = new ArrayData($controller->index());
|
}
|
||||||
$parser = new CSSContentParser($index->renderWith(array('UserDefinedFormControllerTest')));
|
|
||||||
|
|
||||||
$this->checkTemplateIsCorrect($parser);
|
public function testRenderingIntoTemplateWithSubstringReplacement()
|
||||||
}
|
{
|
||||||
|
$form = $this->setupFormFrontend();
|
||||||
|
|
||||||
public function testRenderingIntoTemplateWithSubstringReplacement() {
|
$controller = new UserDefinedFormControllerTest_Controller($form);
|
||||||
$form = $this->setupFormFrontend();
|
|
||||||
|
|
||||||
$controller = new UserDefinedFormControllerTest_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')));
|
||||||
|
|
||||||
// check to see if $Form is replaced to inside the content
|
$this->checkTemplateIsCorrect($parser);
|
||||||
$index = new ArrayData($controller->index());
|
}
|
||||||
$parser = new CSSContentParser($index->renderWith(array('UserDefinedFormControllerTest')));
|
/**
|
||||||
|
* Publish a form for use on the frontend
|
||||||
|
*
|
||||||
|
* @param string $fixtureName
|
||||||
|
* @return UserDefinedForm
|
||||||
|
*/
|
||||||
|
protected function setupFormFrontend($fixtureName = 'basic-form-page')
|
||||||
|
{
|
||||||
|
$form = $this->objFromFixture('UserDefinedForm', $fixtureName);
|
||||||
|
$this->logInWithPermission('ADMIN');
|
||||||
|
|
||||||
$this->checkTemplateIsCorrect($parser);
|
$form->doPublish();
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Publish a form for use on the frontend
|
|
||||||
*
|
|
||||||
* @param string $fixtureName
|
|
||||||
* @return UserDefinedForm
|
|
||||||
*/
|
|
||||||
protected function setupFormFrontend($fixtureName = 'basic-form-page') {
|
|
||||||
$form = $this->objFromFixture('UserDefinedForm', $fixtureName);
|
|
||||||
$this->logInWithPermission('ADMIN');
|
|
||||||
|
|
||||||
$form->doPublish();
|
$member = Member::currentUser();
|
||||||
|
$member->logOut();
|
||||||
|
|
||||||
$member = Member::currentUser();
|
return $form;
|
||||||
$member->logOut();
|
}
|
||||||
|
|
||||||
return $form;
|
public function checkTemplateIsCorrect($parser)
|
||||||
}
|
{
|
||||||
|
$this->assertArrayHasKey(0, $parser->getBySelector('form#UserForm_Form'));
|
||||||
|
|
||||||
public function checkTemplateIsCorrect($parser) {
|
// check for the input
|
||||||
$this->assertArrayHasKey(0, $parser->getBySelector('form#UserForm_Form'));
|
$this->assertArrayHasKey(0, $parser->getBySelector('input.text'));
|
||||||
|
|
||||||
// check for the input
|
// check for the label and the text
|
||||||
$this->assertArrayHasKey(0, $parser->getBySelector('input.text'));
|
$label = $parser->getBySelector('label.left');
|
||||||
|
$this->assertArrayHasKey(0, $label);
|
||||||
|
|
||||||
// check for the label and the text
|
$this->assertEquals((string) $label[0][0], "Basic Text Field", "Label contains correct field name");
|
||||||
$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);
|
||||||
|
|
||||||
// check for the action
|
$this->assertEquals((string) $action[0]['value'], "Submit", "Submit button has default text");
|
||||||
$action = $parser->getBySelector('input.action');
|
}
|
||||||
$this->assertArrayHasKey(0, $action);
|
|
||||||
|
|
||||||
$this->assertEquals((string) $action[0]['value'], "Submit", "Submit button has default text");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class UserDefinedFormControllerTest_Controller extends UserDefinedForm_Controller implements TestOnly {
|
class UserDefinedFormControllerTest_Controller extends UserDefinedForm_Controller implements TestOnly
|
||||||
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overloaded to avoid inconsistencies between 2.4.2 and 2.4.3 (disables all security tokens in unit tests by default)
|
* Overloaded to avoid inconsistencies between 2.4.2 and 2.4.3 (disables all security tokens in unit tests by default)
|
||||||
*/
|
*/
|
||||||
public function Form() {
|
public function Form()
|
||||||
$form = parent::Form();
|
{
|
||||||
|
$form = parent::Form();
|
||||||
|
|
||||||
if($form) $form->disableSecurityToken();
|
if ($form) {
|
||||||
|
$form->disableSecurityToken();
|
||||||
return $form;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
return $form;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,421 +3,436 @@
|
|||||||
/**
|
/**
|
||||||
* @package userforms
|
* @package userforms
|
||||||
*/
|
*/
|
||||||
class UserDefinedFormTest extends FunctionalTest {
|
class UserDefinedFormTest extends FunctionalTest
|
||||||
|
{
|
||||||
|
|
||||||
static $fixture_file = 'UserDefinedFormTest.yml';
|
public static $fixture_file = 'UserDefinedFormTest.yml';
|
||||||
|
|
||||||
public function testRollbackToVersion() {
|
public function testRollbackToVersion()
|
||||||
$this->markTestSkipped(
|
{
|
||||||
'UserDefinedForm::rollback() has not been implemented completely'
|
$this->markTestSkipped(
|
||||||
);
|
'UserDefinedForm::rollback() has not been implemented completely'
|
||||||
|
);
|
||||||
|
|
||||||
// @todo
|
// @todo
|
||||||
$this->logInWithPermission('ADMIN');
|
$this->logInWithPermission('ADMIN');
|
||||||
$form = $this->objFromFixture('UserDefinedForm', 'basic-form-page');
|
$form = $this->objFromFixture('UserDefinedForm', 'basic-form-page');
|
||||||
|
|
||||||
$form->SubmitButtonText = 'Button Text';
|
$form->SubmitButtonText = 'Button Text';
|
||||||
$form->write();
|
$form->write();
|
||||||
$form->doPublish();
|
$form->doPublish();
|
||||||
$origVersion = $form->Version;
|
$origVersion = $form->Version;
|
||||||
|
|
||||||
$form->SubmitButtonText = 'Updated Button Text';
|
$form->SubmitButtonText = 'Updated Button Text';
|
||||||
$form->write();
|
$form->write();
|
||||||
$form->doPublish();
|
$form->doPublish();
|
||||||
|
|
||||||
// check published site
|
// check published site
|
||||||
$updated = Versioned::get_one_by_stage("UserDefinedForm", "Stage", "\"UserDefinedForm\".\"ID\" = $form->ID");
|
$updated = Versioned::get_one_by_stage("UserDefinedForm", "Stage", "\"UserDefinedForm\".\"ID\" = $form->ID");
|
||||||
$this->assertEquals($updated->SubmitButtonText, 'Updated Button Text');
|
$this->assertEquals($updated->SubmitButtonText, 'Updated Button Text');
|
||||||
|
|
||||||
$form->doRollbackTo($origVersion);
|
$form->doRollbackTo($origVersion);
|
||||||
|
|
||||||
$orignal = Versioned::get_one_by_stage("UserDefinedForm", "Stage", "\"UserDefinedForm\".\"ID\" = $form->ID");
|
$orignal = Versioned::get_one_by_stage("UserDefinedForm", "Stage", "\"UserDefinedForm\".\"ID\" = $form->ID");
|
||||||
$this->assertEquals($orignal->SubmitButtonText, 'Button Text');
|
$this->assertEquals($orignal->SubmitButtonText, 'Button Text');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGetCMSFields() {
|
public function testGetCMSFields()
|
||||||
$this->logInWithPermission('ADMIN');
|
{
|
||||||
$form = $this->objFromFixture('UserDefinedForm', 'basic-form-page');
|
$this->logInWithPermission('ADMIN');
|
||||||
|
$form = $this->objFromFixture('UserDefinedForm', 'basic-form-page');
|
||||||
|
|
||||||
$fields = $form->getCMSFields();
|
$fields = $form->getCMSFields();
|
||||||
|
|
||||||
$this->assertTrue($fields->dataFieldByName('Fields') !== null);
|
$this->assertTrue($fields->dataFieldByName('Fields') !== null);
|
||||||
$this->assertTrue($fields->dataFieldByName('EmailRecipients') != null);
|
$this->assertTrue($fields->dataFieldByName('EmailRecipients') != null);
|
||||||
$this->assertTrue($fields->dataFieldByName('Submissions') != null);
|
$this->assertTrue($fields->dataFieldByName('Submissions') != null);
|
||||||
$this->assertTrue($fields->dataFieldByName('OnCompleteMessage') != null);
|
$this->assertTrue($fields->dataFieldByName('OnCompleteMessage') != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testEmailRecipientPopup() {
|
public function testEmailRecipientPopup()
|
||||||
$this->logInWithPermission('ADMIN');
|
{
|
||||||
|
$this->logInWithPermission('ADMIN');
|
||||||
|
|
||||||
$form = $this->objFromFixture('UserDefinedForm', 'basic-form-page');
|
$form = $this->objFromFixture('UserDefinedForm', 'basic-form-page');
|
||||||
|
|
||||||
$popup = new UserDefinedForm_EmailRecipient();
|
$popup = new UserDefinedForm_EmailRecipient();
|
||||||
$popup->FormID = $form->ID;
|
$popup->FormID = $form->ID;
|
||||||
|
|
||||||
$fields = $popup->getCMSFields();
|
$fields = $popup->getCMSFields();
|
||||||
|
|
||||||
$this->assertTrue($fields->dataFieldByName('EmailSubject') !== null);
|
$this->assertTrue($fields->dataFieldByName('EmailSubject') !== null);
|
||||||
$this->assertTrue($fields->dataFieldByName('EmailFrom') !== null);
|
$this->assertTrue($fields->dataFieldByName('EmailFrom') !== null);
|
||||||
$this->assertTrue($fields->dataFieldByName('EmailAddress') !== null);
|
$this->assertTrue($fields->dataFieldByName('EmailAddress') !== null);
|
||||||
$this->assertTrue($fields->dataFieldByName('HideFormData') !== null);
|
$this->assertTrue($fields->dataFieldByName('HideFormData') !== null);
|
||||||
$this->assertTrue($fields->dataFieldByName('SendPlain') !== null);
|
$this->assertTrue($fields->dataFieldByName('SendPlain') !== null);
|
||||||
$this->assertTrue($fields->dataFieldByName('EmailBody') !== null);
|
$this->assertTrue($fields->dataFieldByName('EmailBody') !== null);
|
||||||
|
|
||||||
// add an email field, it should now add a or from X address picker
|
// add an email field, it should now add a or from X address picker
|
||||||
$email = $this->objFromFixture('EditableEmailField','email-field');
|
$email = $this->objFromFixture('EditableEmailField', 'email-field');
|
||||||
$form->Fields()->add($email);
|
$form->Fields()->add($email);
|
||||||
|
|
||||||
$popup->write();
|
$popup->write();
|
||||||
|
|
||||||
$fields = $popup->getCMSFields();
|
$fields = $popup->getCMSFields();
|
||||||
$this->assertThat($fields->dataFieldByName('SendEmailToFieldID'), $this->isInstanceOf('DropdownField'));
|
$this->assertThat($fields->dataFieldByName('SendEmailToFieldID'), $this->isInstanceOf('DropdownField'));
|
||||||
|
|
||||||
// if the front end has checkboxs or dropdown they can select from that can also be used to send things
|
// 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');
|
$dropdown = $this->objFromFixture('EditableDropdown', 'department-dropdown');
|
||||||
$form->Fields()->add($dropdown);
|
$form->Fields()->add($dropdown);
|
||||||
|
|
||||||
$fields = $popup->getCMSFields();
|
$fields = $popup->getCMSFields();
|
||||||
$this->assertTrue($fields->dataFieldByName('SendEmailToFieldID') !== null);
|
$this->assertTrue($fields->dataFieldByName('SendEmailToFieldID') !== null);
|
||||||
|
|
||||||
$popup->delete();
|
$popup->delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
function testGetEmailBodyContent() {
|
public function testGetEmailBodyContent()
|
||||||
$recipient = new UserDefinedForm_EmailRecipient();
|
{
|
||||||
|
$recipient = new UserDefinedForm_EmailRecipient();
|
||||||
|
|
||||||
$emailBody = 'not html';
|
$emailBody = 'not html';
|
||||||
$emailBodyHtml = '<p>html</p>';
|
$emailBodyHtml = '<p>html</p>';
|
||||||
|
|
||||||
$recipient->EmailBody = $emailBody;
|
$recipient->EmailBody = $emailBody;
|
||||||
$recipient->EmailBodyHtml = $emailBodyHtml;
|
$recipient->EmailBodyHtml = $emailBodyHtml;
|
||||||
$recipient->write();
|
$recipient->write();
|
||||||
|
|
||||||
$this->assertEquals($recipient->SendPlain, 0);
|
$this->assertEquals($recipient->SendPlain, 0);
|
||||||
$this->assertEquals($recipient->getEmailBodyContent(), $emailBodyHtml);
|
$this->assertEquals($recipient->getEmailBodyContent(), $emailBodyHtml);
|
||||||
|
|
||||||
$recipient->SendPlain = 1;
|
$recipient->SendPlain = 1;
|
||||||
$recipient->write();
|
$recipient->write();
|
||||||
|
|
||||||
$this->assertEquals($recipient->getEmailBodyContent(), $emailBody);
|
$this->assertEquals($recipient->getEmailBodyContent(), $emailBody);
|
||||||
|
|
||||||
$recipient->delete();
|
$recipient->delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
function testGetEmailTemplateDropdownValues() {
|
public function testGetEmailTemplateDropdownValues()
|
||||||
$recipient = new UserDefinedForm_EmailRecipient();
|
{
|
||||||
|
$recipient = new UserDefinedForm_EmailRecipient();
|
||||||
|
|
||||||
$defaultValues = array('SubmittedFormEmail' => 'SubmittedFormEmail');
|
$defaultValues = array('SubmittedFormEmail' => 'SubmittedFormEmail');
|
||||||
|
|
||||||
$this->assertEquals($recipient->getEmailTemplateDropdownValues(), $defaultValues);
|
$this->assertEquals($recipient->getEmailTemplateDropdownValues(), $defaultValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testEmailTemplateExists() {
|
public function testEmailTemplateExists()
|
||||||
$recipient = new UserDefinedForm_EmailRecipient();
|
{
|
||||||
|
$recipient = new UserDefinedForm_EmailRecipient();
|
||||||
|
|
||||||
// Set the default template
|
// Set the default template
|
||||||
$recipient->EmailTemplate = current(array_keys($recipient->getEmailTemplateDropdownValues()));
|
$recipient->EmailTemplate = current(array_keys($recipient->getEmailTemplateDropdownValues()));
|
||||||
$recipient->write();
|
$recipient->write();
|
||||||
|
|
||||||
// The default template exists
|
// The default template exists
|
||||||
$this->assertTrue($recipient->emailTemplateExists());
|
$this->assertTrue($recipient->emailTemplateExists());
|
||||||
|
|
||||||
// A made up template doesn't exists
|
// A made up template doesn't exists
|
||||||
$this->assertFalse($recipient->emailTemplateExists('MyTemplateThatsNotThere'));
|
$this->assertFalse($recipient->emailTemplateExists('MyTemplateThatsNotThere'));
|
||||||
|
|
||||||
$recipient->delete();
|
$recipient->delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
function testCanEditAndDeleteRecipient() {
|
public function testCanEditAndDeleteRecipient()
|
||||||
$form = $this->objFromFixture('UserDefinedForm', 'basic-form-page');
|
{
|
||||||
|
$form = $this->objFromFixture('UserDefinedForm', 'basic-form-page');
|
||||||
|
|
||||||
$this->logInWithPermission('ADMIN');
|
$this->logInWithPermission('ADMIN');
|
||||||
foreach($form->EmailRecipients() as $recipient) {
|
foreach ($form->EmailRecipients() as $recipient) {
|
||||||
$this->assertTrue($recipient->canEdit());
|
$this->assertTrue($recipient->canEdit());
|
||||||
$this->assertTrue($recipient->canDelete());
|
$this->assertTrue($recipient->canDelete());
|
||||||
}
|
}
|
||||||
|
|
||||||
$member = Member::currentUser();
|
$member = Member::currentUser();
|
||||||
$member->logOut();
|
$member->logOut();
|
||||||
|
|
||||||
$this->logInWithPermission('SITETREE_VIEW_ALL');
|
$this->logInWithPermission('SITETREE_VIEW_ALL');
|
||||||
foreach($form->EmailRecipients() as $recipient) {
|
foreach ($form->EmailRecipients() as $recipient) {
|
||||||
$this->assertFalse($recipient->canEdit());
|
$this->assertFalse($recipient->canEdit());
|
||||||
$this->assertFalse($recipient->canDelete());
|
$this->assertFalse($recipient->canDelete());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function testPublishing() {
|
public function testPublishing()
|
||||||
$this->logInWithPermission('ADMIN');
|
{
|
||||||
|
$this->logInWithPermission('ADMIN');
|
||||||
|
|
||||||
$form = $this->objFromFixture('UserDefinedForm', 'basic-form-page');
|
$form = $this->objFromFixture('UserDefinedForm', 'basic-form-page');
|
||||||
$form->write();
|
$form->write();
|
||||||
|
|
||||||
$form->doPublish();
|
$form->doPublish();
|
||||||
|
|
||||||
$live = Versioned::get_one_by_stage("UserDefinedForm", "Live", "\"UserDefinedForm_Live\".\"ID\" = $form->ID");
|
$live = Versioned::get_one_by_stage("UserDefinedForm", "Live", "\"UserDefinedForm_Live\".\"ID\" = $form->ID");
|
||||||
|
|
||||||
$this->assertNotNull($live);
|
$this->assertNotNull($live);
|
||||||
$this->assertEquals(2, $live->Fields()->Count()); // one page and one field
|
$this->assertEquals(2, $live->Fields()->Count()); // one page and one field
|
||||||
|
|
||||||
$dropdown = $this->objFromFixture('EditableDropdown', 'basic-dropdown');
|
$dropdown = $this->objFromFixture('EditableDropdown', 'basic-dropdown');
|
||||||
$form->Fields()->add($dropdown);
|
$form->Fields()->add($dropdown);
|
||||||
|
|
||||||
$stage = Versioned::get_one_by_stage("UserDefinedForm", "Stage", "\"UserDefinedForm\".\"ID\" = $form->ID");
|
$stage = Versioned::get_one_by_stage("UserDefinedForm", "Stage", "\"UserDefinedForm\".\"ID\" = $form->ID");
|
||||||
$this->assertEquals(3, $stage->Fields()->Count());
|
$this->assertEquals(3, $stage->Fields()->Count());
|
||||||
|
|
||||||
// should not have published the dropdown
|
// should not have published the dropdown
|
||||||
$liveDropdown = Versioned::get_one_by_stage("EditableFormField", "Live", "\"EditableFormField_Live\".\"ID\" = $dropdown->ID");
|
$liveDropdown = Versioned::get_one_by_stage("EditableFormField", "Live", "\"EditableFormField_Live\".\"ID\" = $dropdown->ID");
|
||||||
$this->assertNull($liveDropdown);
|
$this->assertNull($liveDropdown);
|
||||||
|
|
||||||
// when publishing it should have added it
|
// when publishing it should have added it
|
||||||
$form->doPublish();
|
$form->doPublish();
|
||||||
|
|
||||||
$live = Versioned::get_one_by_stage("UserDefinedForm", "Live", "\"UserDefinedForm_Live\".\"ID\" = $form->ID");
|
$live = Versioned::get_one_by_stage("UserDefinedForm", "Live", "\"UserDefinedForm_Live\".\"ID\" = $form->ID");
|
||||||
$this->assertEquals(3, $live->Fields()->Count());
|
$this->assertEquals(3, $live->Fields()->Count());
|
||||||
|
|
||||||
// edit the title
|
// edit the title
|
||||||
$text = $form->Fields()->limit(1, 1)->First();
|
$text = $form->Fields()->limit(1, 1)->First();
|
||||||
$text->Title = 'Edited title';
|
$text->Title = 'Edited title';
|
||||||
$text->write();
|
$text->write();
|
||||||
|
|
||||||
$liveText = Versioned::get_one_by_stage("EditableFormField", "Live", "\"EditableFormField_Live\".\"ID\" = $text->ID");
|
$liveText = Versioned::get_one_by_stage("EditableFormField", "Live", "\"EditableFormField_Live\".\"ID\" = $text->ID");
|
||||||
$this->assertFalse($liveText->Title == $text->Title);
|
$this->assertFalse($liveText->Title == $text->Title);
|
||||||
|
|
||||||
$form->doPublish();
|
$form->doPublish();
|
||||||
|
|
||||||
$liveText = Versioned::get_one_by_stage("EditableFormField", "Live", "\"EditableFormField_Live\".\"ID\" = $text->ID");
|
$liveText = Versioned::get_one_by_stage("EditableFormField", "Live", "\"EditableFormField_Live\".\"ID\" = $text->ID");
|
||||||
$this->assertTrue($liveText->Title == $text->Title);
|
$this->assertTrue($liveText->Title == $text->Title);
|
||||||
|
|
||||||
// Add a display rule to the dropdown
|
// Add a display rule to the dropdown
|
||||||
$displayRule = new EditableCustomRule();
|
$displayRule = new EditableCustomRule();
|
||||||
$displayRule->ParentID = $dropdown->ID;
|
$displayRule->ParentID = $dropdown->ID;
|
||||||
$displayRule->ConditionFieldID = $text->ID;
|
$displayRule->ConditionFieldID = $text->ID;
|
||||||
$displayRule->write();
|
$displayRule->write();
|
||||||
$ruleID = $displayRule->ID;
|
$ruleID = $displayRule->ID;
|
||||||
|
|
||||||
// Not live
|
// Not live
|
||||||
$liveRule = Versioned::get_one_by_stage("EditableCustomRule", "Live", "\"EditableCustomRule_Live\".\"ID\" = $ruleID");
|
$liveRule = Versioned::get_one_by_stage("EditableCustomRule", "Live", "\"EditableCustomRule_Live\".\"ID\" = $ruleID");
|
||||||
$this->assertEmpty($liveRule);
|
$this->assertEmpty($liveRule);
|
||||||
|
|
||||||
// Publish form, it's now live
|
// Publish form, it's now live
|
||||||
$form->doPublish();
|
$form->doPublish();
|
||||||
$liveRule = Versioned::get_one_by_stage("EditableCustomRule", "Live", "\"EditableCustomRule_Live\".\"ID\" = $ruleID");
|
$liveRule = Versioned::get_one_by_stage("EditableCustomRule", "Live", "\"EditableCustomRule_Live\".\"ID\" = $ruleID");
|
||||||
$this->assertNotEmpty($liveRule);
|
$this->assertNotEmpty($liveRule);
|
||||||
|
|
||||||
// Remove rule
|
// Remove rule
|
||||||
$displayRule->delete();
|
$displayRule->delete();
|
||||||
|
|
||||||
// Live rule still exists
|
// Live rule still exists
|
||||||
$liveRule = Versioned::get_one_by_stage("EditableCustomRule", "Live", "\"EditableCustomRule_Live\".\"ID\" = $ruleID");
|
$liveRule = Versioned::get_one_by_stage("EditableCustomRule", "Live", "\"EditableCustomRule_Live\".\"ID\" = $ruleID");
|
||||||
$this->assertNotEmpty($liveRule);
|
$this->assertNotEmpty($liveRule);
|
||||||
|
|
||||||
// Publish form, it should remove this rule
|
// Publish form, it should remove this rule
|
||||||
$form->doPublish();
|
$form->doPublish();
|
||||||
$liveRule = Versioned::get_one_by_stage("EditableCustomRule", "Live", "\"EditableCustomRule_Live\".\"ID\" = $ruleID");
|
$liveRule = Versioned::get_one_by_stage("EditableCustomRule", "Live", "\"EditableCustomRule_Live\".\"ID\" = $ruleID");
|
||||||
$this->assertEmpty($liveRule);
|
$this->assertEmpty($liveRule);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testUnpublishing() {
|
public function testUnpublishing()
|
||||||
$this->logInWithPermission('ADMIN');
|
{
|
||||||
$form = $this->objFromFixture('UserDefinedForm', 'basic-form-page');
|
$this->logInWithPermission('ADMIN');
|
||||||
$form->write();
|
$form = $this->objFromFixture('UserDefinedForm', 'basic-form-page');
|
||||||
$this->assertEquals(0, DB::query("SELECT COUNT(*) FROM \"EditableFormField_Live\"")->value());
|
$form->write();
|
||||||
$form->doPublish();
|
$this->assertEquals(0, DB::query("SELECT COUNT(*) FROM \"EditableFormField_Live\"")->value());
|
||||||
|
$form->doPublish();
|
||||||
|
|
||||||
// assert that it exists and has a field
|
// assert that it exists and has a field
|
||||||
$live = Versioned::get_one_by_stage("UserDefinedForm", "Live", "\"UserDefinedForm_Live\".\"ID\" = $form->ID");
|
$live = Versioned::get_one_by_stage("UserDefinedForm", "Live", "\"UserDefinedForm_Live\".\"ID\" = $form->ID");
|
||||||
|
|
||||||
$this->assertTrue(isset($live));
|
$this->assertTrue(isset($live));
|
||||||
$this->assertEquals(2, DB::query("SELECT COUNT(*) FROM \"EditableFormField_Live\"")->value());
|
$this->assertEquals(2, DB::query("SELECT COUNT(*) FROM \"EditableFormField_Live\"")->value());
|
||||||
|
|
||||||
// unpublish
|
// unpublish
|
||||||
$form->doUnpublish();
|
$form->doUnpublish();
|
||||||
|
|
||||||
$this->assertNull(Versioned::get_one_by_stage("UserDefinedForm", "Live", "\"UserDefinedForm_Live\".\"ID\" = $form->ID"));
|
$this->assertNull(Versioned::get_one_by_stage("UserDefinedForm", "Live", "\"UserDefinedForm_Live\".\"ID\" = $form->ID"));
|
||||||
$this->assertEquals(0, DB::query("SELECT COUNT(*) FROM \"EditableFormField_Live\"")->value());
|
$this->assertEquals(0, DB::query("SELECT COUNT(*) FROM \"EditableFormField_Live\"")->value());
|
||||||
}
|
}
|
||||||
|
|
||||||
function testDoRevertToLive() {
|
public function testDoRevertToLive()
|
||||||
$this->logInWithPermission('ADMIN');
|
{
|
||||||
$form = $this->objFromFixture('UserDefinedForm', 'basic-form-page');
|
$this->logInWithPermission('ADMIN');
|
||||||
$field = $form->Fields()->First();
|
$form = $this->objFromFixture('UserDefinedForm', 'basic-form-page');
|
||||||
|
$field = $form->Fields()->First();
|
||||||
$field->Title = 'Title';
|
|
||||||
$field->write();
|
$field->Title = 'Title';
|
||||||
|
$field->write();
|
||||||
$form->doPublish();
|
|
||||||
|
$form->doPublish();
|
||||||
$field->Title = 'Edited title';
|
|
||||||
$field->write();
|
$field->Title = 'Edited title';
|
||||||
|
$field->write();
|
||||||
// check that the published version is not updated
|
|
||||||
$live = Versioned::get_one_by_stage("EditableFormField", "Live", "\"EditableFormField_Live\".\"ID\" = $field->ID");
|
// check that the published version is not updated
|
||||||
$this->assertEquals('Title', $live->Title);
|
$live = Versioned::get_one_by_stage("EditableFormField", "Live", "\"EditableFormField_Live\".\"ID\" = $field->ID");
|
||||||
|
$this->assertEquals('Title', $live->Title);
|
||||||
// revert back to the live data
|
|
||||||
$form->doRevertToLive();
|
// revert back to the live data
|
||||||
$form->flushCache();
|
$form->doRevertToLive();
|
||||||
|
$form->flushCache();
|
||||||
$check = Versioned::get_one_by_stage("EditableFormField", "Stage", "\"EditableFormField\".\"ID\" = $field->ID");
|
|
||||||
|
$check = Versioned::get_one_by_stage("EditableFormField", "Stage", "\"EditableFormField\".\"ID\" = $field->ID");
|
||||||
$this->assertEquals('Title', $check->Title);
|
|
||||||
}
|
$this->assertEquals('Title', $check->Title);
|
||||||
|
}
|
||||||
function testDuplicatingForm() {
|
|
||||||
$this->logInWithPermission('ADMIN');
|
public function testDuplicatingForm()
|
||||||
$form = $this->objFromFixture('UserDefinedForm', 'basic-form-page');
|
{
|
||||||
|
$this->logInWithPermission('ADMIN');
|
||||||
$duplicate = $form->duplicate();
|
$form = $this->objFromFixture('UserDefinedForm', 'basic-form-page');
|
||||||
|
|
||||||
$this->assertEquals($form->Fields()->Count(), $duplicate->Fields()->Count());
|
$duplicate = $form->duplicate();
|
||||||
$this->assertEquals($form->EmailRecipients()->Count(), $form->EmailRecipients()->Count());
|
|
||||||
|
$this->assertEquals($form->Fields()->Count(), $duplicate->Fields()->Count());
|
||||||
// can't compare object since the dates/ids change
|
$this->assertEquals($form->EmailRecipients()->Count(), $form->EmailRecipients()->Count());
|
||||||
$this->assertEquals($form->Fields()->First()->Title, $duplicate->Fields()->First()->Title);
|
|
||||||
|
// can't compare object since the dates/ids change
|
||||||
// Test duplicate with group
|
$this->assertEquals($form->Fields()->First()->Title, $duplicate->Fields()->First()->Title);
|
||||||
$form2 = $this->objFromFixture('UserDefinedForm', 'page-with-group');
|
|
||||||
$form2Validator = new UserFormValidator();
|
// Test duplicate with group
|
||||||
$form2Validator->setForm(new Form(new Controller(), 'Form', new FieldList(), new FieldList()));
|
$form2 = $this->objFromFixture('UserDefinedForm', 'page-with-group');
|
||||||
$this->assertTrue($form2Validator->php($form2->toMap()));
|
$form2Validator = new UserFormValidator();
|
||||||
|
$form2Validator->setForm(new Form(new Controller(), 'Form', new FieldList(), new FieldList()));
|
||||||
// Check field groups exist
|
$this->assertTrue($form2Validator->php($form2->toMap()));
|
||||||
$form2GroupStart = $form2->Fields()->filter('ClassName', 'EditableFieldGroup')->first();
|
|
||||||
$form2GroupEnd = $form2->Fields()->filter('ClassName', 'EditableFieldGroupEnd')->first();
|
// Check field groups exist
|
||||||
$this->assertEquals($form2GroupEnd->ID, $form2GroupStart->EndID);
|
$form2GroupStart = $form2->Fields()->filter('ClassName', 'EditableFieldGroup')->first();
|
||||||
|
$form2GroupEnd = $form2->Fields()->filter('ClassName', 'EditableFieldGroupEnd')->first();
|
||||||
// Duplicate this
|
$this->assertEquals($form2GroupEnd->ID, $form2GroupStart->EndID);
|
||||||
$form3 = $form2->duplicate();
|
|
||||||
$form3Validator = new UserFormValidator();
|
// Duplicate this
|
||||||
$form3Validator->setForm(new Form(new Controller(), 'Form', new FieldList(), new FieldList()));
|
$form3 = $form2->duplicate();
|
||||||
$this->assertTrue($form3Validator->php($form3->toMap()));
|
$form3Validator = new UserFormValidator();
|
||||||
|
$form3Validator->setForm(new Form(new Controller(), 'Form', new FieldList(), new FieldList()));
|
||||||
// Check field groups exist
|
$this->assertTrue($form3Validator->php($form3->toMap()));
|
||||||
$form3GroupStart = $form3->Fields()->filter('ClassName', 'EditableFieldGroup')->first();
|
|
||||||
$form3GroupEnd = $form3->Fields()->filter('ClassName', 'EditableFieldGroupEnd')->first();
|
// Check field groups exist
|
||||||
$this->assertEquals($form3GroupEnd->ID, $form3GroupStart->EndID);
|
$form3GroupStart = $form3->Fields()->filter('ClassName', 'EditableFieldGroup')->first();
|
||||||
$this->assertNotEquals($form2GroupEnd->ID, $form3GroupStart->EndID);
|
$form3GroupEnd = $form3->Fields()->filter('ClassName', 'EditableFieldGroupEnd')->first();
|
||||||
}
|
$this->assertEquals($form3GroupEnd->ID, $form3GroupStart->EndID);
|
||||||
|
$this->assertNotEquals($form2GroupEnd->ID, $form3GroupStart->EndID);
|
||||||
function testFormOptions() {
|
}
|
||||||
$this->logInWithPermission('ADMIN');
|
|
||||||
$form = $this->objFromFixture('UserDefinedForm', 'basic-form-page');
|
public function testFormOptions()
|
||||||
|
{
|
||||||
$fields = $form->getFormOptions();
|
$this->logInWithPermission('ADMIN');
|
||||||
$submit = $fields->fieldByName('SubmitButtonText');
|
$form = $this->objFromFixture('UserDefinedForm', 'basic-form-page');
|
||||||
$reset = $fields->fieldByName('ShowClearButton');
|
|
||||||
|
$fields = $form->getFormOptions();
|
||||||
$this->assertEquals($submit->Title(), 'Text on submit button:');
|
$submit = $fields->fieldByName('SubmitButtonText');
|
||||||
$this->assertEquals($reset->Title(), 'Show Clear Form Button');
|
$reset = $fields->fieldByName('ShowClearButton');
|
||||||
}
|
|
||||||
|
$this->assertEquals($submit->Title(), 'Text on submit button:');
|
||||||
public function testEmailRecipientFilters() {
|
$this->assertEquals($reset->Title(), 'Show Clear Form Button');
|
||||||
$form = $this->objFromFixture('UserDefinedForm', 'filtered-form-page');
|
}
|
||||||
|
|
||||||
// Check unfiltered recipients
|
public function testEmailRecipientFilters()
|
||||||
$result0 = $form
|
{
|
||||||
->EmailRecipients()
|
$form = $this->objFromFixture('UserDefinedForm', 'filtered-form-page');
|
||||||
->sort('EmailAddress')
|
|
||||||
->column('EmailAddress');
|
// Check unfiltered recipients
|
||||||
$this->assertEquals(
|
$result0 = $form
|
||||||
array(
|
->EmailRecipients()
|
||||||
'filtered1@example.com',
|
->sort('EmailAddress')
|
||||||
'filtered2@example.com',
|
->column('EmailAddress');
|
||||||
'unfiltered@example.com'
|
$this->assertEquals(
|
||||||
),
|
array(
|
||||||
$result0
|
'filtered1@example.com',
|
||||||
);
|
'filtered2@example.com',
|
||||||
|
'unfiltered@example.com'
|
||||||
// check filters based on given data
|
),
|
||||||
$result1 = $form->FilteredEmailRecipients(
|
$result0
|
||||||
array(
|
);
|
||||||
'your-name' => 'Value',
|
|
||||||
'address' => '',
|
// check filters based on given data
|
||||||
'street' => 'Anything',
|
$result1 = $form->FilteredEmailRecipients(
|
||||||
'city' => 'Matches Not Equals',
|
array(
|
||||||
'colours' => array('Red') // matches 2
|
'your-name' => 'Value',
|
||||||
), null
|
'address' => '',
|
||||||
)
|
'street' => 'Anything',
|
||||||
->sort('EmailAddress')
|
'city' => 'Matches Not Equals',
|
||||||
->column('EmailAddress');
|
'colours' => array('Red') // matches 2
|
||||||
$this->assertEquals(
|
), null
|
||||||
array(
|
)
|
||||||
'filtered2@example.com',
|
->sort('EmailAddress')
|
||||||
'unfiltered@example.com'
|
->column('EmailAddress');
|
||||||
),
|
$this->assertEquals(
|
||||||
$result1
|
array(
|
||||||
);
|
'filtered2@example.com',
|
||||||
|
'unfiltered@example.com'
|
||||||
// Check all positive matches
|
),
|
||||||
$result2 = $form->FilteredEmailRecipients(
|
$result1
|
||||||
array(
|
);
|
||||||
'your-name' => '',
|
|
||||||
'address' => 'Anything',
|
// Check all positive matches
|
||||||
'street' => 'Matches Equals',
|
$result2 = $form->FilteredEmailRecipients(
|
||||||
'city' => 'Anything',
|
array(
|
||||||
'colours' => array('Red', 'Blue') // matches 2
|
'your-name' => '',
|
||||||
), null
|
'address' => 'Anything',
|
||||||
)
|
'street' => 'Matches Equals',
|
||||||
->sort('EmailAddress')
|
'city' => 'Anything',
|
||||||
->column('EmailAddress');
|
'colours' => array('Red', 'Blue') // matches 2
|
||||||
$this->assertEquals(
|
), null
|
||||||
array(
|
)
|
||||||
'filtered1@example.com',
|
->sort('EmailAddress')
|
||||||
'filtered2@example.com',
|
->column('EmailAddress');
|
||||||
'unfiltered@example.com'
|
$this->assertEquals(
|
||||||
),
|
array(
|
||||||
$result2
|
'filtered1@example.com',
|
||||||
);
|
'filtered2@example.com',
|
||||||
|
'unfiltered@example.com'
|
||||||
|
),
|
||||||
$result3 = $form->FilteredEmailRecipients(
|
$result2
|
||||||
array(
|
);
|
||||||
'your-name' => 'Should be blank but is not',
|
|
||||||
'address' => 'Anything',
|
|
||||||
'street' => 'Matches Equals',
|
$result3 = $form->FilteredEmailRecipients(
|
||||||
'city' => 'Anything',
|
array(
|
||||||
'colours' => array('Blue')
|
'your-name' => 'Should be blank but is not',
|
||||||
), null
|
'address' => 'Anything',
|
||||||
)->column('EmailAddress');
|
'street' => 'Matches Equals',
|
||||||
$this->assertEquals(
|
'city' => 'Anything',
|
||||||
array(
|
'colours' => array('Blue')
|
||||||
'unfiltered@example.com'
|
), null
|
||||||
),
|
)->column('EmailAddress');
|
||||||
$result3
|
$this->assertEquals(
|
||||||
);
|
array(
|
||||||
|
'unfiltered@example.com'
|
||||||
|
),
|
||||||
$result4 = $form->FilteredEmailRecipients(
|
$result3
|
||||||
array(
|
);
|
||||||
'your-name' => '',
|
|
||||||
'address' => 'Anything',
|
|
||||||
'street' => 'Wrong value for this field',
|
$result4 = $form->FilteredEmailRecipients(
|
||||||
'city' => '',
|
array(
|
||||||
'colours' => array('Blue', 'Green')
|
'your-name' => '',
|
||||||
), null
|
'address' => 'Anything',
|
||||||
)->column('EmailAddress');
|
'street' => 'Wrong value for this field',
|
||||||
$this->assertEquals(
|
'city' => '',
|
||||||
array(
|
'colours' => array('Blue', 'Green')
|
||||||
'unfiltered@example.com'
|
), null
|
||||||
),
|
)->column('EmailAddress');
|
||||||
$result4
|
$this->assertEquals(
|
||||||
);
|
array(
|
||||||
}
|
'unfiltered@example.com'
|
||||||
|
),
|
||||||
public function testIndex() {
|
$result4
|
||||||
// Test that the $UserDefinedForm is stripped out
|
);
|
||||||
$page = $this->objFromFixture('UserDefinedForm', 'basic-form-page');
|
}
|
||||||
$page->publish('Stage', 'Live');
|
|
||||||
|
public function testIndex()
|
||||||
$result = $this->get($page->Link());
|
{
|
||||||
$body = Convert::nl2os($result->getBody(), ''); // strip out newlines
|
// Test that the $UserDefinedForm is stripped out
|
||||||
$this->assertFalse($result->isError());
|
$page = $this->objFromFixture('UserDefinedForm', 'basic-form-page');
|
||||||
$this->assertContains('<p>Here is my form</p><form', $body);
|
$page->publish('Stage', 'Live');
|
||||||
$this->assertContains('</form><p>Thank you for filling it out</p>', $body);
|
|
||||||
|
$result = $this->get($page->Link());
|
||||||
$this->assertNotContains('<p>$UserDefinedForm</p>', $body);
|
$body = Convert::nl2os($result->getBody(), ''); // strip out newlines
|
||||||
$this->assertNotContains('<p></p>', $body);
|
$this->assertFalse($result->isError());
|
||||||
$this->assertNotContains('</p><p>Thank you for filling it out</p>', $body);
|
$this->assertContains('<p>Here is my form</p><form', $body);
|
||||||
}
|
$this->assertContains('</form><p>Thank you for filling it out</p>', $body);
|
||||||
}
|
|
||||||
|
$this->assertNotContains('<p>$UserDefinedForm</p>', $body);
|
||||||
|
$this->assertNotContains('<p></p>', $body);
|
||||||
|
$this->assertNotContains('</p><p>Thank you for filling it out</p>', $body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,18 +1,20 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
|
||||||
class UserFormTest extends SapphireTest {
|
class UserFormTest extends SapphireTest
|
||||||
|
{
|
||||||
|
|
||||||
protected static $fixture_file = 'UserDefinedFormTest.yml';
|
protected static $fixture_file = 'UserDefinedFormTest.yml';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests that a form will not generate empty pages
|
* Tests that a form will not generate empty pages
|
||||||
*/
|
*/
|
||||||
public function testEmptyPages() {
|
public function testEmptyPages()
|
||||||
$page = $this->objFromFixture('UserDefinedForm', 'empty-page');
|
{
|
||||||
$this->assertEquals(5, $page->Fields()->count());
|
$page = $this->objFromFixture('UserDefinedForm', 'empty-page');
|
||||||
$controller = ModelAsController::controller_for($page);
|
$this->assertEquals(5, $page->Fields()->count());
|
||||||
$form = new UserForm($controller);
|
$controller = ModelAsController::controller_for($page);
|
||||||
$this->assertEquals(2, $form->getSteps()->count());
|
$form = new UserForm($controller);
|
||||||
}
|
$this->assertEquals(2, $form->getSteps()->count());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -1,216 +1,220 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
class UserFormsUpgradeServiceTest extends SapphireTest {
|
class UserFormsUpgradeServiceTest extends SapphireTest
|
||||||
|
{
|
||||||
|
|
||||||
static $fixture_file = 'UserFormsUpgradeServiceTest.yml';
|
public static $fixture_file = 'UserFormsUpgradeServiceTest.yml';
|
||||||
|
|
||||||
public function setUp() {
|
public function setUp()
|
||||||
Config::inst()->update('UserDefinedForm', 'upgrade_on_build', false);
|
{
|
||||||
parent::setUp();
|
Config::inst()->update('UserDefinedForm', 'upgrade_on_build', false);
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
// Assign rules programatically
|
// Assign rules programatically
|
||||||
$field1 = $this->objFromFixture('EditableTextField', 'text1');
|
$field1 = $this->objFromFixture('EditableTextField', 'text1');
|
||||||
$field2 = $this->objFromFixture('EditableTextField', 'text2');
|
$field2 = $this->objFromFixture('EditableTextField', 'text2');
|
||||||
$field3 = $this->objFromFixture('EditableTextField', 'text3');
|
$field3 = $this->objFromFixture('EditableTextField', 'text3');
|
||||||
|
|
||||||
$field3->CustomRules = serialize(array(
|
$field3->CustomRules = serialize(array(
|
||||||
array(
|
array(
|
||||||
'Display' => 'Show',
|
'Display' => 'Show',
|
||||||
'ConditionField' => $field1->Name,
|
'ConditionField' => $field1->Name,
|
||||||
'ConditionOption' => 'IsBlank',
|
'ConditionOption' => 'IsBlank',
|
||||||
'Value' => ''
|
'Value' => ''
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
'Display' => 'Hide',
|
'Display' => 'Hide',
|
||||||
'ConditionField' => $field2->Name,
|
'ConditionField' => $field2->Name,
|
||||||
'ConditionOption' => 'HasValue',
|
'ConditionOption' => 'HasValue',
|
||||||
'Value' => 'bob'
|
'Value' => 'bob'
|
||||||
)
|
)
|
||||||
));
|
));
|
||||||
$field3->write();
|
$field3->write();
|
||||||
|
|
||||||
// Assign settings programatically
|
// Assign settings programatically
|
||||||
$field4 = $this->objFromFixture('EditableTextField', 'text4');
|
$field4 = $this->objFromFixture('EditableTextField', 'text4');
|
||||||
$field4->CustomSettings = serialize(array(
|
$field4->CustomSettings = serialize(array(
|
||||||
'MinLength' => 20,
|
'MinLength' => 20,
|
||||||
'MaxLength' => 100,
|
'MaxLength' => 100,
|
||||||
'Rows' => 4,
|
'Rows' => 4,
|
||||||
'ExtraClass' => 'special class',
|
'ExtraClass' => 'special class',
|
||||||
'RightTitle' => 'My Field',
|
'RightTitle' => 'My Field',
|
||||||
'ShowOnLoad' => '',
|
'ShowOnLoad' => '',
|
||||||
'Default' => 'Enter your text here'
|
'Default' => 'Enter your text here'
|
||||||
));
|
));
|
||||||
$field4->write();
|
$field4->write();
|
||||||
|
|
||||||
$numeric1 = $this->objFromFixture('EditableNumericField', 'numeric1');
|
$numeric1 = $this->objFromFixture('EditableNumericField', 'numeric1');
|
||||||
$numeric1->CustomSettings = serialize(array(
|
$numeric1->CustomSettings = serialize(array(
|
||||||
'RightTitle' => 'Number of %',
|
'RightTitle' => 'Number of %',
|
||||||
'Default' => 1,
|
'Default' => 1,
|
||||||
'MinValue' => 1,
|
'MinValue' => 1,
|
||||||
'MaxValue' => 100,
|
'MaxValue' => 100,
|
||||||
'ShowOnLoad' => 'Show'
|
'ShowOnLoad' => 'Show'
|
||||||
));
|
));
|
||||||
$numeric1->write();
|
$numeric1->write();
|
||||||
|
|
||||||
$group1 = $this->objFromFixture('Group', 'group1');
|
$group1 = $this->objFromFixture('Group', 'group1');
|
||||||
$members1 = $this->objFromFixture('EditableMemberListField', 'members1');
|
$members1 = $this->objFromFixture('EditableMemberListField', 'members1');
|
||||||
$members1->CustomSettings = serialize(array(
|
$members1->CustomSettings = serialize(array(
|
||||||
'RightTitle' => 'Select group',
|
'RightTitle' => 'Select group',
|
||||||
'GroupID' => $group1->ID,
|
'GroupID' => $group1->ID,
|
||||||
'ShowOnLoad' => 'Hide'
|
'ShowOnLoad' => 'Hide'
|
||||||
));
|
));
|
||||||
$members1->write();
|
$members1->write();
|
||||||
|
|
||||||
$literal1 = $this->objFromFixture('EditableLiteralField', 'literal1');
|
$literal1 = $this->objFromFixture('EditableLiteralField', 'literal1');
|
||||||
$literal1->CustomSettings = serialize(array(
|
$literal1->CustomSettings = serialize(array(
|
||||||
'HideFromReports' => 1,
|
'HideFromReports' => 1,
|
||||||
'RightTitle' => 'Literal',
|
'RightTitle' => 'Literal',
|
||||||
'Content' => '<p>Content</p>',
|
'Content' => '<p>Content</p>',
|
||||||
'ShowOnLoad' => true
|
'ShowOnLoad' => true
|
||||||
));
|
));
|
||||||
$literal1->write();
|
$literal1->write();
|
||||||
|
|
||||||
$heading1 = $this->objFromFixture('EditableFormHeading', 'heading1');
|
$heading1 = $this->objFromFixture('EditableFormHeading', 'heading1');
|
||||||
$heading1->CustomSettings = serialize(array(
|
$heading1->CustomSettings = serialize(array(
|
||||||
'RightTitle' => 'Right',
|
'RightTitle' => 'Right',
|
||||||
'Level' => 3,
|
'Level' => 3,
|
||||||
'HideFromReports' => true,
|
'HideFromReports' => true,
|
||||||
'ShowOnLoad' => false
|
'ShowOnLoad' => false
|
||||||
));
|
));
|
||||||
$heading1->write();
|
$heading1->write();
|
||||||
|
|
||||||
$folder = $this->objFromFixture('Folder', 'folder1');
|
$folder = $this->objFromFixture('Folder', 'folder1');
|
||||||
$file1 = $this->objFromFixture('EditableFileField', 'file1');
|
$file1 = $this->objFromFixture('EditableFileField', 'file1');
|
||||||
$file1->CustomSettings = serialize(array(
|
$file1->CustomSettings = serialize(array(
|
||||||
'RightTitle' => 'File field',
|
'RightTitle' => 'File field',
|
||||||
'Folder' => $folder->ID
|
'Folder' => $folder->ID
|
||||||
));
|
));
|
||||||
$file1->write();
|
$file1->write();
|
||||||
|
|
||||||
$date1 = $this->objFromFixture('EditableDateField', 'date1');
|
$date1 = $this->objFromFixture('EditableDateField', 'date1');
|
||||||
$date1->CustomSettings = serialize(array(
|
$date1->CustomSettings = serialize(array(
|
||||||
'RightTitle' => 'Date field',
|
'RightTitle' => 'Date field',
|
||||||
'DefaultToToday' => '1'
|
'DefaultToToday' => '1'
|
||||||
));
|
));
|
||||||
$date1->write();
|
$date1->write();
|
||||||
|
|
||||||
$checkbox1 = $this->objFromFixture('EditableCheckbox', 'checkbox1');
|
$checkbox1 = $this->objFromFixture('EditableCheckbox', 'checkbox1');
|
||||||
$checkbox1->CustomSettings = serialize(array(
|
$checkbox1->CustomSettings = serialize(array(
|
||||||
'Default' => true,
|
'Default' => true,
|
||||||
'RightTitle' => 'Check this'
|
'RightTitle' => 'Check this'
|
||||||
));
|
));
|
||||||
$checkbox1->write();
|
$checkbox1->write();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
/**
|
||||||
|
* @return UserFormsUpgradeService;
|
||||||
|
*/
|
||||||
|
protected function getService()
|
||||||
|
{
|
||||||
|
return singleton('UserFormsUpgradeService');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return UserFormsUpgradeService;
|
* Tests migration of custom rules
|
||||||
*/
|
*/
|
||||||
protected function getService() {
|
public function testCustomRulesMigration()
|
||||||
return singleton('UserFormsUpgradeService');
|
{
|
||||||
}
|
$service = $this->getService();
|
||||||
|
$service->setQuiet(true);
|
||||||
|
$service->run();
|
||||||
|
|
||||||
/**
|
$field1 = $this->objFromFixture('EditableTextField', 'text1');
|
||||||
* Tests migration of custom rules
|
$field2 = $this->objFromFixture('EditableTextField', 'text2');
|
||||||
*/
|
$field3 = $this->objFromFixture('EditableTextField', 'text3');
|
||||||
public function testCustomRulesMigration() {
|
|
||||||
$service = $this->getService();
|
|
||||||
$service->setQuiet(true);
|
|
||||||
$service->run();
|
|
||||||
|
|
||||||
$field1 = $this->objFromFixture('EditableTextField', 'text1');
|
$this->assertDOSEquals(array(
|
||||||
$field2 = $this->objFromFixture('EditableTextField', 'text2');
|
array(
|
||||||
$field3 = $this->objFromFixture('EditableTextField', 'text3');
|
'Display' => 'Show',
|
||||||
|
'ConditionFieldID' => $field1->ID,
|
||||||
|
'ConditionOption' => 'IsBlank'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'Display' => 'Hide',
|
||||||
|
'ConditionFieldID' => $field2->ID,
|
||||||
|
'ConditionOption' => 'HasValue',
|
||||||
|
'FieldValue' => 'bob'
|
||||||
|
)
|
||||||
|
), $field3->DisplayRules());
|
||||||
|
}
|
||||||
|
|
||||||
$this->assertDOSEquals(array(
|
/**
|
||||||
array(
|
* Tests migration of all custom settings
|
||||||
'Display' => 'Show',
|
*/
|
||||||
'ConditionFieldID' => $field1->ID,
|
public function testCustomSettingsMigration()
|
||||||
'ConditionOption' => 'IsBlank'
|
{
|
||||||
),
|
$service = $this->getService();
|
||||||
array(
|
$service->setQuiet(true);
|
||||||
'Display' => 'Hide',
|
$service->run();
|
||||||
'ConditionFieldID' => $field2->ID,
|
|
||||||
'ConditionOption' => 'HasValue',
|
|
||||||
'FieldValue' => 'bob'
|
|
||||||
)
|
|
||||||
), $field3->DisplayRules());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
$group1 = $this->objFromFixture('Group', 'group1');
|
||||||
* Tests migration of all custom settings
|
$form = $this->objFromFixture('UserDefinedForm', 'form-with-settings');
|
||||||
*/
|
$folder = $this->objFromFixture('Folder', 'folder1');
|
||||||
public function testCustomSettingsMigration() {
|
|
||||||
$service = $this->getService();
|
|
||||||
$service->setQuiet(true);
|
|
||||||
$service->run();
|
|
||||||
|
|
||||||
$group1 = $this->objFromFixture('Group', 'group1');
|
$this->assertDOSEquals(array(
|
||||||
$form = $this->objFromFixture('UserDefinedForm', 'form-with-settings');
|
array(
|
||||||
$folder = $this->objFromFixture('Folder', 'folder1');
|
'ClassName' => 'EditableTextField',
|
||||||
|
'Title' => 'Text with rule',
|
||||||
$this->assertDOSEquals(array(
|
'MinLength' => 20,
|
||||||
array(
|
'MaxLength' => 100,
|
||||||
'ClassName' => 'EditableTextField',
|
'Rows' => 4,
|
||||||
'Title' => 'Text with rule',
|
'ExtraClass' => 'special class',
|
||||||
'MinLength' => 20,
|
'RightTitle' => 'My Field',
|
||||||
'MaxLength' => 100,
|
'ShowOnLoad' => true,
|
||||||
'Rows' => 4,
|
'Default' => 'Enter your text here',
|
||||||
'ExtraClass' => 'special class',
|
),
|
||||||
'RightTitle' => 'My Field',
|
array(
|
||||||
'ShowOnLoad' => true,
|
'ClassName' => 'EditableNumericField',
|
||||||
'Default' => 'Enter your text here',
|
'Title' => 'Numeric 1',
|
||||||
),
|
'RightTitle' => 'Number of %',
|
||||||
array(
|
'Default' => 1,
|
||||||
'ClassName' => 'EditableNumericField',
|
'MinValue' => 1,
|
||||||
'Title' => 'Numeric 1',
|
'MaxValue' => 100,
|
||||||
'RightTitle' => 'Number of %',
|
'ShowOnLoad' => true,
|
||||||
'Default' => 1,
|
),
|
||||||
'MinValue' => 1,
|
array(
|
||||||
'MaxValue' => 100,
|
'ClassName' => 'EditableMemberListField',
|
||||||
'ShowOnLoad' => true,
|
'Title' => 'Members 1',
|
||||||
),
|
'RightTitle' => 'Select group',
|
||||||
array(
|
'GroupID' => $group1->ID,
|
||||||
'ClassName' => 'EditableMemberListField',
|
'ShowOnLoad' => false,
|
||||||
'Title' => 'Members 1',
|
),
|
||||||
'RightTitle' => 'Select group',
|
array(
|
||||||
'GroupID' => $group1->ID,
|
'ClassName' => 'EditableLiteralField',
|
||||||
'ShowOnLoad' => false,
|
'Title' => 'Literal 1',
|
||||||
),
|
'HideFromReports' => true,
|
||||||
array(
|
'RightTitle' => 'Literal',
|
||||||
'ClassName' => 'EditableLiteralField',
|
'Content' => '<p>Content</p>',
|
||||||
'Title' => 'Literal 1',
|
'ShowOnLoad' => true,
|
||||||
'HideFromReports' => true,
|
),
|
||||||
'RightTitle' => 'Literal',
|
array(
|
||||||
'Content' => '<p>Content</p>',
|
'ClassName' => 'EditableFormHeading',
|
||||||
'ShowOnLoad' => true,
|
'Title' => 'Heading 1',
|
||||||
),
|
'RightTitle' => 'Right',
|
||||||
array(
|
'Level' => 3,
|
||||||
'ClassName' => 'EditableFormHeading',
|
'HideFromReports' => true,
|
||||||
'Title' => 'Heading 1',
|
'ShowOnLoad' => false,
|
||||||
'RightTitle' => 'Right',
|
),
|
||||||
'Level' => 3,
|
array(
|
||||||
'HideFromReports' => true,
|
'ClassName' => 'EditableFileField',
|
||||||
'ShowOnLoad' => false,
|
'Title' => 'File 1',
|
||||||
),
|
'RightTitle' => 'File field',
|
||||||
array(
|
'FolderID' => $folder->ID,
|
||||||
'ClassName' => 'EditableFileField',
|
),
|
||||||
'Title' => 'File 1',
|
array(
|
||||||
'RightTitle' => 'File field',
|
'ClassName' => 'EditableDateField',
|
||||||
'FolderID' => $folder->ID,
|
'Title' => 'Date 1',
|
||||||
),
|
'RightTitle' => 'Date field',
|
||||||
array(
|
'DefaultToToday' => true,
|
||||||
'ClassName' => 'EditableDateField',
|
),
|
||||||
'Title' => 'Date 1',
|
array(
|
||||||
'RightTitle' => 'Date field',
|
'ClassName' => 'EditableCheckbox',
|
||||||
'DefaultToToday' => true,
|
'Title' => 'Checkbox 1',
|
||||||
),
|
'CheckedDefault' => true,
|
||||||
array(
|
'RightTitle' => 'Check this',
|
||||||
'ClassName' => 'EditableCheckbox',
|
),
|
||||||
'Title' => 'Checkbox 1',
|
), $form->Fields());
|
||||||
'CheckedDefault' => true,
|
}
|
||||||
'RightTitle' => 'Check this',
|
|
||||||
),
|
|
||||||
), $form->Fields());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user