diff --git a/code/Model/Recipient/EmailRecipient.php b/code/Model/Recipient/EmailRecipient.php index 7343fa7..01ae893 100644 --- a/code/Model/Recipient/EmailRecipient.php +++ b/code/Model/Recipient/EmailRecipient.php @@ -2,7 +2,6 @@ namespace SilverStripe\UserForms\Model\Recipient; -use SilverStripe\Admin\LeftAndMain; use SilverStripe\Assets\FileFinder; use SilverStripe\CMS\Controllers\CMSMain; use SilverStripe\CMS\Controllers\CMSPageEditController; @@ -27,14 +26,18 @@ use SilverStripe\Forms\TabSet; use SilverStripe\Forms\TextareaField; use SilverStripe\Forms\TextField; use SilverStripe\ORM\ArrayList; +use SilverStripe\ORM\DataList; use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DB; use SilverStripe\ORM\FieldType\DBField; +use SilverStripe\ORM\ValidationResult; +use SilverStripe\Security\Member; use SilverStripe\UserForms\Model\EditableFormField; use SilverStripe\UserForms\Model\EditableFormField\EditableEmailField; use SilverStripe\UserForms\Model\EditableFormField\EditableMultipleOptionField; use SilverStripe\UserForms\Model\EditableFormField\EditableTextField; use SilverStripe\UserForms\Model\UserDefinedForm; +use SilverStripe\UserForms\UserForm; use SilverStripe\View\Requirements; use Symbiote\GridFieldExtensions\GridFieldAddNewInlineButton; use Symbiote\GridFieldExtensions\GridFieldEditableColumns; @@ -75,7 +78,7 @@ class EmailRecipient extends DataObject 'CustomRules', ]; - private static $cascade_deetes = [ + private static $cascade_deletes = [ '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() { // LeftAndMain::sessionNamespace is protected. @todo replace this with a non-deprecated equivalent. $sessionNamespace = $this->config()->get('session_namespace') ?: CMSMain::class; - $formID = $this->FormID - ? $this->FormID - : Controller::curr()->getRequest()->getSession()->get($sessionNamespace . '.currentPage'); - return UserDefinedForm::get()->byID($formID); + $formID = $this->FormID ?: Controller::curr()->getRequest()->getSession()->get($sessionNamespace . '.currentPage'); + $formClass = $this->FormClass ?: UserDefinedForm::class; + + return $formClass::get()->byID($formID); } public function getTitle() @@ -156,6 +159,9 @@ class EmailRecipient extends DataObject */ protected function getRulesConfig() { + if (!$this->getFormParent()) { + return null; + } $formFields = $this->getFormParent()->Fields(); $config = GridFieldConfig::create() @@ -190,122 +196,22 @@ class EmailRecipient extends DataObject { 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 $fields = FieldList::create(Tabset::create('Root')->addExtraClass('EmailRecipientForm')); + if (!$this->getFormParent()) { + $fields->addFieldToTab('Root.EmailDetails', $this->getUnsavedFormLiteralField()); + } + // Configuration fields $fields->addFieldsToTab('Root.EmailDetails', [ - // Subject - FieldGroup::create( - TextField::create( - 'EmailSubject', - _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.' - )) + $this->getSubjectCMSFields(), + $this->getEmailToCMSFields(), + $this->getEmailFromCMSFields(), + $this->getEmailReplyToCMSFields(), ]); - $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. if (!empty($this->EmailTemplate)) { @@ -328,7 +234,7 @@ class EmailRecipient extends DataObject ); } else { $preview = sprintf( - '%s', + '

%s

', _t( 'SilverStripe\\UserForms\\Model\\UserDefinedForm.PREVIEW_EMAIL_UNAVAILABLE', '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 $grid = GridField::create( @@ -386,21 +292,29 @@ class EmailRecipient extends DataObject ); $grid->setDescription(_t( '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', [ DropdownField::create( 'CustomRulesCondition', _t('SilverStripe\\UserForms\\Model\\UserDefinedForm.SENDIF', 'Send condition'), [ - 'Or' => _t('SilverStripe\\UserForms\\Model\\UserDefinedForm.SENDIFOR', 'Any conditions are true'), - 'And' => _t('SilverStripe\\UserForms\\Model\\UserDefinedForm.SENDIFAND', 'All conditions are true') + 'Or' => _t( + 'SilverStripe\\UserForms\\Model\\UserDefinedForm.SENDIFOR', + 'Any conditions are true' + ), + 'And' => _t( + 'SilverStripe\\UserForms\\Model\\UserDefinedForm.SENDIFAND', + 'All conditions are true' + ) ] ), $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); return $fields; @@ -619,4 +533,197 @@ class EmailRecipient extends DataObject } 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( + '

%s

', + _t( + 'SilverStripe\\UserForms\\Model\\UserDefinedForm.EMAIL_RECIPIENT_UNSAVED_FORM', + 'You will be able to select from valid form fields after saving this record.' + ) + ) + ); + } } diff --git a/lang/en.yml b/lang/en.yml index c4f528e..a91fbad 100644 --- a/lang/en.yml +++ b/lang/en.yml @@ -221,6 +221,7 @@ en: EMAILBODYHTML: Body EMAILFROM: From EMAILRECIPIENTS: 'Email Recipients' + EMAIL_RECIPIENT_UNSAVED_FORM: 'You will be able to select from valid form fields after saving this record.' EMAILSUBJECT: 'Email subject' EMAILTEMPLATE: 'Email template' ENABLELIVEVALIDATION: 'Enable live validation' diff --git a/tests/Model/UserDefinedFormTest.php b/tests/Model/UserDefinedFormTest.php index a3cccff..7ba426a 100644 --- a/tests/Model/UserDefinedFormTest.php +++ b/tests/Model/UserDefinedFormTest.php @@ -130,7 +130,7 @@ class UserDefinedFormTest extends FunctionalTest $fields = $popup->getCMSFields(); $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'); $form->Fields()->add($dropdown);