From 2f0aea847ae734386ed8f01853b8828054da53fc Mon Sep 17 00:00:00 2001 From: Garion Herman Date: Fri, 3 May 2019 15:55:59 +1200 Subject: [PATCH] Add presence validation for EmailRecipient recipient, add error handling --- code/Control/UserDefinedFormController.php | 30 ++++++++++++++++---- code/Model/Recipient/EmailRecipient.php | 6 ++++ tests/Model/Recipient/EmailRecipientTest.php | 11 +++++++ tests/Model/UserDefinedFormTest.php | 4 ++- 4 files changed, 44 insertions(+), 7 deletions(-) diff --git a/code/Control/UserDefinedFormController.php b/code/Control/UserDefinedFormController.php index ae42217..e2a6ec6 100644 --- a/code/Control/UserDefinedFormController.php +++ b/code/Control/UserDefinedFormController.php @@ -2,13 +2,16 @@ namespace SilverStripe\UserForms\Control; +use Exception; use PageController; +use Psr\Log\LoggerInterface; use SilverStripe\Assets\File; use SilverStripe\Assets\Upload; use SilverStripe\Control\Controller; use SilverStripe\Control\Email\Email; use SilverStripe\Control\HTTPResponse; use SilverStripe\Control\HTTPRequest; +use SilverStripe\Core\Injector\Injector; use SilverStripe\Core\Manifest\ModuleLoader; use SilverStripe\Forms\Form; use SilverStripe\i18n\i18n; @@ -23,6 +26,7 @@ use SilverStripe\UserForms\Model\Submission\SubmittedForm; use SilverStripe\View\ArrayData; use SilverStripe\View\Requirements; use SilverStripe\View\SSViewer; +use Swift_RfcComplianceException; /** * Controller for the {@link UserDefinedForm} page type. @@ -350,16 +354,30 @@ JS // check to see if they are a dynamic reciever eg based on a dropdown field a user selected $emailTo = $recipient->SendEmailToField(); - if ($emailTo && $emailTo->exists()) { - $submittedFormField = $submittedFields->find('Name', $recipient->SendEmailToField()->Name); - if ($submittedFormField && is_string($submittedFormField->Value)) { - $email->setTo(explode(',', $submittedFormField->Value)); + try { + if ($emailTo && $emailTo->exists()) { + $submittedFormField = $submittedFields->find('Name', $recipient->SendEmailToField()->Name); + + if ($submittedFormField && is_string($submittedFormField->Value)) { + $email->setTo(explode(',', $submittedFormField->Value)); + } else { + $email->setTo(explode(',', $recipient->EmailAddress)); + } } else { $email->setTo(explode(',', $recipient->EmailAddress)); } - } else { - $email->setTo(explode(',', $recipient->EmailAddress)); + } catch (Swift_RfcComplianceException $e) { + // The sending address is empty and/or invalid. Log and skip sending. + $error = sprintf( + 'Failed to set sender for userform submission %s: %s', + $submittedForm->ID, + $e->getMessage() + ); + + Injector::inst()->get(LoggerInterface::class)->notice($error); + + continue; } // check to see if there is a dynamic subject diff --git a/code/Model/Recipient/EmailRecipient.php b/code/Model/Recipient/EmailRecipient.php index 8201842..6f33922 100644 --- a/code/Model/Recipient/EmailRecipient.php +++ b/code/Model/Recipient/EmailRecipient.php @@ -550,6 +550,12 @@ class EmailRecipient extends DataObject if (!$this->EmailFrom && empty(Email::getSendAllEmailsFrom()) && empty(Email::config()->get('admin_email'))) { $result->addError(_t(__CLASS__.".EMAILFROMREQUIRED", '"Email From" address is required')); } + + // Sending will also fail if there's no recipient defined + if (!$this->EmailAddress && !$this->SendEmailToFieldID) { + $result->addError(_t(__CLASS__.".EMAILTOREQUIRED", '"Send email to" address or field is required')); + } + return $result; } diff --git a/tests/Model/Recipient/EmailRecipientTest.php b/tests/Model/Recipient/EmailRecipientTest.php index 92c95bb..742e1e6 100644 --- a/tests/Model/Recipient/EmailRecipientTest.php +++ b/tests/Model/Recipient/EmailRecipientTest.php @@ -27,4 +27,15 @@ class EmailRecipientTest extends SapphireTest $result = $recipient->getEmailBodyContent(); $this->assertContains('/about-us/', $result); } + + /** + * @expectedException SilverStripe\ORM\ValidationException + * @expectedExceptionMessage "Send email to" address or field is required + */ + public function testEmptyRecipientFailsValidation() + { + $recipient = new EmailRecipient(); + $recipient->EmailFrom = 'test@example.com'; + $recipient->write(); + } } diff --git a/tests/Model/UserDefinedFormTest.php b/tests/Model/UserDefinedFormTest.php index ef6a638..7f3ae51 100644 --- a/tests/Model/UserDefinedFormTest.php +++ b/tests/Model/UserDefinedFormTest.php @@ -104,7 +104,6 @@ class UserDefinedFormTest extends FunctionalTest $this->assertNotContains('SummaryHide', array_keys($summaryFields), 'Summary field showing displayed field'); } - public function testEmailRecipientPopup() { $this->logInWithPermission('ADMIN'); @@ -114,6 +113,7 @@ class UserDefinedFormTest extends FunctionalTest $popup = new EmailRecipient(); $popup->FormID = $form->ID; $popup->FormClass = UserDefinedForm::class; + $popup->EmailAddress = 'test@example.com'; $fields = $popup->getCMSFields(); @@ -146,6 +146,7 @@ class UserDefinedFormTest extends FunctionalTest public function testGetEmailBodyContent() { $recipient = new EmailRecipient(); + $recipient->EmailAddress = 'test@example.com'; $emailBody = 'not html'; $emailBodyHtml = '

html

'; @@ -185,6 +186,7 @@ class UserDefinedFormTest extends FunctionalTest $recipient = new EmailRecipient(); $recipient->FormID = $page->ID; $recipient->FormClass = UserDefinedForm::class; + $recipient->EmailAddress = 'test@example.com'; // Set the default template $recipient->EmailTemplate = current(array_keys($recipient->getEmailTemplateDropdownValues()));