diff --git a/README.md b/README.md index 33552d2..b262fa3 100755 --- a/README.md +++ b/README.md @@ -62,6 +62,8 @@ and queue a new one by storing the correct data: email template - Third arguments is an array of options, possible options are * `subject`: Email's subject + * `cc`: Email's carbon copy (string with email, Array with email as key, name as value or email as value (without name)) + * `bcc`: Email's blind carbon copy (string with email, Array with email as key, name as value or email as value (without name)) * `send_at`: date time sting representing the time this email should be sent at (in UTC) * `template`: the name of the element to use as template for the email message. (maximum supported length is 100 chars) * `layout`: the name of the layout to be used to wrap email message diff --git a/config/Migrations/20211105000000_AddCCAndBccToEmailQueue.php b/config/Migrations/20211105000000_AddCCAndBccToEmailQueue.php new file mode 100644 index 0000000..f0c7827 --- /dev/null +++ b/config/Migrations/20211105000000_AddCCAndBccToEmailQueue.php @@ -0,0 +1,43 @@ +table('email_queue'); + $table->addColumn('cc', 'string', [ + 'default' => null, + 'limit' => 129, + 'null' => true, + 'after' => 'email' + ]); + $table->addColumn('bcc', 'string', [ + 'default' => null, + 'limit' => 129, + 'null' => true, + 'after' => 'cc' + ]); + $table->addIndex([ + 'cc', + ], [ + 'name' => 'BY_CC', + 'unique' => false, + ]); + $table->addIndex([ + 'bcc', + ], [ + 'name' => 'BY_BCC', + 'unique' => false, + ]); + $table->update(); + } +} diff --git a/src/Database/Type/JsonType.php b/src/Database/Type/JsonType.php index 09ccc4b..e783401 100755 --- a/src/Database/Type/JsonType.php +++ b/src/Database/Type/JsonType.php @@ -18,11 +18,7 @@ class JsonType extends BaseType implements OptionalConvertInterface */ public function toPHP($value, DriverInterface $driver) { - if ($value === null) { - return; - } - - return json_decode($value, true); + return $this->decodeJson($value); } /** @@ -33,11 +29,7 @@ public function toPHP($value, DriverInterface $driver) */ public function marshal($value) { - if (is_array($value) || $value === null) { - return $value; - } - - return json_decode($value, true); + return $this->decodeJson($value); } /** @@ -61,4 +53,27 @@ public function requiresToPhpCast(): bool { return true; } + + /** + * Returns the given value as an array (if it is json or already an array) + * or as a string (if it is already a string) + * + * @param array|string|null $value json string, array or string to decode + * @return array|string|null depending on the input, see description + */ + private function decodeJson($value) + { + if (is_array($value) || $value === null) { + return $value; + } + + $jsonDecode = json_decode($value, true); + + // check, if the value is null after json_decode to handle plain strings + if ($jsonDecode === null) { + return $value; + } + + return $jsonDecode; + } } diff --git a/src/Database/Type/SerializeType.php b/src/Database/Type/SerializeType.php index 773d785..8a7d5af 100755 --- a/src/Database/Type/SerializeType.php +++ b/src/Database/Type/SerializeType.php @@ -22,7 +22,12 @@ public function toPHP($value, DriverInterface $driver) return null; } - return unserialize($value); + try { + return unserialize($value); + } catch (\Exception $e) { + // return value, if the value isn't serialized + return $value; + } } /** diff --git a/src/EmailQueue.php b/src/EmailQueue.php index 232c97a..b3cd616 100755 --- a/src/EmailQueue.php +++ b/src/EmailQueue.php @@ -15,6 +15,8 @@ class EmailQueue * @param array $options list of options for email sending. Possible keys: * * - subject : Email's subject + * - cc: array of carbon copy + * - bcc: array of blind carbon copy * - send_at : date time sting representing the time this email should be sent at (in UTC) * - template : the name of the element to use as template for the email message * - layout : the name of the layout to be used to wrap email message @@ -22,7 +24,6 @@ class EmailQueue * - headers: Key => Value list of extra headers for the email * - theme: The View Theme to find the email templates * - config : the name of the email config to be used for sending - * * @return bool */ public static function enqueue($to, array $data, array $options = []) diff --git a/src/Model/Table/EmailQueueTable.php b/src/Model/Table/EmailQueueTable.php index bb408f7..cb58b68 100755 --- a/src/Model/Table/EmailQueueTable.php +++ b/src/Model/Table/EmailQueueTable.php @@ -48,6 +48,8 @@ public function initialize(array $config = []): void * @param array $options list of options for email sending. Possible keys: * * - subject : Email's subject + * - cc: array of carbon copy + * - bcc: array of blind carbon copy * - send_at : date time sting representing the time this email should be sent at (in UTC) * - template : the name of the element to use as template for the email message * - layout : the name of the layout to be used to wrap email message @@ -66,6 +68,8 @@ public function enqueue($to, array $data, array $options = []): bool $defaults = [ 'subject' => '', + 'cc' => '', + 'bcc' => '', 'send_at' => new FrozenTime('now'), 'template' => 'default', 'layout' => 'default', @@ -199,6 +203,8 @@ protected function _initializeSchema(TableSchemaInterface $schema): TableSchemaI $schema->setColumnType('template_vars', $type); $schema->setColumnType('headers', $type); $schema->setColumnType('attachments', $type); + $schema->setColumnType('cc', $type); + $schema->setColumnType('bcc', $type); return $schema; } diff --git a/src/Shell/PreviewShell.php b/src/Shell/PreviewShell.php index 1ab9db5..eb846c7 100755 --- a/src/Shell/PreviewShell.php +++ b/src/Shell/PreviewShell.php @@ -61,6 +61,16 @@ public function preview($e) $email = new Mailer($configName); + // set cc + if (!empty($e['cc'])) { + $email->setCC($e['cc']); + } + + // set bcc + if (!empty($e['bcc'])) { + $email->setBcc($e['bcc']); + } + if (!empty($e['attachments'])) { $email->setAttachments($e['attachments']); } diff --git a/src/Shell/SenderShell.php b/src/Shell/SenderShell.php index b415938..5fc0af4 100755 --- a/src/Shell/SenderShell.php +++ b/src/Shell/SenderShell.php @@ -115,6 +115,16 @@ public function main(): void $transport->setConfig(['additionalParameters' => "-f $from"]); } + // set cc + if (!empty($e->cc)) { + $email->setCC($e->cc); + } + + // set bcc + if (!empty($e->bcc)) { + $email->setBcc($e->bcc); + } + if (!empty($e->attachments)) { $email->setAttachments($e->attachments); } diff --git a/tests/Fixture/EmailQueueFixture.php b/tests/Fixture/EmailQueueFixture.php index 62d901c..cd1c11a 100755 --- a/tests/Fixture/EmailQueueFixture.php +++ b/tests/Fixture/EmailQueueFixture.php @@ -19,6 +19,8 @@ class EmailQueueFixture extends TestFixture public $fields = [ 'id' => ['type' => 'uuid', 'null' => false], 'email' => ['type' => 'string', 'null' => false, 'default' => null, 'length' => 100, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'], + 'cc' => ['type' => 'string', 'null' => true, 'default' => null, 'length' => 129, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'], + 'bcc' => ['type' => 'string', 'null' => true, 'default' => null, 'length' => 129, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'], 'from_name' => ['type' => 'string', 'null' => true, 'default' => null, 'length' => 100, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'], 'from_email' => ['type' => 'string', 'null' => true, 'default' => null, 'length' => 100, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'], 'subject' => ['type' => 'string', 'null' => false, 'default' => null, 'length' => 255, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'], diff --git a/tests/TestCase/Model/Table/EmailQueueTest.php b/tests/TestCase/Model/Table/EmailQueueTest.php index d85dd98..95cd941 100755 --- a/tests/TestCase/Model/Table/EmailQueueTest.php +++ b/tests/TestCase/Model/Table/EmailQueueTest.php @@ -73,6 +73,8 @@ public function testEnqueue() 'error' => null, 'from_name' => null, 'from_email' => null, + 'cc' => '', + 'bcc' => '' ]; $sendAt = new Time($result['send_at']); unset($result['id'], $result['created'], $result['modified'], $result['send_at']); @@ -197,4 +199,28 @@ public function testProxy() $this->assertEquals('custom', $email['template']); $this->assertEquals('email', $email['layout']); } + + /** + * Test cc and bcc with string and array + */ + public function testCCAndBcc() + { + $cc = ['cc@example.com', 'cc2@example.com']; + $bcc = 'bcc@example.com'; + + $result = EmailQueue::enqueue( + 'd@example.com', + ['a' => 'c'], + ['subject' => 'Hey', 'cc' => $cc, 'bcc' => $bcc, 'template' => 'custom', 'layout' => 'email'] + ); + $this->assertTrue($result); + $email = $this->EmailQueue->find() + ->where(['email' => 'd@example.com']) + ->first() + ->toArray(); + + $this->assertEquals($cc[0], $email['cc'][0]); + $this->assertEquals($cc[1], $email['cc'][1]); + $this->assertEquals($bcc, $email['bcc']); + } }