Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Mime] added classes for generating MIME messages
- Loading branch information
Showing
100 changed files
with
8,201 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <fabien@symfony.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Bridge\Twig\Mime; | ||
|
||
use League\HTMLToMarkdown\HtmlConverter; | ||
use Twig\Environment; | ||
|
||
/** | ||
* @author Fabien Potencier <fabien@symfony.com> | ||
* | ||
* @experimental in 4.3 | ||
*/ | ||
final class Renderer | ||
{ | ||
private $twig; | ||
private $context; | ||
private $converter; | ||
|
||
public function __construct(Environment $twig, array $context = []) | ||
{ | ||
$this->twig = $twig; | ||
$this->context = $context; | ||
if (class_exists(HtmlConverter::class)) { | ||
$this->converter = new HtmlConverter([ | ||
'hard_break' => true, | ||
'strip_tags' => true, | ||
'remove_nodes' => 'head style', | ||
]); | ||
} | ||
} | ||
|
||
public function render(TemplatedEmail $email): TemplatedEmail | ||
{ | ||
$email = clone $email; | ||
|
||
$vars = array_merge($this->context, $email->getContext(), [ | ||
'email' => new WrappedTemplatedEmail($this->twig, $email), | ||
]); | ||
|
||
if ($template = $email->getTemplate()) { | ||
$this->renderFull($email, $template, $vars); | ||
} | ||
|
||
if ($template = $email->getTextTemplate()) { | ||
$email->text($this->twig->render($template, $vars)); | ||
} | ||
|
||
if ($template = $email->getHtmlTemplate()) { | ||
$email->html($this->twig->render($template, $vars)); | ||
} | ||
|
||
// if text body is empty, compute one from the HTML body | ||
if (!$email->getTextBody() && null !== $html = $email->getHtmlBody()) { | ||
$email->text($this->convertHtmlToText(\is_resource($html) ? stream_get_contents($html) : $html)); | ||
} | ||
|
||
return $email; | ||
} | ||
|
||
private function renderFull(TemplatedEmail $email, string $template, array $vars): void | ||
{ | ||
$template = $this->twig->load($template); | ||
|
||
if ($template->hasBlock('subject', $vars)) { | ||
$email->subject($template->renderBlock('subject', $vars)); | ||
} | ||
|
||
if ($template->hasBlock('text', $vars)) { | ||
$email->text($template->renderBlock('text', $vars)); | ||
} | ||
|
||
if ($template->hasBlock('html', $vars)) { | ||
$email->html($template->renderBlock('html', $vars)); | ||
} | ||
|
||
if ($template->hasBlock('config', $vars)) { | ||
// we discard the output as we're only interested | ||
// in the side effect of calling email methods | ||
$template->renderBlock('config', $vars); | ||
} | ||
} | ||
|
||
private function convertHtmlToText(string $html): string | ||
{ | ||
if (null !== $this->converter) { | ||
return $this->converter->convert($html); | ||
} | ||
|
||
return strip_tags($html); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <fabien@symfony.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Bridge\Twig\Mime; | ||
|
||
use Symfony\Component\Mime\Email; | ||
|
||
/** | ||
* @author Fabien Potencier <fabien@symfony.com> | ||
* | ||
* @experimental in 4.3 | ||
*/ | ||
class TemplatedEmail extends Email | ||
{ | ||
private $template; | ||
private $htmlTemplate; | ||
private $textTemplate; | ||
private $context = []; | ||
|
||
/** | ||
* @return $this | ||
*/ | ||
public function template(?string $template) | ||
{ | ||
$this->template = $template; | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* @return $this | ||
*/ | ||
public function textTemplate(?string $template) | ||
{ | ||
$this->textTemplate = $template; | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* @return $this | ||
*/ | ||
public function htmlTemplate(?string $template) | ||
{ | ||
$this->htmlTemplate = $template; | ||
|
||
return $this; | ||
} | ||
|
||
public function getTemplate(): ?string | ||
{ | ||
return $this->template; | ||
} | ||
|
||
public function getTextTemplate(): ?string | ||
{ | ||
return $this->textTemplate; | ||
} | ||
|
||
public function getHtmlTemplate(): ?string | ||
{ | ||
return $this->htmlTemplate; | ||
} | ||
|
||
/** | ||
* @return $this | ||
*/ | ||
public function context(array $context) | ||
{ | ||
$this->context = $context; | ||
|
||
return $this; | ||
} | ||
|
||
public function getContext(): array | ||
{ | ||
return $this->context; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,199 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <fabien@symfony.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Bridge\Twig\Mime; | ||
|
||
use Symfony\Component\Mime\Address; | ||
use Symfony\Component\Mime\NamedAddress; | ||
use Twig\Environment; | ||
|
||
/** | ||
* @internal | ||
* | ||
* @author Fabien Potencier <fabien@symfony.com> | ||
* | ||
* @experimental in 4.3 | ||
*/ | ||
final class WrappedTemplatedEmail | ||
{ | ||
private $twig; | ||
private $message; | ||
|
||
public function __construct(Environment $twig, TemplatedEmail $message) | ||
{ | ||
$this->twig = $twig; | ||
$this->message = $message; | ||
} | ||
|
||
public function toName(): string | ||
{ | ||
$to = $this->message->getTo()[0]; | ||
|
||
return $to instanceof NamedAddress ? $to->getName() : ''; | ||
} | ||
|
||
public function image(string $image, string $contentType = null): string | ||
{ | ||
$file = $this->twig->getLoader()->getSourceContext($image); | ||
if ($path = $file->getPath()) { | ||
$this->message->embedFromPath($path, $image, $contentType); | ||
} else { | ||
$this->message->embed($file->getCode(), $image, $contentType); | ||
} | ||
|
||
return 'cid:'.$image; | ||
} | ||
|
||
public function attach(string $file, string $name = null, string $contentType = null): void | ||
{ | ||
$file = $this->twig->getLoader()->getSourceContext($file); | ||
if ($path = $file->getPath()) { | ||
$this->message->attachFromPath($path, $name, $contentType); | ||
} else { | ||
$this->message->attach($file->getCode(), $name, $contentType); | ||
} | ||
} | ||
|
||
/** | ||
* @return $this | ||
*/ | ||
public function setSubject(string $subject) | ||
{ | ||
$this->message->subject($subject); | ||
|
||
return $this; | ||
} | ||
|
||
public function getSubject(): ?string | ||
{ | ||
return $this->message->getSubject(); | ||
} | ||
|
||
/** | ||
* @return $this | ||
*/ | ||
public function setReturnPath(string $address) | ||
{ | ||
$this->message->returnPath($address); | ||
|
||
return $this; | ||
} | ||
|
||
public function getReturnPath(): string | ||
{ | ||
return $this->message->getReturnPath(); | ||
} | ||
|
||
/** | ||
* @return $this | ||
*/ | ||
public function addFrom(string $address, string $name = null) | ||
{ | ||
$this->message->addFrom($name ? new NamedAddress($address, $name) : new Address($address)); | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* @return (Address|NamedAddress)[] | ||
*/ | ||
public function getFrom(): array | ||
{ | ||
return $this->message->getFrom(); | ||
} | ||
|
||
/** | ||
* @return $this | ||
*/ | ||
public function addReplyTo(string $address) | ||
{ | ||
$this->message->addReplyTo($address); | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* @return Address[] | ||
*/ | ||
public function getReplyTo(): array | ||
{ | ||
return $this->message->getReplyTo(); | ||
} | ||
|
||
/** | ||
* @return $this | ||
*/ | ||
public function addTo(string $address, string $name = null) | ||
{ | ||
$this->message->addTo($name ? new NamedAddress($address, $name) : new Address($address)); | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* @return (Address|NamedAddress)[] | ||
*/ | ||
public function getTo(): array | ||
{ | ||
return $this->message->getTo(); | ||
} | ||
|
||
/** | ||
* @return $this | ||
*/ | ||
public function addCc(string $address, string $name = null) | ||
{ | ||
$this->message->addCc($name ? new NamedAddress($address, $name) : new Address($address)); | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* @return (Address|NamedAddress)[] | ||
*/ | ||
public function getCc(): array | ||
{ | ||
return $this->message->getCc(); | ||
} | ||
|
||
/** | ||
* @return $this | ||
*/ | ||
public function addBcc(string $address, string $name = null) | ||
{ | ||
$this->message->addBcc($name ? new NamedAddress($address, $name) : new Address($address)); | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* @return (Address|NamedAddress)[] | ||
*/ | ||
public function getBcc(): array | ||
{ | ||
return $this->message->getBcc(); | ||
} | ||
|
||
/** | ||
* @return $this | ||
*/ | ||
public function setPriority(int $priority) | ||
{ | ||
$this->message->setPriority($priority); | ||
|
||
return $this; | ||
} | ||
|
||
public function getPriority(): int | ||
{ | ||
return $this->message->getPriority(); | ||
} | ||
} |
Oops, something went wrong.