Skip to content

Commit 8f859f0

Browse files
authored
Add support Laravel 9 (#9)
1 parent 1b211f7 commit 8f859f0

File tree

4 files changed

+70
-112
lines changed

4 files changed

+70
-112
lines changed

README.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ Add the configuration to your mail.php config file:
1717
'microsoft-graph' => [
1818
'transport' => 'graph-api',
1919
'tenant' => env('GRAPH_API_TENANT'),
20-
'client' => env('GRAPH_API_CLIENT_ID'),
21-
'secret' => env('GRAPH_API_CLIENT_SECRET')
20+
'client_id' => env('GRAPH_API_CLIENT_ID'),
21+
'client_secret' => env('GRAPH_API_CLIENT_SECRET')
2222
]
2323
]
2424
```
@@ -31,3 +31,4 @@ Add the configuration to your mail.php config file:
3131
| 1.x.x | 5.5.x |
3232
| ^2.0 | 7.x |
3333
| ^2.0.2 | 8.x |
34+
| ^3.0 | 9.x |

composer.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@
2121
}
2222
],
2323
"require": {
24-
"php": "^7.2.5|^8.0",
25-
"guzzlehttp/guzzle": "^6.3.1|^7.0.1",
26-
"laravel/framework": "^7.0|^8.0"
24+
"php": "^8.0.2",
25+
"guzzlehttp/guzzle": "^7.2",
26+
"laravel/framework": "^9.0"
2727
},
2828
"extra": {
2929
"laravel": {

src/ServiceProvider.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22

33
namespace Mondago\MSGraph\Mail;
44

5-
use GuzzleHttp\Client;
5+
use Illuminate\Support\Facades\Mail;
66
use Illuminate\Support\ServiceProvider as LaravelServiceProvider;
77

88
class ServiceProvider extends LaravelServiceProvider
99
{
1010
public function boot()
1111
{
12-
$this->app->get('mail.manager')->extend('graph-api', function (array $config) {
13-
return new Transport(new Client(), $config);
12+
Mail::extend('graph-api', function (array $config) {
13+
return new Transport($config);
1414
});
1515
}
1616
}

src/Transport.php

+61-104
Original file line numberDiff line numberDiff line change
@@ -2,71 +2,53 @@
22

33
namespace Mondago\MSGraph\Mail;
44

5-
use GuzzleHttp\ClientInterface;
6-
use Illuminate\Mail\Transport\Transport as LaravelTransport;
7-
use Illuminate\Support\Str;
8-
9-
class Transport extends LaravelTransport
5+
use Illuminate\Support\Facades\Http;
6+
use Symfony\Component\Mailer\SentMessage;
7+
use Symfony\Component\Mailer\Transport\AbstractTransport;
8+
use Symfony\Component\Mime\Email;
9+
use Symfony\Component\Mime\MessageConverter;
10+
use Symfony\Component\Mime\Part\DataPart;
11+
12+
class Transport extends AbstractTransport
1013
{
1114
/**
1215
* Graph api configuration
1316
* @var array
1417
*/
15-
private $config;
16-
17-
private $http;
18+
private array $config;
1819

19-
public function __construct(ClientInterface $client, array $config)
20+
public function __construct(array $config)
2021
{
22+
parent::__construct(null, null);
2123
$this->config = $config;
22-
$this->http = $client;
2324
}
2425

25-
public function send(\Swift_Mime_SimpleMessage $message, &$failedRecipients = null)
26+
27+
protected function doSend(SentMessage $message): void
2628
{
27-
$this->beforeSendPerformed($message);
2829
$token = $this->getToken();
29-
$emailMessage = $this->getMessage($message);
30-
$url = sprintf('https://graph.microsoft.com/v1.0/users/%s/sendMail', urlencode($emailMessage['from']['emailAddress']['address']));
31-
32-
try {
33-
$this->http->post($url, [
34-
'headers' => [
35-
'Accept' => 'application/json',
36-
'Authorization' => sprintf('Bearer %s', $token),
37-
],
38-
'json' => [
39-
'message' => $emailMessage,
40-
],
41-
]);
42-
43-
$this->sendPerformed($message);
44-
45-
return $this->numberOfRecipients($message);
46-
47-
} catch (\Exception $e) {
48-
throw $e;
49-
}
30+
$email = MessageConverter::toEmail($message->getOriginalMessage());
31+
$url = sprintf('https://graph.microsoft.com/v1.0/users/%s/sendMail', $email->getFrom()[0]->getEncodedAddress());
32+
$response = Http::withHeaders([
33+
'Authorization' => sprintf('Bearer %s', $token)
34+
])->post($url, [
35+
"message" => $this->getMessage($email)
36+
]);
37+
$response->throw();
5038
}
5139

5240
public function getToken()
5341
{
5442
$url = sprintf('https://login.microsoftonline.com/%s/oauth2/v2.0/token', $this->config['tenant']);
55-
try {
56-
$response = $this->http->request('POST', $url, [
57-
'form_params' => [
58-
'client_id' => $this->config['client_id'],
59-
'client_secret' => $this->config['client_secret'],
60-
'scope' => 'https://graph.microsoft.com/.default',
61-
'grant_type' => 'client_credentials'
62-
],
63-
]);
64-
$data = json_decode($response->getBody()->getContents());
43+
$response = Http::asForm()->post($url, [
44+
'client_id' => $this->config['client_id'],
45+
'client_secret' => $this->config['client_secret'],
46+
'scope' => 'https://graph.microsoft.com/.default',
47+
'grant_type' => 'client_credentials'
48+
]);
49+
$response->throw();
6550

66-
return $data->access_token;
67-
} catch (\Exception $e) {
68-
throw $e;
69-
}
51+
return $response['access_token'];
7052
}
7153

7254
public function __toString(): string
@@ -75,84 +57,59 @@ public function __toString(): string
7557
}
7658

7759
/*
78-
* @link https://docs.microsoft.com/en-us/graph/api/resources/message?view=graph-rest-1.0
60+
* https://docs.microsoft.com/en-us/graph/api/resources/message?view=graph-rest-1.0
7961
*/
80-
private function getMessage(\Swift_Mime_SimpleMessage $email)
62+
private function getMessage(Email $email)
8163
{
8264
return array_filter([
83-
"from" => $this->getRecipientsCollection($email->getFrom())[0],
84-
"sender" => $this->getRecipientsCollection($email->getFrom())[0],
65+
"from" => $this->getRecipient($email->getFrom()[0]),
66+
"sender" => $this->getRecipient($email->getFrom()[0]),
8567
"toRecipients" => $this->getRecipientsCollection($email->getTo()),
8668
"ccRecipients" => $this->getRecipientsCollection($email->getCc()),
8769
"bccRecipients" => $this->getRecipientsCollection($email->getBcc()),
8870
"replyTo" => $this->getRecipientsCollection($email->getReplyTo()),
8971
"subject" => $email->getSubject(),
9072
"body" => [
91-
"contentType" => $this->getContentType($email),
92-
"content" => $email->getBody()
73+
"contentType" => $email->getTextBody() ? 'Text' : 'HTML',
74+
"content" => $email->getTextBody() ?? $email->getHtmlBody(),
9375
],
94-
"attachments" => $this->getAttachmentsCollection($email->getChildren())
76+
"attachments" => $this->getAttachmentsCollection($email->getAttachments())
9577
]);
9678
}
9779

98-
private function getRecipientsCollection($addresses): array
80+
private function getRecipientsCollection(array $addresses): array
9981
{
100-
$collection = [];
101-
if (!$addresses) {
102-
return [];
103-
}
104-
if (is_string($addresses)) {
105-
$addresses = [
106-
$addresses => null,
107-
];
108-
}
109-
110-
foreach ($addresses as $email => $name) {
111-
# https://docs.microsoft.com/en-us/graph/api/resources/recipient?view=graph-rest-1.0
112-
$collection[] = [
113-
'emailAddress' => [
114-
'name' => $name,
115-
'address' => $email,
116-
],
117-
];
118-
}
82+
return array_map('self::getRecipient', $addresses);
83+
}
11984

120-
return $collection;
85+
/*
86+
* https://docs.microsoft.com/en-us/graph/api/resources/recipient?view=graph-rest-1.0
87+
*/
88+
private function getRecipient($address): array
89+
{
90+
return [
91+
'emailAddress' => array_filter([
92+
'address' => $address->getAddress(),
93+
'name' => $address->getName(),
94+
])
95+
];
12196
}
12297

12398
private function getAttachmentsCollection($attachments)
12499
{
125-
$collection = [];
126-
127-
foreach ($attachments as $attachment) {
128-
if (!$attachment instanceof \Swift_Mime_Attachment) {
129-
continue;
130-
}
131-
// https://docs.microsoft.com/en-us/graph/api/resources/fileattachment?view=graph-rest-1.0
132-
$collection[] = [
133-
'name' => $attachment->getFilename(),
134-
'contentId' => $attachment->getId(),
135-
'contentType' => $attachment->getContentType(),
136-
'contentBytes' => base64_encode($attachment->getBody()),
137-
'size' => strlen($attachment->getBody()),
138-
'@odata.type' => '#microsoft.graph.fileAttachment',
139-
'isInline' => $attachment instanceof \Swift_Mime_EmbeddedFile,
140-
];
141-
142-
}
143-
144-
return $collection;
100+
return array_map('self::getAttachment', $attachments);
145101
}
146102

147-
public function getContentType(\Swift_Mime_SimpleMessage $email): string
103+
/*
104+
* https://docs.microsoft.com/en-us/graph/api/resources/fileattachment?view=graph-rest-1.0
105+
*/
106+
private function getAttachment(DataPart $attachment)
148107
{
149-
if (Str::contains($email->getBodyContentType(), ['html'])) {
150-
return 'HTML';
151-
} else {
152-
if (Str::contains($email->getBodyContentType(), ['text', 'plain'])) {
153-
return 'Text';
154-
}
155-
}
156-
return 'HTML';
108+
return array_filter([
109+
"@odata.type" => "#microsoft.graph.fileAttachment",
110+
"name" => $attachment->getName() ?? $attachment->getFilename(),
111+
"contentType" => $attachment->getContentType(),
112+
"contentBytes" => base64_encode($attachment->getBody()),
113+
]);
157114
}
158115
}

0 commit comments

Comments
 (0)