diff --git a/doc/index.md b/doc/index.md index ed98f37..885d483 100644 --- a/doc/index.md +++ b/doc/index.md @@ -92,6 +92,26 @@ $parameters = [ ]; $mailgun->messages()->send('example.com', $parameters); ``` +#### Send a message with Mime + +Below in an example how to create a Mime message with SwiftMailer. + +```php +$message = \Swift_Message::newInstance('Mail Subject'); +$message->setFrom(['from@exemple.com' => 'Example Inc']); +$message->setTo(['user0gmail.com' => 'User 0', 'user1@hotmail.com' => 'User 1']); +// $message->setBcc('admin@example.com'); Do not do this, BCC will be visible for all receipients if you do. +$message->setCc('invoice@example.com'); + +$messageBody = 'Look at the fancy HTML body.'; +$message->setBody($messageBody, 'text/html'); + +// We need all "tos". Incluce the BCC here. +$to = ['admin@example.com', 'user0gmail.com', 'user1@hotmail.com', 'invoice@example.com'] + +// Send the message +$mailgun->messages()->sendMime('example.com', $to, $message->toString()); +``` #### Show a stored message @@ -154,7 +174,6 @@ $mailgun->stats()->total('example.com'); $mailgun->stats()->all('example.com'); ``` - ## Suppression API The suppression API consists of 3 parts; `Bounce`, `Complaint` and `Unsubscribe`. diff --git a/src/Mailgun/Api/Message.php b/src/Mailgun/Api/Message.php index bf12caa..cdbfd87 100644 --- a/src/Mailgun/Api/Message.php +++ b/src/Mailgun/Api/Message.php @@ -20,59 +20,74 @@ use Mailgun\Model\Message\ShowResponse; class Message extends HttpApi { /** - * @param $domain - * @param array $params + * @param string $domain + * @param array $params * * @return SendResponse */ public function send($domain, array $params) { + Assert::string($domain); Assert::notEmpty($domain); Assert::notEmpty($params); $postDataMultipart = []; - $fields = ['message', 'attachment', 'inline']; + $fields = ['attachment', 'inline']; foreach ($fields as $fieldName) { if (!isset($params[$fieldName])) { continue; } - if (!is_array($params[$fieldName])) { - $postDataMultipart[] = $this->prepareFile($fieldName, $params[$fieldName]); - } else { - foreach ($params[$fieldName] as $file) { - $postDataMultipart[] = $this->prepareFile($fieldName, $file); - } + + Assert::isArray($params[$fieldName]); + foreach ($params[$fieldName] as $file) { + $postDataMultipart[] = $this->prepareFile($fieldName, $file); } unset($params[$fieldName]); } - foreach ($params as $key => $value) { - if (is_array($value)) { - foreach ($value as $subValue) { - $postDataMultipart[] = [ - 'name' => $key, - 'content' => $subValue, - ]; - } - } else { - $postDataMultipart[] = [ - 'name' => $key, - 'content' => $value, - ]; - } - } - + $postDataMultipart = array_merge($this->prepareMultipartParameters($params), $postDataMultipart); $response = $this->httpPostRaw(sprintf('/v3/%s/messages', $domain), $postDataMultipart); return $this->hydrateResponse($response, SendResponse::class); } + /** + * @param string $domain + * @param array $recipients with all you send emails to. Including bcc and cc + * @param string $message Message filepath or content + * @param array $params + */ + public function sendMime($domain, array $recipients, $message, array $params) + { + Assert::string($domain); + Assert::notEmpty($domain); + Assert::notEmpty($recipients); + Assert::notEmpty($message); + Assert::nullOrIsArray($params); + + $params['to'] = $recipients; + $postDataMultipart = $this->prepareMultipartParameters($params); + + if (is_file($message)) { + $fileData = ['filePath' => $message]; + } else { + $fileData = [ + 'fileContent' => $message, + 'filename' => 'message', + ]; + } + $postDataMultipart[] = $this->prepareFile('message', $fileData); + $response = $this->httpPostRaw(sprintf('/v3/%s/messages.mime', $domain), $postDataMultipart); + + return $this->hydrateResponse($response, SendResponse::class); + } + /** * Get stored message. * * @param string $url - * @param bool $rawMessage if true we will use "Accept: message/rfc2822" header. + * @param bool $rawMessage if true we will use "Accept: message/rfc2822" header * * @return ShowResponse */ @@ -129,4 +144,27 @@ class Message extends HttpApi 'filename' => $filename, ]; } + + /** + * Prepare multipart parameters. Make sure each POST parameter is splitted into an array with 'name' and 'content' keys. + * + * @param array $params + * + * @return array + */ + private function prepareMultipartParameters(array $params) + { + $postDataMultipart = []; + foreach ($params as $key => $value) { + // If $value is not an array we cast it to an array + foreach ((array) $value as $subValue) { + $postDataMultipart[] = [ + 'name' => $key, + 'content' => $subValue, + ]; + } + } + + return $postDataMultipart; + } } diff --git a/tests/Api/MessageTest.php b/tests/Api/MessageTest.php new file mode 100644 index 0000000..6b857fc --- /dev/null +++ b/tests/Api/MessageTest.php @@ -0,0 +1,71 @@ + + */ +class MessageTest extends TestCase +{ + public function testSendMime() + { + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('httpPostRaw') + ->with('/v3/foo/messages.mime', + $this->callback(function ($multipartBody) { + $parameters = ['o:Foo' => 'bar', 'to' => 'mailbox@myapp.com']; + + // Verify all parameters + foreach ($parameters as $name => $content) { + $found = false; + foreach ($multipartBody as $body) { + if ($body['name'] === $name && $body['content'] === $content) { + $found = true; + } + } + if (!$found) { + return false; + } + } + + $found = false; + foreach ($multipartBody as $body) { + if ($body['name'] === 'message') { + // Make sure message exists. + $found = true; + // Make sure content is what we expect + if (!is_resource($body['content'])) { + return false; + } + } + } + if (!$found) { + return false; + } + + return true; + })) + ->willReturn(new Response()); + + $api->sendMime('foo', ['mailbox@myapp.com'], 'mime message', ['o:Foo' => 'bar']); + } + + /** + * {@inheritdoc} + */ + protected function getApiClass() + { + return Message::class; + } +} diff --git a/tests/MailgunTest.php b/tests/MailgunTest.php index 23d4a1e..adc30fd 100644 --- a/tests/MailgunTest.php +++ b/tests/MailgunTest.php @@ -59,12 +59,4 @@ class MailgunTest extends \Mailgun\Tests\MailgunTestCase $this->assertInstanceOf('stdClass', $response); $this->assertEquals($response->http_response_code, 200); } - - public function testGetAttachmentFail() - { - $this->setExpectedException('\\Mailgun\\Connection\\Exceptions\\GenericHTTPError'); - $attachmentUrl = 'https://api.mailgun.net/non.existing.uri/1/2/3'; - $client = new Mailgun('key-3ax6xnjp29jd6fds4gc373sgvjxteol0'); - $client->getAttachment($attachmentUrl); - } }