Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 58d28b0

Browse files
committed
[Twig] Add NotificationEmail
1 parent 1efae63 commit 58d28b0

File tree

15 files changed

+2121
-14
lines changed

15 files changed

+2121
-14
lines changed

composer.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,10 @@
119119
"egulias/email-validator": "~1.2,>=1.2.8|~2.0",
120120
"symfony/phpunit-bridge": "^3.4.31|^4.3.4|~5.0",
121121
"symfony/security-acl": "~2.8|~3.0",
122-
"phpdocumentor/reflection-docblock": "^3.0|^4.0"
122+
"phpdocumentor/reflection-docblock": "^3.0|^4.0",
123+
"twig/cssinliner-extra": "^2.12",
124+
"twig/inky-extra": "^2.12",
125+
"twig/markdown-extra": "^2.12"
123126
},
124127
"conflict": {
125128
"masterminds/html5": "<2.6",

src/Symfony/Bridge/Twig/Mime/BodyRenderer.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public function render(Message $message): void
4747

4848
$messageContext = $message->getContext();
4949
if (isset($messageContext['email'])) {
50-
throw new InvalidArgumentException(sprintf('A "%s" context cannot have an "email" entry as this is a reserved variable.', TemplatedEmail::class));
50+
throw new InvalidArgumentException(sprintf('A "%s" context cannot have an "email" entry as this is a reserved variable.', \get_class($message)));
5151
}
5252

5353
$vars = array_merge($this->context, $messageContext, [
Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bridge\Twig\Mime;
13+
14+
use Symfony\Component\ErrorRenderer\Exception\FlattenException;
15+
use Symfony\Component\Mime\Header\Headers;
16+
use Symfony\Component\Mime\Part\AbstractPart;
17+
use Twig\Extra\CssInliner\CssInlinerExtension;
18+
use Twig\Extra\Inky\InkyExtension;
19+
use Twig\Extra\Markdown\MarkdownExtension;
20+
21+
/**
22+
* @author Fabien Potencier <[email protected]>
23+
*/
24+
class NotificationEmail extends TemplatedEmail
25+
{
26+
public const IMPORTANCE_URGENT = 'urgent';
27+
public const IMPORTANCE_HIGH = 'high';
28+
public const IMPORTANCE_MEDIUM = 'medium';
29+
public const IMPORTANCE_LOW = 'low';
30+
31+
private const DEFAULT_THEME = '@email/zurb_2/notification';
32+
33+
private static $defaultTheme = self::DEFAULT_THEME;
34+
35+
private $theme;
36+
private $context = [
37+
'importance' => self::IMPORTANCE_LOW,
38+
'content' => '',
39+
'exception' => false,
40+
'action_text' => null,
41+
'action_url' => null,
42+
'markdown' => false,
43+
'raw' => false,
44+
];
45+
46+
public function __construct(Headers $headers = null, AbstractPart $body = null)
47+
{
48+
if (!class_exists(CssInlinerExtension::class)) {
49+
throw new \LogicException(sprintf('You cannot use "%s" if the CSS Inliner Twig extension is not available; try running "composer require twig/cssinliner-extra".', static::class));
50+
}
51+
52+
if (!class_exists(InkyExtension::class)) {
53+
throw new \LogicException(sprintf('You cannot use "%s" if the Inky Twig extension is not available; try running "composer require twig/inky-extra".', static::class));
54+
}
55+
56+
parent::__construct($headers, $body);
57+
}
58+
59+
/**
60+
* @return $this
61+
*/
62+
public function markdown()
63+
{
64+
if (!class_exists(MarkdownExtension::class)) {
65+
throw new \LogicException(sprintf('You cannot use "%s" if the Markdown Twig extension is not available; try running "composer require twig/markdown-extra".', __METHOD__));
66+
}
67+
68+
$this->context['markdown'] = true;
69+
70+
return $this;
71+
}
72+
73+
/**
74+
* @return $this
75+
*/
76+
public function content(string $content, bool $raw = false)
77+
{
78+
$this->context['content'] = $content;
79+
$this->context['raw'] = $raw;
80+
81+
return $this;
82+
}
83+
84+
/**
85+
* @return $this
86+
*/
87+
public function action(string $text, string $url)
88+
{
89+
$this->context['action_text'] = $text;
90+
$this->context['action_url'] = $url;
91+
92+
return $this;
93+
}
94+
95+
/**
96+
* @return self
97+
*/
98+
public function importance(string $importance)
99+
{
100+
$this->context['importance'] = $importance;
101+
102+
return $this;
103+
}
104+
105+
/**
106+
* @param \Throwable|FlattenException
107+
*
108+
* @return $this
109+
*/
110+
public function exception($exception)
111+
{
112+
$exceptionAsString = $this->getExceptionAsString($exception);
113+
114+
$this->context['exception'] = true;
115+
$this->attach($exceptionAsString, 'exception.txt', 'text/plain');
116+
$this->importance(self::IMPORTANCE_URGENT);
117+
118+
if (!$this->getSubject()) {
119+
$this->subject($exception->getMessage());
120+
}
121+
122+
return $this;
123+
}
124+
125+
/**
126+
* @return $this
127+
*/
128+
public function theme(string $themePath = null)
129+
{
130+
$this->theme = $themePath;
131+
132+
return $this;
133+
}
134+
135+
public static function setDefaultTheme(string $themePath = null)
136+
{
137+
self::$defaultTheme = $themePath ?: self::DEFAULT_THEME;
138+
}
139+
140+
public function getTextTemplate(): ?string
141+
{
142+
if ($template = parent::getTextTemplate()) {
143+
return $template;
144+
}
145+
146+
return ($this->theme ?: self::$defaultTheme).'.txt.twig';
147+
}
148+
149+
public function getHtmlTemplate(): ?string
150+
{
151+
if ($template = parent::getHtmlTemplate()) {
152+
return $template;
153+
}
154+
155+
return ($this->theme ?: self::$defaultTheme).'.html.twig';
156+
}
157+
158+
public function getContext(): array
159+
{
160+
return array_merge($this->context, parent::getContext());
161+
}
162+
163+
public function getPreparedHeaders(): Headers
164+
{
165+
$headers = parent::getPreparedHeaders();
166+
167+
$importance = $this->context['importance'] ?? IMPORTANCE_LOW;
168+
$this->priority($this->determinePriority($importance));
169+
$headers->setHeaderBody('Text', 'Subject', sprintf('[%s] %s', strtoupper($importance), $this->getSubject()));
170+
171+
return $headers;
172+
}
173+
174+
private function determinePriority(string $importance): int
175+
{
176+
switch ($importance) {
177+
case self::IMPORTANCE_URGENT:
178+
return self::PRIORITY_HIGHEST;
179+
case self::IMPORTANCE_HIGH:
180+
return self::PRIORITY_HIGH;
181+
case self::IMPORTANCE_MEDIUM:
182+
return self::PRIORITY_NORMAL;
183+
case self::IMPORTANCE_LOW:
184+
return self::PRIORITY_LOW;
185+
default:
186+
return self::PRIORITY_LOWEST;
187+
}
188+
}
189+
190+
private function getExceptionAsString($exception): string
191+
{
192+
if (class_exists(FlattenException::class)) {
193+
$exception = $exception instanceof FlattenException ? $exception : FlattenException::createFromThrowable($exception);
194+
195+
return $exception->getAsString();
196+
}
197+
198+
$message = \get_class($exception);
199+
if ('' != $exception->getMessage()) {
200+
$message .= ': '.$exception->getMessage();
201+
}
202+
203+
$message .= ' in '.$exception->getFile().':'.$exception->getLine()."\n";
204+
$message .= "Stack trace:\n".$exception->getTraceAsString()."\n\n";
205+
206+
return rtrim($message);
207+
}
208+
209+
/**
210+
* @internal
211+
*/
212+
public function __serialize(): array
213+
{
214+
return [$this->context, parent::__serialize()];
215+
}
216+
217+
/**
218+
* @internal
219+
*/
220+
public function __unserialize(array $data): void
221+
{
222+
[$this->context, $parentData] = $data;
223+
224+
parent::__unserialize($parentData);
225+
}
226+
}

0 commit comments

Comments
 (0)