1 | <?php |
||||
2 | |||||
3 | namespace Azine\EmailBundle\Services; |
||||
4 | |||||
5 | /* |
||||
6 | * This Service provides the templates and template-variables to be used for emails |
||||
7 | * @author Dominik Businger |
||||
8 | */ |
||||
9 | use Azine\EmailBundle\DependencyInjection\AzineEmailExtension; |
||||
10 | use Symfony\Bundle\FrameworkBundle\Translation\Translator; |
||||
11 | use Symfony\Component\Routing\Generator\UrlGeneratorInterface; |
||||
12 | use Symfony\Component\Translation\TranslatorInterface; |
||||
13 | |||||
14 | class AzineTemplateProvider implements TemplateProviderInterface |
||||
15 | { |
||||
16 | const BASE_TEMPLATE = 'AzineEmailBundle::baseEmailLayout'; |
||||
17 | const NEWSLETTER_TEMPLATE = 'AzineEmailBundle::newsletterEmailLayout'; |
||||
18 | const NOTIFICATIONS_TEMPLATE = 'AzineEmailBundle::notificationsEmailLayout'; |
||||
19 | const CONTENT_ITEM_MESSAGE_TEMPLATE = 'AzineEmailBundle:contentItem:message'; |
||||
20 | const EMAIL_UPDATE_CONFIRMATION_TEMPLATE = '@AzineEmailUpdateConfirmation/Email/email_update_confirmation'; |
||||
21 | const FOS_USER_PWD_RESETTING_TEMPLATE = '@FOSUser/Resetting/email'; |
||||
22 | const FOS_USER_REGISTRATION_TEMPLATE = '@FOSUser/Registration/email'; |
||||
23 | const FOS_USER_CONFIRM_EMAIL_UPDATE = '@FOSUser/Profile/email_update_confirmation'; |
||||
24 | const SEND_IMMEDIATELY_FLAG = 'AzineEmailBundle_SendThisEmailImmediately'; |
||||
25 | |||||
26 | /** |
||||
27 | * Override this function for your template(s)! |
||||
28 | * |
||||
29 | * For each template you like to render, you need to supply the array with variables that can be passed to the twig renderer. |
||||
30 | * Those variables can then be used in the twig-template => {{ logo_png }} |
||||
31 | * |
||||
32 | * In this function you should fill a set of variables for each template. |
||||
33 | * |
||||
34 | * @param string $template the template id in standard-notation, without the ending ( .txt.twig) => "AcmeFooBundle:bar:default" |
||||
35 | * |
||||
36 | * @return array |
||||
37 | 11 | */ |
|||
38 | protected function getParamArrayFor($template) |
||||
39 | { |
||||
40 | // this implementation uses the same array for all templates. |
||||
41 | // override this function with a more sophisticated logic |
||||
42 | // if you need different styles for different templates. |
||||
43 | 11 | ||||
44 | $newVars = array(); |
||||
45 | |||||
46 | 11 | // add template-specific stuff. |
|||
47 | 1 | if (self::NOTIFICATIONS_TEMPLATE == $template) { |
|||
48 | $newVars['subject'] = 'Your notifications sent by AzineEmailBundle'; |
||||
49 | } |
||||
50 | 11 | ||||
51 | 5 | if (self::NEWSLETTER_TEMPLATE == $template) { |
|||
52 | $newVars['subject'] = 'Newsletter sent by AzineEmailBundle'; |
||||
53 | } |
||||
54 | |||||
55 | 11 | // send some mails immediately instead of spooled |
|||
56 | 10 | if (self::FOS_USER_PWD_RESETTING_TEMPLATE == $template |
|||
57 | 11 | || self::FOS_USER_REGISTRATION_TEMPLATE == $template |
|||
58 | || self::FOS_USER_CONFIRM_EMAIL_UPDATE == $template |
||||
59 | 3 | || self::EMAIL_UPDATE_CONFIRMATION_TEMPLATE == $template |
|||
60 | ) { |
||||
61 | $newVars[self::SEND_IMMEDIATELY_FLAG] = true; |
||||
62 | } |
||||
63 | |||||
64 | // add generic stuff needed for all templates |
||||
65 | |||||
66 | // add images to be encoded and attached to the email |
||||
67 | // the absolute file-path will be replaced with the CID of |
||||
68 | // the attached image, so it will be rendered in the html-email. |
||||
69 | 11 | // => to render the logo inside your twig-template you can write: |
|||
70 | 11 | // <html><body> ... <img src="{{ logo_png }}" alt="logo"> ... </body></html> |
|||
71 | 11 | $imagesDir = $this->getTemplateImageDir(); |
|||
72 | 11 | $newVars['logo_png'] = $imagesDir.'logo.png'; |
|||
73 | 11 | $newVars['bottom_shadow_png'] = $imagesDir.'bottomshadow.png'; |
|||
74 | 11 | $newVars['top_shadow_png'] = $imagesDir.'topshadow.png'; |
|||
75 | 11 | $newVars['left_shadow_png'] = $imagesDir.'left-shadow.png'; |
|||
76 | $newVars['right_shadow_png'] = $imagesDir.'right-shadow.png'; |
||||
77 | $newVars['placeholder_png'] = $imagesDir.'placeholder.png'; |
||||
78 | 11 | ||||
79 | 11 | // define some colors to be reused in the following style-definitions |
|||
80 | 11 | $azGreen = 'green'; |
|||
81 | 11 | $azBlue = 'blue'; |
|||
82 | $blackColor = 'black'; |
||||
83 | $lightGray = '#EEEEEE'; |
||||
84 | |||||
85 | // add html-styles for your html-emails |
||||
86 | 11 | // css does not work in html-emails, so all styles need to be |
|||
87 | 11 | // embeded directly into the html-elements |
|||
88 | 11 | $newVars['azGreen'] = $azGreen; |
|||
89 | 11 | $newVars['azBlue'] = $azBlue; |
|||
90 | 11 | $newVars['blackColor'] = $blackColor; |
|||
91 | 11 | $newVars['lightGray'] = $lightGray; |
|||
92 | 11 | $newVars['bodyBackgroundColor'] = '#fdfbfa'; |
|||
93 | 11 | $newVars['contentBackgroundColor'] = '#f2f1f0'; |
|||
94 | 11 | $fontFamily = 'Arial, Helvetica, sans-serif'; |
|||
95 | 11 | $newVars['fontFamily'] = $fontFamily; |
|||
96 | 11 | $newVars['emailWidth'] = 640; // width for the whole email-body |
|||
97 | 11 | $newVars['shadowWidth'] = 10; // width for the shadows left and right of the content |
|||
98 | 11 | $newVars['contentWidth'] = 620; // width for the mail content |
|||
99 | 11 | $newVars['mediaQueryWidth'] = 479; // width for the media-query for mobile devices |
|||
100 | 11 | $newVars['mobileEmailWidth'] = 459; // width for the whole email-body for mobile devices |
|||
101 | $newVars['mobileContentWidth'] = 439; // width for the mail content for mobile devices |
||||
102 | 11 | $newVars['footerBackgroundColor'] = '#434343'; |
|||
103 | 11 | ||||
104 | 11 | $newVars['h1Style'] = "style='padding:0; margin:0; font:bold 30px $fontFamily; color:$azBlue; text-decoration:none;'"; |
|||
105 | 11 | $newVars['h2Style'] = "style='padding:0; margin:0; font:bold 24px $fontFamily; color:$azBlue; text-decoration:none;'"; |
|||
106 | 11 | $newVars['h3Style'] = "style='margin:12px 0 5px 0; font:bold 18px $fontFamily; padding:0; color:$azGreen; text-decoration:none;'"; |
|||
107 | 11 | $newVars['h4Style'] = "style='padding:0; margin:0 0 20px 0; color:$blackColor; font-size:14px; text-decoration:none;'"; |
|||
108 | 11 | $newVars['smallGreyStyle'] = "style='color: grey; font: $fontFamily 11px;'"; |
|||
109 | 11 | $newVars['salutationStyle'] = "style='color:$azBlue; font:bold 16px $fontFamily;'"; |
|||
110 | 11 | $newVars['smallerTextStyle'] = "style='font: normal 13px/18px $fontFamily;'"; |
|||
111 | 11 | $newVars['dateStyle'] = "style='padding:0; margin:5px 0; color:$blackColor; font-weight:bold; font-size:12px;'"; |
|||
112 | 11 | $newVars['readMoreLinkStyle'] = "style='color:$azGreen; text-decoration:none; font-size:13px;'"; |
|||
113 | 11 | $newVars['titleLinkStyle'] = "style='text-decoration:none;'"; |
|||
114 | 11 | $newVars['salutationStyle'] = "style='color:$azBlue; font:bold 16px Arial;'"; |
|||
115 | 11 | $newVars['dateStyle'] = "style='padding:0; margin:5px 0; color:$blackColor; font-weight:bold; font-size:12px;'"; |
|||
116 | 11 | $newVars['smallerTextStyle'] = "style='font: normal 13px/18px Arial, Helvetica, sans-serif;'"; |
|||
117 | $newVars['actionButtonStyle'] = "style='font-weight: bold; background: none repeat scroll 0 0 #DF940B; border: 1px solid orange; border-radius: 5px; box-shadow: 0 1px 0 #DF940B inset; color: white; padding: 10px;'"; |
||||
118 | $newVars['sloganStyle'] = "style='font-size: 16px; color:$blackColor; margin: 0px; padding: 0px;'"; |
||||
119 | 11 | ||||
120 | 11 | // some simple txt styling elements |
|||
121 | 11 | $newVars['txtH1Style'] = '////////////////////////////////////////////////////////////////////////////////'; |
|||
122 | 11 | $newVars['txtH2Style'] = '================================================================================'; |
|||
123 | 11 | $newVars['txtH3Style'] = '--------------------------------------------------------------------------------'; |
|||
124 | $newVars['txtH4Style'] = "''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''"; |
||||
125 | 11 | $newVars['txtHR'] = '________________________________________________________________________________'; |
|||
126 | |||||
127 | return $newVars; |
||||
128 | } |
||||
129 | |||||
130 | /** |
||||
131 | * Override this function for your template(s) if you use other "snippets" with embedded images. |
||||
132 | * |
||||
133 | * This function adds more complex elements to the array of variables that are passed |
||||
134 | * to the twig-renderer, just before sending the mail. |
||||
135 | * |
||||
136 | * In this implementation for example some reusable "snippets" are added to render |
||||
137 | * a nice shadow around content parts and add a "link to top" at the top of each part. |
||||
138 | * |
||||
139 | * As these "snippets" contain references to images that first had to be embedded into the |
||||
140 | * Message, these "snippets" are added after embedding/adding the attachments. |
||||
141 | * |
||||
142 | * This means, that here the variable "bottom_shadow_png" defined in AzineTemplateProvider.fillParamArrayFor() |
||||
143 | * does not contain the path to the image-file anymore but now contains the CID of the embedded image. |
||||
144 | * |
||||
145 | * @param string $template the template id in standard-notation, without the ending ( .txt.twig) => "AcmeFooBundle:bar:default" |
||||
146 | * @param array $vars |
||||
147 | * @param string $emailLocale |
||||
148 | * |
||||
149 | * @throws \Exception |
||||
150 | * |
||||
151 | 11 | * @return array of strings |
|||
152 | */ |
||||
153 | protected function getSnippetArrayFor($template, array $vars, $emailLocale) |
||||
154 | { |
||||
155 | // this implementation uses the same snippets for all templates. |
||||
156 | // override this function with a more sophisticated logic |
||||
157 | // if you need different snippets for different templates. |
||||
158 | |||||
159 | // the snippets added in this implementation depend on the |
||||
160 | 11 | // following images, so they must be present in the $vars-array |
|||
161 | 10 | if ( |
|||
162 | 10 | !array_key_exists('bottom_shadow_png', $vars) || |
|||
163 | 11 | !array_key_exists('top_shadow_png', $vars) || |
|||
164 | !array_key_exists('left_shadow_png', $vars) || |
||||
165 | 1 | !array_key_exists('right_shadow_png', $vars) |
|||
166 | ) { |
||||
167 | throw new \Exception('some required images are not yet added to the template-vars array.'); |
||||
168 | 10 | } |
|||
169 | |||||
170 | $snippets = array(); |
||||
171 | 10 | ||||
172 | 10 | // define some vars that are used several times |
|||
173 | 10 | $lightGray = $vars['lightGray']; |
|||
174 | 9 | $blackColor = $vars['blackColor']; |
|||
175 | $upLinkTitle = $this->getTranslator($emailLocale)->trans('html.email.go.to.top.link.label', array(), 'messages', $emailLocale); |
||||
176 | $fontFamily = $vars['fontFamily']; |
||||
177 | 9 | ||||
178 | 9 | // create and add html-elements for easy reuse in the twig-templates |
|||
179 | 9 | $snippets['linkToTop'] = "<a href='#top' style='text-decoration:none;color:$blackColor' title='$upLinkTitle'>Λ</a>"; |
|||
180 | 9 | $snippets['tableOpen'] = "<table summary='box with shadows' class='emailWidth' width='".$vars['emailWidth']."' border='0' align='center' cellpadding='0' cellspacing='0' style='font: normal 14px/18px $fontFamily;'>"; |
|||
181 | 9 | $snippets['topShadow'] = $snippets['tableOpen']."<tr><td class='emailWidth' colspan='3' width='".$vars['emailWidth']."'><img class='emailWidth' width='".$vars['emailWidth']."' height='10' src='".$vars['top_shadow_png']."' alt='' style='vertical-align: bottom;'/></td></tr>"; |
|||
182 | 9 | $snippets['leftShadow'] = "<tr><td width='10' style='border-right: 1px solid $lightGray; background-image: url(\"".$vars['left_shadow_png']."\");'> </td>"; |
|||
183 | 9 | $snippets['rightShadow'] = "<td width='10' style='border-left: 1px solid $lightGray; background-image: url(\"".$vars['right_shadow_png']."\");'> </td></tr>"; |
|||
184 | 9 | $snippets['bottomShadow'] = " <tr><td colspan='3' class='emailWidth' width='".$vars['emailWidth']."'><img src='".$vars['bottom_shadow_png']."' class='emailWidth' width='".$vars['emailWidth']."' height='10' alt='' style='vertical-align: top;'/></td></tr></table>"; |
|||
185 | $snippets['linkToTopRow'] = $snippets['leftShadow']."<td width='610' bgcolor='white' style='text-align: right; padding: 5px 5px 0; border-top: 1px solid $lightGray;'>".$snippets['linkToTop'].'</td>'.$snippets['rightShadow']; |
||||
186 | 9 | $snippets['cellSeparator'] = '</td>'.$snippets['rightShadow'].$snippets['bottomShadow'].$snippets['topShadow'].$snippets['linkToTopRow'].$snippets['leftShadow']."<td bgcolor='white' width='580' align='left' valign='top' style='padding:10px 20px 20px 20px;'>"; |
|||
187 | |||||
188 | return $snippets; |
||||
189 | } |
||||
190 | |||||
191 | /** |
||||
192 | * Override this function to define your own campaign-parameters |
||||
193 | * (non-PHPdoc). |
||||
194 | * |
||||
195 | 8 | * @see Azine\EmailBundle\Services\TemplateProviderInterface::getCampaignParamsFor() |
|||
196 | */ |
||||
197 | public function getCampaignParamsFor($templateId, array $params = null) |
||||
198 | 8 | { |
|||
199 | 8 | $campaignParams = array( |
|||
200 | $this->tracking_params_campaign_medium => 'email', |
||||
201 | $this->tracking_params_campaign_name => date('y-m-d'), |
||||
202 | 8 | ); |
|||
203 | 5 | ||||
204 | 4 | if (self::NEWSLETTER_TEMPLATE == $templateId) { |
|||
205 | 1 | $campaignParams[$this->tracking_params_campaign_source] = 'newsletter'; |
|||
206 | 4 | } elseif (self::NOTIFICATIONS_TEMPLATE == $templateId) { |
|||
207 | 1 | $campaignParams[$this->tracking_params_campaign_source] = 'mailnotify'; |
|||
208 | } elseif (self::CONTENT_ITEM_MESSAGE_TEMPLATE == $templateId) { |
||||
209 | $campaignParams[$this->tracking_params_campaign_content] = 'message'; |
||||
210 | 3 | ||||
211 | 2 | // don't track password-reset emails |
|||
212 | } elseif (self::FOS_USER_PWD_RESETTING_TEMPLATE == $templateId || self::FOS_USER_REGISTRATION_TEMPLATE == $templateId) { |
||||
213 | $campaignParams = array(); |
||||
214 | 8 | } |
|||
215 | |||||
216 | return $campaignParams; |
||||
217 | } |
||||
218 | |||||
219 | /** |
||||
220 | * Override this function if you want to add extra headers to the messages sent. |
||||
221 | * (non-PHPdoc). |
||||
222 | * |
||||
223 | 6 | * @see Azine\EmailBundle\Services.TemplateProviderInterface::addCustomHeaders() |
|||
224 | */ |
||||
225 | public function addCustomHeaders($template, \Swift_Message $message, array $params) |
||||
226 | { |
||||
227 | 6 | $headerSet = $message->getHeaders(); |
|||
228 | //$headerSet->addTextHeader($name, $vale); |
||||
229 | |||||
230 | if (array_key_exists($this->getWebViewTokenId(), $params)) { |
||||
231 | $headerSet->addTextHeader('x-azine-webview-token', $params[$this->getWebViewTokenId()]); |
||||
232 | } |
||||
233 | |||||
234 | 8 | if (array_key_exists(AzineEmailExtension::TRACKING_PARAM_CAMPAIGN_NAME, $params)) { |
|||
235 | $headerSet->addTextHeader('x-utm_campaign', $params[AzineEmailExtension::TRACKING_PARAM_CAMPAIGN_NAME]); |
||||
236 | 8 | } |
|||
237 | 5 | ||||
238 | if (array_key_exists(AzineEmailExtension::TRACKING_PARAM_CAMPAIGN_SOURCE, $params)) { |
||||
239 | $headerSet->addTextHeader('x-utm_source', $params[AzineEmailExtension::TRACKING_PARAM_CAMPAIGN_SOURCE]); |
||||
240 | 4 | } |
|||
241 | } |
||||
242 | |||||
243 | /** |
||||
244 | * (non-PHPdoc). |
||||
245 | * |
||||
246 | * @see Azine\EmailBundle\Services.TemplateProviderInterface::saveWebViewFor() |
||||
247 | */ |
||||
248 | 8 | public function saveWebViewFor($template) |
|||
249 | { |
||||
250 | 8 | if (false !== array_search($template, $this->getTemplatesToStoreForWebView())) { |
|||
251 | 8 | return true; |
|||
252 | } |
||||
253 | 8 | ||||
254 | return false; |
||||
255 | } |
||||
256 | |||||
257 | /** |
||||
258 | * Override this function to define which emails you want to make the web-view available and for which not. |
||||
259 | * |
||||
260 | * @return array of string => the template id in standard-notation, without the ending ( .txt.twig) => "AcmeFooBundle:bar:default" |
||||
261 | */ |
||||
262 | 8 | protected function getTemplatesToStoreForWebView() |
|||
263 | { |
||||
264 | 8 | $include = array(); |
|||
265 | $include[] = self::NEWSLETTER_TEMPLATE; |
||||
266 | |||||
267 | return $include; |
||||
268 | } |
||||
269 | |||||
270 | /** |
||||
271 | * Only override this method if you want to change the ID used in the twig-template for the web-view-link from 'azineEmailWebViewToken' to something else. |
||||
272 | * (non-PHPdoc). |
||||
273 | * |
||||
274 | * @see Azine\EmailBundle\Services.TemplateProviderInterface::getWebViewTokenId() |
||||
275 | */ |
||||
276 | public function getWebViewTokenId() |
||||
277 | { |
||||
278 | return self::EMAIL_WEB_VIEW_TOKEN; |
||||
279 | } |
||||
280 | |||||
281 | ////////////////////////////////////////////////////////////////////////// |
||||
282 | /* You probably don't need to change or override any of the stuff below */ |
||||
283 | ////////////////////////////////////////////////////////////////////////// |
||||
284 | |||||
285 | const CONTENT_ITEMS = 'contentItems'; |
||||
286 | const EMAIL_WEB_VIEW_TOKEN = 'azineEmailWebViewToken'; |
||||
287 | |||||
288 | /** |
||||
289 | * Full filesystem-path to the directory where you store your email-template images. |
||||
290 | * |
||||
291 | * @var string |
||||
292 | */ |
||||
293 | private $templateImageDir; |
||||
294 | |||||
295 | /** |
||||
296 | * List of directories from which images are allowed to be embeded into emails. |
||||
297 | * |
||||
298 | * @var array of string |
||||
299 | */ |
||||
300 | private $allowedImageFolders = array(); |
||||
301 | |||||
302 | /** |
||||
303 | * @var UrlGeneratorInterface |
||||
304 | */ |
||||
305 | private $router; |
||||
306 | |||||
307 | /** |
||||
308 | * @var TranslatorInterface |
||||
309 | */ |
||||
310 | private $translator; |
||||
311 | |||||
312 | /** |
||||
313 | * Array to store all the arrays for the variables/parameters for all the different templates. |
||||
314 | * |
||||
315 | * @var array of array |
||||
316 | */ |
||||
317 | protected $paramArrays = array(); |
||||
318 | |||||
319 | /** |
||||
320 | * @var string |
||||
321 | */ |
||||
322 | protected $tracking_params_campaign_source; |
||||
323 | |||||
324 | /** |
||||
325 | * @var string |
||||
326 | */ |
||||
327 | protected $tracking_params_campaign_medium; |
||||
328 | |||||
329 | /** |
||||
330 | * @var string |
||||
331 | */ |
||||
332 | protected $tracking_params_campaign_content; |
||||
333 | |||||
334 | /** |
||||
335 | * @var string |
||||
336 | */ |
||||
337 | 16 | protected $tracking_params_campaign_name; |
|||
338 | |||||
339 | 16 | /** |
|||
340 | 16 | * @var string |
|||
341 | 16 | */ |
|||
342 | 16 | protected $tracking_params_campaign_term; |
|||
343 | 16 | ||||
344 | /** |
||||
345 | * Array to store all the arrays for the code snippets for all the different temlpates. |
||||
346 | 16 | * |
|||
347 | 16 | * @var unknown_type |
|||
0 ignored issues
–
show
|
|||||
348 | 16 | */ |
|||
349 | 16 | protected $snippetArrays = array(); |
|||
350 | |||||
351 | public function __construct(UrlGeneratorInterface $router, TranslatorInterface $translator, array $parameters) |
||||
352 | 16 | { |
|||
353 | 16 | $this->router = $router; |
|||
354 | 16 | $this->translator = $translator; |
|||
355 | 16 | $templateImageDir = realpath($parameters[AzineEmailExtension::TEMPLATE_IMAGE_DIR]); |
|||
356 | 16 | if (false !== $this->templateImageDir) { |
|||
0 ignored issues
–
show
|
|||||
357 | 16 | $this->templateImageDir = $templateImageDir.'/'; |
|||
358 | 16 | } |
|||
359 | |||||
360 | foreach ($parameters[AzineEmailExtension::ALLOWED_IMAGES_FOLDERS] as $nextFolder) { |
||||
361 | $imageFolder = realpath($nextFolder); |
||||
362 | if (false !== $imageFolder) { |
||||
363 | $this->allowedImageFolders[md5($imageFolder)] = $imageFolder.'/'; |
||||
364 | } |
||||
365 | 11 | } |
|||
366 | $this->allowedImageFolders[md5($this->templateImageDir)] = $this->templateImageDir; |
||||
367 | 11 | $this->tracking_params_campaign_content = $parameters[AzineEmailExtension::TRACKING_PARAM_CAMPAIGN_CONTENT]; |
|||
368 | $this->tracking_params_campaign_medium = $parameters[AzineEmailExtension::TRACKING_PARAM_CAMPAIGN_MEDIUM]; |
||||
369 | $this->tracking_params_campaign_name = $parameters[AzineEmailExtension::TRACKING_PARAM_CAMPAIGN_NAME]; |
||||
370 | $this->tracking_params_campaign_source = $parameters[AzineEmailExtension::TRACKING_PARAM_CAMPAIGN_SOURCE]; |
||||
371 | $this->tracking_params_campaign_term = $parameters[AzineEmailExtension::TRACKING_PARAM_CAMPAIGN_TERM]; |
||||
372 | } |
||||
373 | |||||
374 | /** |
||||
375 | 11 | * (non-PHPdoc). |
|||
376 | * |
||||
377 | 11 | * @see Azine\EmailBundle\Services.TemplateProviderInterface::getTemplateImageDir() |
|||
378 | 11 | */ |
|||
379 | public function getTemplateImageDir() |
||||
380 | { |
||||
381 | return $this->templateImageDir; |
||||
382 | 11 | } |
|||
383 | |||||
384 | /** |
||||
385 | 11 | * (non-PHPdoc). |
|||
386 | 6 | * |
|||
387 | * @see Azine\EmailBundle\Services.TemplateProviderInterface::addTemplateVariablesFor() |
||||
388 | 6 | */ |
|||
389 | 6 | public function addTemplateVariablesFor($template, array $contentVariables) |
|||
390 | { |
||||
391 | if (!array_key_exists($template, $this->paramArrays)) { |
||||
392 | 6 | $this->paramArrays[$template] = $this->getParamArrayFor($template); |
|||
393 | } |
||||
394 | |||||
395 | 6 | // add vars for main template |
|||
396 | $contentVariables = array_merge($this->paramArrays[$template], $contentVariables); |
||||
397 | |||||
398 | 6 | // add the template-variables to the contentItem-params-arrays |
|||
399 | if (array_key_exists(self::CONTENT_ITEMS, $contentVariables)) { |
||||
400 | foreach ($contentVariables[self::CONTENT_ITEMS] as $key => $contentItem) { |
||||
401 | // get the key (=> template) |
||||
402 | 11 | reset($contentItem); |
|||
403 | $itemTemplate = key($contentItem); |
||||
404 | |||||
405 | // get the params |
||||
406 | $itemParams = $contentItem[$itemTemplate]; |
||||
407 | |||||
408 | // add params for this template |
||||
409 | $contentItem[$itemTemplate] = $this->addTemplateVariablesFor($itemTemplate, $itemParams); |
||||
410 | 11 | ||||
411 | // store back into the main array |
||||
412 | 11 | $contentVariables[self::CONTENT_ITEMS][$key] = $contentItem; |
|||
413 | 11 | } |
|||
414 | } |
||||
415 | 11 | ||||
416 | 11 | return $contentVariables; |
|||
417 | } |
||||
418 | |||||
419 | /** |
||||
420 | 9 | * (non-PHPdoc). |
|||
421 | * |
||||
422 | * @see Azine\EmailBundle\Services.TemplateProviderInterface::addTemplateSnippetsWithImagesFor() |
||||
423 | 9 | */ |
|||
424 | 4 | public function addTemplateSnippetsWithImagesFor($template, array $vars, $emailLocale, $forWebView = false) |
|||
425 | { |
||||
426 | 4 | $channel = $forWebView ? 'webView' : 'email'; |
|||
427 | 4 | $templateKey = $channel.$template.$emailLocale; |
|||
428 | |||||
429 | if (!array_key_exists($templateKey, $this->snippetArrays)) { |
||||
0 ignored issues
–
show
$this->snippetArrays of type Azine\EmailBundle\Services\unknown_type is incompatible with the type array expected by parameter $search of array_key_exists() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
430 | 4 | $this->snippetArrays[$templateKey] = $this->getSnippetArrayFor($template, $vars, $emailLocale); |
|||
431 | } |
||||
432 | |||||
433 | 4 | // add vars for main template |
|||
434 | $vars = array_merge($this->snippetArrays[$templateKey], $vars); |
||||
435 | |||||
436 | 4 | // add the template-code-snippets to the contentItem-params-arrays |
|||
437 | if (array_key_exists(self::CONTENT_ITEMS, $vars)) { |
||||
438 | foreach ($vars[self::CONTENT_ITEMS] as $key => $contentItem) { |
||||
439 | // get the key (=> template) |
||||
440 | 9 | reset($contentItem); |
|||
441 | $itemTemplate = key($contentItem); |
||||
442 | |||||
443 | // get the params |
||||
444 | $itemParams = $contentItem[$itemTemplate]; |
||||
445 | |||||
446 | 3 | // add params for this template |
|||
447 | $contentItem[$itemTemplate] = $this->addTemplateSnippetsWithImagesFor($itemTemplate, $itemParams, $emailLocale, $forWebView); |
||||
448 | 3 | ||||
449 | // store back into the main array |
||||
450 | $vars[self::CONTENT_ITEMS][$key] = $contentItem; |
||||
451 | } |
||||
452 | } |
||||
453 | |||||
454 | return $vars; |
||||
455 | } |
||||
456 | |||||
457 | /** |
||||
458 | * @return UrlGeneratorInterface |
||||
459 | */ |
||||
460 | 10 | protected function getRouter() |
|||
461 | { |
||||
462 | 10 | return $this->router; |
|||
463 | 1 | } |
|||
464 | |||||
465 | /** |
||||
466 | 9 | * Only use the translator here when you already know in which language the user should get the email. |
|||
467 | * |
||||
468 | * @param string $emailLocale |
||||
469 | * |
||||
470 | * @throws \Exception |
||||
471 | * |
||||
472 | * @return Translator |
||||
473 | */ |
||||
474 | protected function getTranslator($emailLocale) |
||||
475 | { |
||||
476 | if (null === $emailLocale) { |
||||
0 ignored issues
–
show
|
|||||
477 | 3 | throw new \Exception('Only use the translator here when you already know in which language the user should get the email.'); |
|||
478 | } |
||||
479 | 3 | ||||
480 | 3 | return $this->translator; |
|||
481 | } |
||||
482 | 3 | ||||
483 | 3 | /** |
|||
484 | * Recursively replace all absolute image-file-paths with relative web-paths. |
||||
485 | 3 | * |
|||
486 | 3 | * @param array $emailVars |
|||
487 | 3 | * @param string $locale |
|||
488 | * |
||||
489 | 3 | * @return array |
|||
490 | 3 | */ |
|||
491 | public function makeImagePathsWebRelative(array $emailVars, $locale) |
||||
492 | { |
||||
493 | foreach ($emailVars as $key => $value) { |
||||
494 | 3 | if (is_string($value) && is_file($value)) { |
|||
495 | // check if the file is in an allowed_images_folder |
||||
496 | $folderKey = $this->isFileAllowed($value); |
||||
497 | if (false !== $folderKey) { |
||||
498 | // replace the fs-path with the web-path |
||||
499 | $fsPathToReplace = $this->getFolderFrom($folderKey); |
||||
500 | $filename = substr($value, strlen($fsPathToReplace)); |
||||
0 ignored issues
–
show
It seems like
$fsPathToReplace can also be of type false ; however, parameter $string of strlen() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
501 | $newValue = $this->getRouter()->generate('azine_email_serve_template_image', array('folderKey' => $folderKey, 'filename' => urlencode($filename), '_locale' => $locale)); |
||||
502 | 9 | $emailVars[$key] = $newValue; |
|||
503 | } |
||||
504 | 9 | } elseif (is_array($value)) { |
|||
505 | 9 | $emailVars[$key] = $this->makeImagePathsWebRelative($value, $locale); |
|||
506 | 9 | } |
|||
507 | 9 | } |
|||
508 | |||||
509 | return $emailVars; |
||||
510 | } |
||||
511 | 2 | ||||
512 | /** |
||||
513 | * (non-PHPdoc). |
||||
514 | * |
||||
515 | * @see Azine\EmailBundle\Services.TemplateProviderInterface::isFileAllowed() |
||||
516 | */ |
||||
517 | public function isFileAllowed($filePath) |
||||
518 | { |
||||
519 | 1 | $filePath = realpath($filePath); |
|||
520 | foreach ($this->allowedImageFolders as $key => $nextFolder) { |
||||
521 | 1 | if (0 === strpos($filePath, $nextFolder)) { |
|||
522 | 1 | return $key; |
|||
523 | } |
||||
524 | } |
||||
525 | 1 | ||||
526 | return false; |
||||
527 | } |
||||
528 | |||||
529 | /** |
||||
530 | * (non-PHPdoc). |
||||
531 | * |
||||
532 | * @see Azine\EmailBundle\Services.TemplateProviderInterface::getFolderFrom() |
||||
533 | */ |
||||
534 | public function getFolderFrom($key) |
||||
535 | { |
||||
536 | if (array_key_exists($key, $this->allowedImageFolders)) { |
||||
537 | return $this->allowedImageFolders[$key]; |
||||
538 | } |
||||
539 | |||||
540 | return false; |
||||
541 | } |
||||
542 | } |
||||
543 |
The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g.
excluded_paths: ["lib/*"]
, you can move it to the dependency path list as follows:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths