Merge pull request #722 from creative-commoners/pulls/5.0/fix_getFormParent

refactor how getCMSFields is built to handle no parent form
This commit is contained in:
Dylan Wagstaff 2018-02-21 09:46:08 +13:00 committed by GitHub
commit 7e54584615
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 232 additions and 124 deletions

View File

@ -2,7 +2,6 @@
namespace SilverStripe\UserForms\Model\Recipient; namespace SilverStripe\UserForms\Model\Recipient;
use SilverStripe\Admin\LeftAndMain;
use SilverStripe\Assets\FileFinder; use SilverStripe\Assets\FileFinder;
use SilverStripe\CMS\Controllers\CMSMain; use SilverStripe\CMS\Controllers\CMSMain;
use SilverStripe\CMS\Controllers\CMSPageEditController; use SilverStripe\CMS\Controllers\CMSPageEditController;
@ -27,14 +26,18 @@ use SilverStripe\Forms\TabSet;
use SilverStripe\Forms\TextareaField; use SilverStripe\Forms\TextareaField;
use SilverStripe\Forms\TextField; use SilverStripe\Forms\TextField;
use SilverStripe\ORM\ArrayList; use SilverStripe\ORM\ArrayList;
use SilverStripe\ORM\DataList;
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\DB; use SilverStripe\ORM\DB;
use SilverStripe\ORM\FieldType\DBField; use SilverStripe\ORM\FieldType\DBField;
use SilverStripe\ORM\ValidationResult;
use SilverStripe\Security\Member;
use SilverStripe\UserForms\Model\EditableFormField; use SilverStripe\UserForms\Model\EditableFormField;
use SilverStripe\UserForms\Model\EditableFormField\EditableEmailField; use SilverStripe\UserForms\Model\EditableFormField\EditableEmailField;
use SilverStripe\UserForms\Model\EditableFormField\EditableMultipleOptionField; use SilverStripe\UserForms\Model\EditableFormField\EditableMultipleOptionField;
use SilverStripe\UserForms\Model\EditableFormField\EditableTextField; use SilverStripe\UserForms\Model\EditableFormField\EditableTextField;
use SilverStripe\UserForms\Model\UserDefinedForm; use SilverStripe\UserForms\Model\UserDefinedForm;
use SilverStripe\UserForms\UserForm;
use SilverStripe\View\Requirements; use SilverStripe\View\Requirements;
use Symbiote\GridFieldExtensions\GridFieldAddNewInlineButton; use Symbiote\GridFieldExtensions\GridFieldAddNewInlineButton;
use Symbiote\GridFieldExtensions\GridFieldEditableColumns; use Symbiote\GridFieldExtensions\GridFieldEditableColumns;
@ -75,7 +78,7 @@ class EmailRecipient extends DataObject
'CustomRules', 'CustomRules',
]; ];
private static $cascade_deetes = [ private static $cascade_deletes = [
'CustomRules', 'CustomRules',
]; ];
@ -123,19 +126,19 @@ class EmailRecipient extends DataObject
} }
/** /**
* Get instance of UserDefinedForm when editing in getCMSFields * Get instance of UserForm when editing in getCMSFields
* *
* @return UserDefinedForm * @return UserDefinedForm|UserForm
*/ */
protected function getFormParent() protected function getFormParent()
{ {
// LeftAndMain::sessionNamespace is protected. @todo replace this with a non-deprecated equivalent. // LeftAndMain::sessionNamespace is protected. @todo replace this with a non-deprecated equivalent.
$sessionNamespace = $this->config()->get('session_namespace') ?: CMSMain::class; $sessionNamespace = $this->config()->get('session_namespace') ?: CMSMain::class;
$formID = $this->FormID $formID = $this->FormID ?: Controller::curr()->getRequest()->getSession()->get($sessionNamespace . '.currentPage');
? $this->FormID $formClass = $this->FormClass ?: UserDefinedForm::class;
: Controller::curr()->getRequest()->getSession()->get($sessionNamespace . '.currentPage');
return UserDefinedForm::get()->byID($formID); return $formClass::get()->byID($formID);
} }
public function getTitle() public function getTitle()
@ -156,6 +159,9 @@ class EmailRecipient extends DataObject
*/ */
protected function getRulesConfig() protected function getRulesConfig()
{ {
if (!$this->getFormParent()) {
return null;
}
$formFields = $this->getFormParent()->Fields(); $formFields = $this->getFormParent()->Fields();
$config = GridFieldConfig::create() $config = GridFieldConfig::create()
@ -190,122 +196,22 @@ class EmailRecipient extends DataObject
{ {
Requirements::javascript('silverstripe/userforms:client/dist/js/userforms-cms.js'); Requirements::javascript('silverstripe/userforms:client/dist/js/userforms-cms.js');
// Determine optional field values
$form = $this->getFormParent();
// predefined choices are also candidates
$multiOptionFields = EditableMultipleOptionField::get()->filter('ParentID', $form->ID);
// if they have email fields then we could send from it
$validEmailFromFields = EditableEmailField::get()->filter('ParentID', $form->ID);
// For the subject, only one-line entry boxes make sense
$validSubjectFields = ArrayList::create(
EditableTextField::get()
->filter('ParentID', $form->ID)
->exclude('Rows:GreaterThan', 1)
->toArray()
);
$validSubjectFields->merge($multiOptionFields);
// Check valid email-recipient fields
if ($this->config()->get('allow_unbound_recipient_fields')) {
// To address can only be email fields or multi option fields
$validEmailToFields = ArrayList::create($validEmailFromFields->toArray());
$validEmailToFields->merge($multiOptionFields);
} else {
// To address cannot be unbound, so restrict to pre-defined lists
$validEmailToFields = $multiOptionFields;
}
// Build fieldlist // Build fieldlist
$fields = FieldList::create(Tabset::create('Root')->addExtraClass('EmailRecipientForm')); $fields = FieldList::create(Tabset::create('Root')->addExtraClass('EmailRecipientForm'));
if (!$this->getFormParent()) {
$fields->addFieldToTab('Root.EmailDetails', $this->getUnsavedFormLiteralField());
}
// Configuration fields // Configuration fields
$fields->addFieldsToTab('Root.EmailDetails', [ $fields->addFieldsToTab('Root.EmailDetails', [
// Subject $this->getSubjectCMSFields(),
FieldGroup::create( $this->getEmailToCMSFields(),
TextField::create( $this->getEmailFromCMSFields(),
'EmailSubject', $this->getEmailReplyToCMSFields(),
_t('SilverStripe\\UserForms\\Model\\UserDefinedForm.TYPESUBJECT', 'Type subject')
)
->setAttribute('style', 'min-width: 400px;'),
DropdownField::create(
'SendEmailSubjectFieldID',
_t(
'SilverStripe\\UserForms\\Model\\UserDefinedForm.SELECTAFIELDTOSETSUBJECT',
'.. or select a field to use as the subject'
),
$validSubjectFields->map('ID', 'Title')
)->setEmptyString('')
)
->setTitle(_t('SilverStripe\\UserForms\\Model\\UserDefinedForm.EMAILSUBJECT', 'Email subject')),
// To
FieldGroup::create(
TextField::create(
'EmailAddress',
_t('SilverStripe\\UserForms\\Model\\UserDefinedForm.TYPETO', 'Type to address')
)
->setAttribute('style', 'min-width: 400px;'),
DropdownField::create(
'SendEmailToFieldID',
_t(
'SilverStripe\\UserForms\\Model\\UserDefinedForm.ORSELECTAFIELDTOUSEASTO',
'.. or select a field to use as the to address'
),
$validEmailToFields->map('ID', 'Title')
)->setEmptyString(' ')
)
->setTitle(_t('SilverStripe\\UserForms\\Model\\UserDefinedForm.SENDEMAILTO', 'Send email to'))
->setDescription(_t(
'SilverStripe\\UserForms\\Model\\UserDefinedForm.SENDEMAILTO_DESCRIPTION',
'You may enter multiple email addresses as a comma separated list.'
)),
// From
TextField::create(
'EmailFrom',
_t('SilverStripe\\UserForms\\Model\\UserDefinedForm.FROMADDRESS', 'Send email from')
)
->setDescription(_t(
'SilverStripe\\UserForms\\Model\\UserDefinedForm.EmailFromContent',
"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. ".
"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."
)),
// Reply-To
FieldGroup::create(
TextField::create('EmailReplyTo', _t(
'SilverStripe\\UserForms\\Model\\UserDefinedForm.TYPEREPLY',
'Type reply address'
))
->setAttribute('style', 'min-width: 400px;'),
DropdownField::create(
'SendEmailFromFieldID',
_t(
'SilverStripe\\UserForms\\Model\\UserDefinedForm.ORSELECTAFIELDTOUSEASFROM',
'.. or select a field to use as reply to address'
),
$validEmailFromFields->map('ID', 'Title')
)->setEmptyString(' ')
)
->setTitle(_t(
'SilverStripe\\UserForms\\Model\\UserDefinedForm.REPLYADDRESS',
'Email for reply to'
))
->setDescription(_t(
'SilverStripe\\UserForms\\Model\\UserDefinedForm.REPLYADDRESS_DESCRIPTION',
'The email address which the recipient is able to \'reply\' to.'
))
]); ]);
$fields->fieldByName('Root.EmailDetails')->setTitle(_t(__CLASS__.'.EMAILDETAILSTAB', 'Email Details')); $fields->fieldByName('Root.EmailDetails')->setTitle(_t(__CLASS__ . '.EMAILDETAILSTAB', 'Email Details'));
// Only show the preview link if the recipient has been saved. // Only show the preview link if the recipient has been saved.
if (!empty($this->EmailTemplate)) { if (!empty($this->EmailTemplate)) {
@ -328,7 +234,7 @@ class EmailRecipient extends DataObject
); );
} else { } else {
$preview = sprintf( $preview = sprintf(
'<em>%s</em>', '<p class="alert alert-warning">%s</p>',
_t( _t(
'SilverStripe\\UserForms\\Model\\UserDefinedForm.PREVIEW_EMAIL_UNAVAILABLE', 'SilverStripe\\UserForms\\Model\\UserDefinedForm.PREVIEW_EMAIL_UNAVAILABLE',
'You can preview this email once you have saved the Recipient.' 'You can preview this email once you have saved the Recipient.'
@ -375,7 +281,7 @@ class EmailRecipient extends DataObject
); );
} }
$fields->fieldByName('Root.EmailContent')->setTitle(_t(__CLASS__.'.EMAILCONTENTTAB', 'Email Content')); $fields->fieldByName('Root.EmailContent')->setTitle(_t(__CLASS__ . '.EMAILCONTENTTAB', 'Email Content'));
// Custom rules for sending this field // Custom rules for sending this field
$grid = GridField::create( $grid = GridField::create(
@ -386,21 +292,29 @@ class EmailRecipient extends DataObject
); );
$grid->setDescription(_t( $grid->setDescription(_t(
'SilverStripe\\UserForms\\Model\\UserDefinedForm.RulesDescription', 'SilverStripe\\UserForms\\Model\\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.' 'Emails will only be sent to the recipient if the custom rules are met. If no rules are defined, '
. 'this recipient will receive notifications for every submission.'
)); ));
$fields->addFieldsToTab('Root.CustomRules', [ $fields->addFieldsToTab('Root.CustomRules', [
DropdownField::create( DropdownField::create(
'CustomRulesCondition', 'CustomRulesCondition',
_t('SilverStripe\\UserForms\\Model\\UserDefinedForm.SENDIF', 'Send condition'), _t('SilverStripe\\UserForms\\Model\\UserDefinedForm.SENDIF', 'Send condition'),
[ [
'Or' => _t('SilverStripe\\UserForms\\Model\\UserDefinedForm.SENDIFOR', 'Any conditions are true'), 'Or' => _t(
'And' => _t('SilverStripe\\UserForms\\Model\\UserDefinedForm.SENDIFAND', 'All conditions are true') 'SilverStripe\\UserForms\\Model\\UserDefinedForm.SENDIFOR',
'Any conditions are true'
),
'And' => _t(
'SilverStripe\\UserForms\\Model\\UserDefinedForm.SENDIFAND',
'All conditions are true'
)
] ]
), ),
$grid $grid
]); ]);
$fields->fieldByName('Root.CustomRules')->setTitle(_t(__CLASS__.'.CUSTOMRULESTAB', 'Custom Rules')); $fields->fieldByName('Root.CustomRules')->setTitle(_t(__CLASS__ . '.CUSTOMRULESTAB', 'Custom Rules'));
$this->extend('updateCMSFields', $fields); $this->extend('updateCMSFields', $fields);
return $fields; return $fields;
@ -619,4 +533,197 @@ class EmailRecipient extends DataObject
} }
return $result; return $result;
} }
/**
* @return FieldGroup|TextField
*/
protected function getSubjectCMSFields()
{
$subjectTextField = TextField::create(
'EmailSubject',
_t('SilverStripe\\UserForms\\Model\\UserDefinedForm.TYPESUBJECT', 'Type subject')
)
->setAttribute('style', 'min-width: 400px;');
if ($this->getFormParent() && $this->getValidSubjectFields()) {
return FieldGroup::create(
$subjectTextField,
DropdownField::create(
'SendEmailSubjectFieldID',
_t(
'SilverStripe\\UserForms\\Model\\UserDefinedForm.SELECTAFIELDTOSETSUBJECT',
'.. or select a field to use as the subject'
),
$this->getValidSubjectFields()->map('ID', 'Title')
)->setEmptyString('')
)
->setTitle(_t('SilverStripe\\UserForms\\Model\\UserDefinedForm.EMAILSUBJECT', 'Email subject'));
} else {
return $subjectTextField;
}
}
/**
* @return FieldGroup|TextField
*/
protected function getEmailToCMSFields()
{
$emailToTextField = TextField::create(
'EmailAddress',
_t('SilverStripe\\UserForms\\Model\\UserDefinedForm.TYPETO', 'Type to address')
)
->setAttribute('style', 'min-width: 400px;');
if ($this->getFormParent() && $this->getValidEmailToFields()) {
return FieldGroup::create(
$emailToTextField,
DropdownField::create(
'SendEmailToFieldID',
_t(
'SilverStripe\\UserForms\\Model\\UserDefinedForm.ORSELECTAFIELDTOUSEASTO',
'.. or select a field to use as the to address'
),
$this->getValidEmailToFields()->map('ID', 'Title')
)->setEmptyString(' ')
)
->setTitle(_t('SilverStripe\\UserForms\\Model\\UserDefinedForm.SENDEMAILTO', 'Send email to'))
->setDescription(_t(
'SilverStripe\\UserForms\\Model\\UserDefinedForm.SENDEMAILTO_DESCRIPTION',
'You may enter multiple email addresses as a comma separated list.'
));
} else {
return $emailToTextField;
}
}
/**
* @return TextField
*/
protected function getEmailFromCMSFields()
{
return TextField::create(
'EmailFrom',
_t('SilverStripe\\UserForms\\Model\\UserDefinedForm.FROMADDRESS', 'Send email from')
)
->setDescription(_t(
'SilverStripe\\UserForms\\Model\\UserDefinedForm.EmailFromContent',
"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. " .
"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."
));
}
/**
* @return FieldGroup|TextField
*/
protected function getEmailReplyToCMSFields()
{
$replyToTextField = TextField::create('EmailReplyTo', _t(
'SilverStripe\\UserForms\\Model\\UserDefinedForm.TYPEREPLY',
'Type reply address'
))
->setAttribute('style', 'min-width: 400px;');
if ($this->getFormParent() && $this->getValidEmailFromFields()) {
return FieldGroup::create(
$replyToTextField,
DropdownField::create(
'SendEmailFromFieldID',
_t(
'SilverStripe\\UserForms\\Model\\UserDefinedForm.ORSELECTAFIELDTOUSEASFROM',
'.. or select a field to use as reply to address'
),
$this->getValidEmailFromFields()->map('ID', 'Title')
)->setEmptyString(' ')
)
->setTitle(_t(
'SilverStripe\\UserForms\\Model\\UserDefinedForm.REPLYADDRESS',
'Email for reply to'
))
->setDescription(_t(
'SilverStripe\\UserForms\\Model\\UserDefinedForm.REPLYADDRESS_DESCRIPTION',
'The email address which the recipient is able to \'reply\' to.'
));
} else {
return $replyToTextField;
}
}
/**
* @return DataList|null
*/
protected function getMultiOptionFields()
{
if (!$form = $this->getFormParent()) {
return null;
}
return EditableMultipleOptionField::get()->filter('ParentID', $form->ID);
}
/**
* @return ArrayList|null
*/
protected function getValidSubjectFields()
{
if (!$form = $this->getFormParent()) {
return null;
}
// For the subject, only one-line entry boxes make sense
$validSubjectFields = ArrayList::create(
EditableTextField::get()
->filter('ParentID', $form->ID)
->exclude('Rows:GreaterThan', 1)
->toArray()
);
$validSubjectFields->merge($this->getMultiOptionFields());
return $validSubjectFields;
}
/**
* @return DataList|null
*/
protected function getValidEmailFromFields()
{
if (!$form = $this->getFormParent()) {
return null;
}
// if they have email fields then we could send from it
return EditableEmailField::get()->filter('ParentID', $form->ID);
}
/**
* @return ArrayList|DataList|null
*/
protected function getValidEmailToFields()
{
if (!$this->getFormParent()) {
return null;
}
// Check valid email-recipient fields
if ($this->config()->get('allow_unbound_recipient_fields')) {
// To address can only be email fields or multi option fields
$validEmailToFields = ArrayList::create($this->getValidEmailFromFields()->toArray());
$validEmailToFields->merge($this->getMultiOptionFields());
return $validEmailToFields;
} else {
// To address cannot be unbound, so restrict to pre-defined lists
return $this->getMultiOptionFields();
}
}
protected function getUnsavedFormLiteralField()
{
return LiteralField::create(
'UnsavedFormMessage',
sprintf(
'<p class="alert alert-warning">%s</p>',
_t(
'SilverStripe\\UserForms\\Model\\UserDefinedForm.EMAIL_RECIPIENT_UNSAVED_FORM',
'You will be able to select from valid form fields after saving this record.'
)
)
);
}
} }

View File

@ -221,6 +221,7 @@ en:
EMAILBODYHTML: Body EMAILBODYHTML: Body
EMAILFROM: From EMAILFROM: From
EMAILRECIPIENTS: 'Email Recipients' EMAILRECIPIENTS: 'Email Recipients'
EMAIL_RECIPIENT_UNSAVED_FORM: 'You will be able to select from valid form fields after saving this record.'
EMAILSUBJECT: 'Email subject' EMAILSUBJECT: 'Email subject'
EMAILTEMPLATE: 'Email template' EMAILTEMPLATE: 'Email template'
ENABLELIVEVALIDATION: 'Enable live validation' ENABLELIVEVALIDATION: 'Enable live validation'

View File

@ -130,7 +130,7 @@ class UserDefinedFormTest extends FunctionalTest
$fields = $popup->getCMSFields(); $fields = $popup->getCMSFields();
$this->assertThat($fields->dataFieldByName('SendEmailToFieldID'), $this->isInstanceOf(DropdownField::class)); $this->assertThat($fields->dataFieldByName('SendEmailToFieldID'), $this->isInstanceOf(DropdownField::class));
// 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 checkboxes or dropdown they can select from that can also be used to send things
$dropdown = $this->objFromFixture(EditableDropdown::class, 'department-dropdown'); $dropdown = $this->objFromFixture(EditableDropdown::class, 'department-dropdown');
$form->Fields()->add($dropdown); $form->Fields()->add($dropdown);