From b116e9e8c325048daabe388d9202fe6410d05c33 Mon Sep 17 00:00:00 2001 From: arnoson Date: Tue, 14 Mar 2023 11:45:30 +0100 Subject: [PATCH 1/3] Allow body in email action --- src/Actions/EmailAction.php | 29 ++++++++++++++++++++++------- tests/Actions/EmailActionTest.php | 14 ++++++++++++++ 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/src/Actions/EmailAction.php b/src/Actions/EmailAction.php index d7314d8..3eb5ebf 100644 --- a/src/Actions/EmailAction.php +++ b/src/Actions/EmailAction.php @@ -3,7 +3,6 @@ namespace Uniform\Actions; use Exception; -use Uniform\Form; use Kirby\Cms\App; use Kirby\Toolkit\Str; use Kirby\Toolkit\I18n; @@ -100,12 +99,13 @@ protected function sendEmail(array $params) } /** - * Get the email subject and resolve possible template strings - * + * Resolve template strings + * + * @param string $string + * * @return string */ - protected function getSubject() - { + protected function resolveTemplate($string) { // the form could contain arrays which are incompatible with the template function $templatableItems = array_filter($this->form->data(), function ($item) { return is_scalar($item); @@ -119,14 +119,24 @@ protected function getSubject() $fallback = ''; } - $subject = Str::template($this->option('subject', I18n::translate('uniform-email-subject')), $templatableItems, $fallback); + return Str::template($string, $templatableItems, $fallback); + } + + /** + * Get the email subject and resolve possible template strings + * + * @return string + */ + protected function getSubject() + { + $subject = $this->resolveTemplate($this->option('subject', I18n::translate('uniform-email-subject'))); // Remove newlines to prevent malicious modifications of the email header. return str_replace("\n", '', $subject); } /** - * Get the email body + * Get the email body and resolve possible template strings * * @param array $data * @@ -136,6 +146,11 @@ protected function getBody($data) { unset($data[self::EMAIL_KEY]); unset($data[self::RECEIVE_COPY_KEY]); + + if (isset($data['body'])) { + return $this->resolveTemplate($data['body']); + } + $body = ''; foreach ($data as $key => $value) { if (is_array($value)) { diff --git a/tests/Actions/EmailActionTest.php b/tests/Actions/EmailActionTest.php index 0a1bed2..b5dce20 100644 --- a/tests/Actions/EmailActionTest.php +++ b/tests/Actions/EmailActionTest.php @@ -127,6 +127,20 @@ public function testBody() $this->assertEquals($expect, $action->email->body()->text()); } + public function testBodyTemplate() + { + $this->form->data('email', 'joe@user.com'); + $this->form->data('name', 'Joe'); + $this->form->data('data', ['somedata']); + $action = new EmailActionStub($this->form, [ + 'to' => 'jane@user.com', + 'from' => 'info@user.com', + 'body' => "Hello\n{{name}} with {{data}}" + ]); + $action->perform(); + $this->assertEquals("Hello\nJoe with ", $action->email->body()->text()); + } + public function testBodyEscapeHtml() { $this->form->data('email', 'joe@user.com'); From 87a1c4762886040376c28318f593880a62f019ea Mon Sep 17 00:00:00 2001 From: arnoson Date: Tue, 14 Mar 2023 11:59:14 +0100 Subject: [PATCH 2/3] Use `body` from params not data --- src/Actions/EmailAction.php | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/Actions/EmailAction.php b/src/Actions/EmailAction.php index 3eb5ebf..d3250e2 100644 --- a/src/Actions/EmailAction.php +++ b/src/Actions/EmailAction.php @@ -55,6 +55,8 @@ public function perform() '_data' => $params['data'], '_options' => $this->options, ]); + } else if (isset($params['body']) && is_string($params['body'])) { + $params['body'] = $this->resolveTemplate($params['body']); } else { $params['body'] = $this->getBody($this->form->data('', '', $escape)); } @@ -130,13 +132,13 @@ protected function resolveTemplate($string) { protected function getSubject() { $subject = $this->resolveTemplate($this->option('subject', I18n::translate('uniform-email-subject'))); - + // Remove newlines to prevent malicious modifications of the email header. return str_replace("\n", '', $subject); } /** - * Get the email body and resolve possible template strings + * Get the email body * * @param array $data * @@ -147,10 +149,6 @@ protected function getBody($data) unset($data[self::EMAIL_KEY]); unset($data[self::RECEIVE_COPY_KEY]); - if (isset($data['body'])) { - return $this->resolveTemplate($data['body']); - } - $body = ''; foreach ($data as $key => $value) { if (is_array($value)) { From f7727e2d7f1d02a64a9e6013ef62d68529780862 Mon Sep 17 00:00:00 2001 From: arnoson Date: Wed, 15 Mar 2023 13:20:17 +0100 Subject: [PATCH 3/3] Update docs --- docs/actions/email.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/docs/actions/email.md b/docs/actions/email.md index 0dd611e..b50a9e7 100644 --- a/docs/actions/email.md +++ b/docs/actions/email.md @@ -1,6 +1,6 @@ # Email Action -This actions sends the form data by email. In its simplest form it just appends all form fields in `name: value` pairs as plain text. But it can use a [snippet](#snippet) to build the email, too. You can use snippets to send HTML instead of plain text emails, too. +This actions sends the form data by email. In its simplest form it just appends all form fields in `name: value` pairs as plain text. But it can use a custom [body](#body) or [template](#template) to build the email, too. You can use templates to send HTML instead of plain text emails, too. If there is an `email` field in the form data, the action will use it as `replyTo` of the sent email and remove it from the email body. If there is a `receive_copy` field present (e.g. a checkbox) and the [receive-copy](#receive-copy) option is set, the action will send a copy of the email to the address specified in the `email` field. The subject of this copy email will get the `uniform-email-copy` prefix. @@ -80,6 +80,18 @@ Check out the email templates of the [Uniform repo](https://github.com/mzur/kirb !!! warning "Note" You cannot access form fields with the name `_data` or `_options` directly in the template as these are reserved for the additional variables provided by Uniform. Use `$_data['_data']` and `$_data['_options']` in this case. +### body + +The body of the email. If not specified, the form data will be used as the body (`name: value` pairs as plain text). The body supports templates, too, so you can dynamically add form data to it. A template is a name of a form field surrounded by `{{}}`. Example: + +```php +'body' => 'Dear {{name}}, we will get back to you soon!', +``` +The body will only be used, if no [template](#template) is specified. + +!!! warning "Note" + Body templates do not work with [array form fields](http://stackoverflow.com/a/1978788/1796523). + ### replyTo Set a static email address as `replyTo` of the email instead of the value of the `email` form field.