Skip to content

Commit

Permalink
Merge pull request #11 from swiftmade/dev
Browse files Browse the repository at this point in the history
Release v2.3.0
  • Loading branch information
aozisik authored Dec 12, 2022
2 parents 91b13ac + e35362c commit 4def6fd
Show file tree
Hide file tree
Showing 9 changed files with 275 additions and 4 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

All notable changes will be documented in this file

## 2.3.0 - 2022-12-12

- Attachments and inline attachments are now supported.

## 2.2.0 - 2022-09-24

- You can now pass nested arrays, numbers, bools as the payload. Previously, the library only accepted strings. (Thanks [timstl](https://github.com/swiftmade/laravel-sendgrid-notification-channel/pull/7))
Expand Down
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,21 @@ return (new SendGridMessage('Your SendGrid template ID'))

When making a request with sandbox mode enabled, Sendgrid will validate the form, type, and shape of your request. No email will be sent. You can read more about the sandbox mode [here](https://docs.sendgrid.com/for-developers/sending-email/sandbox-mode).

### Attachments

You can attach or embed (inline attachment) files to your messages. `SendGridMessage` object exposes the following methods to help you do that:

- `attach($file, $options)`
- `attachData($data, $name, $options)`
- `embed($file, $options)`
- `embedData($data, $name, $options)`

**Good to know:**

- While using `attachData` and `embedData` you must always pass the `mime` key in the options array.
- You can use the `as` key in the options to change the filename to appears in the email. (e.g. `attach($file, ['as' => 'invoice-3252.pdf'])`)
- `embed` and `embedData` methods will return the ContentID with `cid:` in front (e.g. `embed('avatar.jpg') -> "cid:avatar.jpg"`).

## Changelog

Please see [CHANGELOG](CHANGELOG.md) for more information what has changed recently.
Expand Down
8 changes: 6 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^3.8",
"mockery/mockery": "^1.3",
"mockery/mockery": "^1.5",
"orchestra/testbench": "^5.0|^6.0|^7.0",
"phpunit/phpunit": "^8.4|^9.0"
},
"autoload": {
Expand All @@ -34,7 +35,10 @@
},
"scripts": {
"test": "phpunit",
"test:coverage": "phpunit --coverage-text --coverage-clover=coverage.clover"
"test:coverage": "phpunit --coverage-text --coverage-clover=coverage.clover",
"post-autoload-dump": [
"@php vendor/bin/testbench package:discover --ansi"
]
},
"config": {
"sort-packages": true
Expand Down
3 changes: 3 additions & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,7 @@
<directory suffix=".php">src/</directory>
</whitelist>
</filter>
<php>
<env name="APP_KEY" value="AckfSECXIvnK5r28GVIWUAxmbBSjTsmF"/>
</php>
</phpunit>
125 changes: 125 additions & 0 deletions src/SendGridMessage.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@

namespace NotificationChannels\SendGrid;

use RuntimeException;
use SendGrid\Mail\To;
use SendGrid\Mail\From;
use SendGrid\Mail\Mail;
use SendGrid\Mail\ReplyTo;
use SendGrid\Mail\Attachment;
use Illuminate\Support\Facades\File;

class SendGridMessage
{
Expand Down Expand Up @@ -42,6 +45,13 @@ class SendGridMessage
*/
public $payload = [];

/**
* An array of attachments for the message.
*
* @var array
*/
public $attachments = [];

/**
* The sandbox mode for SendGrid
*
Expand Down Expand Up @@ -103,6 +113,116 @@ public function payload($payload)
return $this;
}

/**
* Attach a file to the message.
*
* array(
* 'as' => 'name.pdf',
* 'mime' => 'application/pdf',
* )
*
* @param string $file
* @param array $options
* @return $this
*/
public function attach($file, array $options = [])
{
if (! isset($options['mime'])) {
$options['mime'] = File::mimeType($file);
}

// TODO: Support "Attachable" and "Attachment" types.

return $this->attachData(
file_get_contents($file),
$file,
$options
);
}

/**
* Attach in-memory data as an attachment.
*
* @param string $data
* @param string $name
* @param array $options
* @return $this
*/
public function attachData($data, $name, array $options)
{
if (! isset($options['mime'])) {
throw new RuntimeException(
'Cannot predict mimetype of "' . $name . '". '
. 'Provide a valid \'mime\' in $options parameter.'
);
}

$showFilenameAs = isset($options['as'])
? $options['as']
: basename($name);

$attachment = new Attachment(
base64_encode($data),
$options['mime'],
$showFilenameAs,
isset($options['inline']) ? 'inline' : 'attachment'
);

if (isset($options['inline'])) {
$attachment->setContentID($showFilenameAs);
}

$this->attachments[] = $attachment;

return $this;
}

/**
* Add inline attachment from a file in the message and get the CID.
*
* array(
* 'as' => 'name.pdf',
* 'mime' => 'application/pdf',
* )
*
* @param string $file
* @return string
*/
public function embed($file, array $options = [])
{
if (! isset($options['mime'])) {
$options['mime'] = File::mimeType($file);
}

// TODO: Support "Attachable" and "Attachment" types.

return $this->embedData(
file_get_contents($file),
$file,
$options
);
}

/**
* Add inline attachments from in-memory data in the message and get the CID.
*
* @param string $data
* @param string $name
* @param string|null $contentType
* @return string
*/
public function embedData($data, $name, array $options)
{
$this->attachData($data, $name, array_merge(
$options,
['inline' => true]
));

$lastIndex = count($this->attachments) - 1;

return "cid:" . $this->attachments[$lastIndex]->getContentID();
}

/**
* @return Mail
*/
Expand All @@ -124,6 +244,11 @@ public function build(): Mail
$email->addDynamicTemplateData((string) $key, $value);
}

foreach ($this->attachments as $attachment) {
$email->addAttachment($attachment);
}


return $email;
}

Expand Down
1 change: 0 additions & 1 deletion tests/SendGridChannelTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
use Mockery;
use SendGrid;
use SendGrid\Response;
use PHPUnit\Framework\TestCase;
use Illuminate\Notifications\Notifiable;
use Illuminate\Notifications\Notification;
use NotificationChannels\SendGrid\SendGridChannel;
Expand Down
116 changes: 115 additions & 1 deletion tests/SendGridMessageTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace NotificationChannels\SendGrid\Test;

use PHPUnit\Framework\TestCase;
use SendGrid\Mail\Attachment;
use NotificationChannels\SendGrid\SendGridMessage;

class SendGridMessageTest extends TestCase
Expand Down Expand Up @@ -50,4 +50,118 @@ public function testSandboxMode()
'Sandbox mode is disabled in Sendgrid mail settings'
);
}

public function testAttachmentFromPath()
{
$path = __DIR__ . '/fixtures/blank.jpg';

$message = new SendGridMessage('template-id');
$message->attach(__DIR__ . '/fixtures/blank.jpg');

/**
* @var Attachment
*/
$attachment = $message->attachments[0];

// Contents are base64-encoded
$this->assertEquals(
base64_encode(file_get_contents($path)),
$attachment->getContent()
);

$this->assertEquals('blank.jpg', $attachment->getFilename());
$this->assertEquals('image/jpeg', $attachment->getType());
$this->assertEquals('attachment', $attachment->getDisposition());

// Let's test the options array.
$message->attach(__DIR__ . '/fixtures/blank.jpg', [
'as' => 'custom.png',
'mime' => 'image/png',
]);

/**
* @var Attachment
*/
$attachment2 = $message->attachments[1];
$this->assertEquals('custom.png', $attachment2->getFilename());
$this->assertEquals('image/png', $attachment2->getType());
$this->assertEquals('attachment', $attachment2->getDisposition());
}

public function testAttachmentFromData()
{
$path = __DIR__ . '/fixtures/blank.jpg';
$contents = file_get_contents($path);

$message = new SendGridMessage('template-id');
$message->attachData($contents, 'blank.jpg', ['mime' => 'image/jpeg']);

/**
* @var Attachment
*/
$attachment = $message->attachments[0];

// Contents are base64-encoded
$this->assertEquals(
base64_encode($contents),
$attachment->getContent()
);

$this->assertEquals('blank.jpg', $attachment->getFilename());
$this->assertEquals('image/jpeg', $attachment->getType());
$this->assertEquals('attachment', $attachment->getDisposition());
}

public function testEmbeddingFromPath()
{
$path = __DIR__ . '/fixtures/blank.jpg';

$message = new SendGridMessage('template-id');
$contentId = $message->embed(__DIR__ . '/fixtures/blank.jpg');

$this->assertEquals('cid:blank.jpg', $contentId);

/**
* @var Attachment
*/
$attachment = $message->attachments[0];

// Contents are base64-encoded
$this->assertEquals(
base64_encode(file_get_contents($path)),
$attachment->getContent()
);

$this->assertEquals('blank.jpg', $attachment->getFilename());
$this->assertEquals('image/jpeg', $attachment->getType());
$this->assertEquals('inline', $attachment->getDisposition());
$this->assertEquals('blank.jpg', $attachment->getContentID());
}

public function testEmbeddingFromData()
{
$path = __DIR__ . '/fixtures/blank.jpg';
$contents = file_get_contents($path);

$message = new SendGridMessage('template-id');
$contentId = $message->embedData($contents, 'blank.png', ['mime' => 'image/png']);

$this->assertEquals('cid:blank.png', $contentId);

/**
* @var Attachment
*/
$attachment = $message->attachments[0];

// Contents are base64-encoded
$this->assertEquals(
base64_encode(file_get_contents($path)),
$attachment->getContent()
);

$this->assertEquals('blank.png', $attachment->getFilename());
$this->assertEquals('image/png', $attachment->getType());
$this->assertEquals('inline', $attachment->getDisposition());
$this->assertEquals('blank.png', $attachment->getContentID());
}
}
7 changes: 7 additions & 0 deletions tests/TestCase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

namespace NotificationChannels\SendGrid\Test;

class TestCase extends \Orchestra\Testbench\TestCase
{
}
Binary file added tests/fixtures/blank.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 4def6fd

Please sign in to comment.