1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
messagemail.php
См. документацию.
1<?php
8
9namespace Bitrix\Sender\Integration\Sender\Mail;
10
11use Bitrix\Fileman\Block;
12use Bitrix\Main\Application;
13use Bitrix\Main\Config\Option;
14use Bitrix\Main\Error;
15use Bitrix\Main\Loader;
16use Bitrix\Main\Localization\Loc;
17use Bitrix\Main\Mail;
18use Bitrix\Main\Result;
19use Bitrix\Main\SystemException;
20use Bitrix\Main\Web\DOM\Document;
21use Bitrix\Main\Web\DOM\StyleInliner;
22use Bitrix\Sender\Entity;
23use Bitrix\Sender\Integration;
24use Bitrix\Sender\Integration\Crm\Connectors\Helper;
25use Bitrix\Sender\Message;
26use Bitrix\Sender\Posting;
27use Bitrix\Sender\PostingRecipientTable;
28use Bitrix\Sender\Templates;
29use Bitrix\Sender\Transport;
30use Bitrix\Sender\Transport\TimeLimiter;
31
32Loc::loadMessages(__FILE__);
33
39{
40 const CODE = self::CODE_MAIL;
41
43 protected $configuration;
44
47
49
53 public function __construct()
54 {
55 $this->configuration = new Message\Configuration();
56 }
57
63 public function getName()
64 {
65 return Loc::getMessage('SENDER_INTEGRATION_MAIL_MESSAGE_NAME');
66 }
67
73 public function getCode()
74 {
75 return self::CODE;
76 }
77
83 public function getSupportedTransports()
84 {
86 }
87
92 protected function setConfigurationOptions()
93 {
94 if ($this->configuration->hasOptions())
95 {
96 return;
97 }
98
99 $this->configuration->setArrayOptions(array(
100 array(
101 'type' => 'string',
102 'code' => 'SUBJECT',
103 'name' => Loc::getMessage('SENDER_INTEGRATION_MAIL_MESSAGE_CONFIG_SUBJECT'),
104 'required' => true,
105 'value' => '',
106 'show_in_list' => true,
107 'hint' => array(
108 'menu' => array_map(
109 function ($item)
110 {
111 return array(
112 'id' => '#' . ($item['CODE'] ?? '') . '#',
113 'text' => $item['NAME'] ?? '',
114 'title' => $item['DESC'] ?? '',
115 'items' => isset($item['ITEMS']) ? array_map(
116 function ($item)
117 {
118 return array(
119 'id' => '#' . ($item['CODE'] ?? ''). '#',
120 'text' => $item['NAME'] ?? '',
121 'title' => $item['DESC'] ?? ''
122 );
123 }, $item['ITEMS']
124 ) : []
125 );
126 },
127 array_merge(
128 Helper::getPersonalizeFieldsFromConnectors(),
130 )
131 ),
132 ),
133 ),
134 array(
135 'type' => 'email',
136 'code' => 'EMAIL_FROM',
137 'name' => Loc::getMessage('SENDER_INTEGRATION_MAIL_MESSAGE_CONFIG_EMAIL_FROM'),
138 'required' => true,
139 'value' => '',
140 'show_in_list' => true,
141 'readonly_view' => function($value)
142 {
143 return (new Mail\Address())->set($value)->get();
144 },
145 //'group' => Message\ConfigurationOption::GROUP_ADDITIONAL,
146 ),
147 array(
148 'type' => 'mail-editor',
149 'code' => 'MESSAGE',
150 'name' => Loc::getMessage('SENDER_INTEGRATION_MAIL_MESSAGE_CONFIG_MESSAGE'),
151 'required' => true,
152 'templated' => true,
153 'value' => '',
154 'items' => array(),
155 ),
156 array(
157 'type' => 'list',
158 'code' => 'PRIORITY',
159 'name' => Loc::getMessage('SENDER_INTEGRATION_MAIL_MESSAGE_CONFIG_PRIORITY'),
160 'required' => false,
162 'value' => '',
163 'show_in_list' => true,
164 'items' => array(
165 array('code' => '', 'value' => '(' . Loc::getMessage('SENDER_INTEGRATION_MAIL_MESSAGE_NO') . ')'),
166 array('code' => '1 (Highest)', 'value' => Loc::getMessage('SENDER_INTEGRATION_MAIL_MESSAGE_CONFIG_PRIORITY_HIGHEST')),
167 array('code' => '3 (Normal)', 'value' => Loc::getMessage('SENDER_INTEGRATION_MAIL_MESSAGE_CONFIG_PRIORITY_NORMAL')),
168 array('code' => '5 (Lowest)', 'value' => Loc::getMessage('SENDER_INTEGRATION_MAIL_MESSAGE_CONFIG_PRIORITY_LOWEST')),
169 ),
170 'hint' => Loc::getMessage('SENDER_INTEGRATION_MAIL_MESSAGE_CONFIG_PRIORITY_HINT'),
171 ),
172 array(
173 'type' => 'string',
174 'code' => 'LINK_PARAMS',
175 'name' => Loc::getMessage('SENDER_INTEGRATION_MAIL_MESSAGE_CONFIG_LINK_PARAMS'),
176 'required' => false,
178 'value' => '',
179 'show_in_list' => true,
180 'items' => array(),
181 ),
182 array(
183 'type' => 'file',
184 'code' => 'ATTACHMENT',
185 'name' => Loc::getMessage('SENDER_INTEGRATION_MAIL_MESSAGE_CONFIG_ATTACHMENT'),
186 'required' => false,
187 'multiple' => true,
189 'value' => '',
190 'items' => array(),
191 ), [
193 'code' => 'TRACK_MAIL',
194 'name' => Loc::getMessage('SENDER_INTEGRATION_MAIL_MESSAGE_CONFIG_TRACK_MAIL'),
196 'show_in_list' => false,
197 'required' => false,
198 'value' => Option::get('sender', 'track_mails')
199 ],
200 [
202 'code' => 'APPROVE_CONFIRMATION',
203 'name' => Loc::getMessage('SENDER_INTEGRATION_MAIL_MESSAGE_CONFIG_APPROVE_CONFIRMATION'),
204 'hint' => Loc::getMessage('SENDER_INTEGRATION_MAIL_MESSAGE_CONFIG_APPROVE_CONFIRMATION_HINT'),
206 'show_in_list' => false,
207 'required' => false,
208 'value' => Option::get('sender', 'mail_consent'),
209 ], [
211 'code' => 'APPROVE_CONFIRMATION_CONSENT',
213 'show_in_list' => false,
214 'required' => false,
215 'show_preview' => true
216 ],
217 ));
218
219 TimeLimiter::prepareMessageConfiguration($this->configuration);
220
221 $list = array(
222 array(
223 'type' => 'template-type',
224 'code' => 'TEMPLATE_TYPE',
225 'name' => 'Template type',
226 'value' => '',
227 ),
228 array(
229 'type' => 'template-id',
230 'code' => 'TEMPLATE_ID',
231 'name' => 'Template id',
232 'value' => '',
233 ),
234 );
235
236 foreach ($list as $optionData)
237 {
238 $optionData = $optionData + array(
239 'type' => 'string',
240 'name' => '',
241 'internal' => true,
242 );
243 $this->configuration->addOption(new Message\ConfigurationOption($optionData));
244 }
245 }
246
254 public function loadConfiguration($id = null)
255 {
257 Entity\Message::create()
258 ->setCode($this->getCode())
259 ->loadConfiguration($id, $this->configuration);
260
261
262 // do not remove: increment ref count to closure for rewriting.
263 $instance = $this;
264 $this->closureRefCountFix = function () use (&$instance)
265 {
266 return $instance->getMailBody();
267 };
268
269 $trackMail = $this->configuration->getOption('TRACK_MAIL')->getValue();
270 if (is_null($trackMail))
271 {
272 $this->configuration->getOption('TRACK_MAIL')->setValue(Option::get('sender', 'track_mails'));
273 }
274
275 $optionLinkParams = $this->configuration->getOption('LINK_PARAMS');
276 if ($optionLinkParams)
277 {
278 $optionLinkParams->setView(
279 function () use ($id, $optionLinkParams)
280 {
281 ob_start();
282 $GLOBALS['APPLICATION']->IncludeComponent(
283 'bitrix:sender.mail.link.editor', '',
284 array(
285 "INPUT_NAME" => "%INPUT_NAME%",
286 "VALUE" => $optionLinkParams->getValue(),
287 "USE_DEFAULT" => (
288 !$optionLinkParams->getValue()
289 &&
290 !$id
291 &&
292 !Application::getInstance()->getContext()->getRequest()->isPost()
293 ),
294 "PLACEHOLDERS" => array(
295 array(
296 "code" => "campaign",
297 "inputName" => "%INPUT_NAME_SUBJECT%"
298 )
299 ),
300 "DEFAULT_VALUE" => Option::get(
301 'sender',
302 'mail_utm',
303 'utm_source=newsletter&utm_medium=mail&utm_campaign=%campaign%'
304 )
305 )
306 );
307 return ob_get_clean();
308 }
309 );
310 }
311
312 $optionFrom = $this->configuration->getOption('EMAIL_FROM');
313 if ($optionFrom)
314 {
315 $optionFrom->setView(
316 function () use ($optionFrom)
317 {
318 ob_start();
319 $GLOBALS['APPLICATION']->IncludeComponent(
320 'bitrix:sender.mail.sender', '',
321 array(
322 "INPUT_NAME" => "%INPUT_NAME%",
323 "VALUE" => $optionFrom->getValue()
324 )
325 );
326 return ob_get_clean();
327 }
328 );
329 }
330
331 $this->configuration->set('BODY', $this->closureRefCountFix);
332
333 $mailHeaders = array('Precedence' => 'bulk');
334 $mailHeaders = self::fillHeadersByOptionHeaders($mailHeaders);
335 $this->configuration->set('HEADERS', $mailHeaders);
336 TimeLimiter::prepareMessageConfigurationView($this->configuration);
337
339 }
340
348 {
349 $this->configuration = $configuration;
350
351 try
352 {
353 $mailBody = $this->getMailBody();
354 }
355 catch (SystemException $exception)
356 {
357 $result = new Result();
358 $result->addError(new Error($exception->getMessage()));
359
360 return $result;
361 }
362
363 $sizeInBytes = mb_strlen($mailBody);
364 $sizeInKilobytes = $sizeInBytes / 1024;
365 $limitInKilobytes = 2.4 * 1024;
366 $saveAsTemplate = $this->configuration->get('save_as_template') === 'Y';
367
368 if ($saveAsTemplate && $sizeInKilobytes > $limitInKilobytes)
369 {
370 $result = new Result();
371
372 $result->addError(new Error(Loc::getMessage('SENDER_INTEGRATION_MAIL_BODY_LIMIT')));
373 return $result;
374 }
375
376 if (Integration\Bitrix24\Service::isCloud())
377 {
378 if ($mailBody && mb_strpos($mailBody, '#UNSUBSCRIBE_LINK#') === false)
379 {
380 $result = new Result();
381 $result->addError(new Error(Loc::getMessage('SENDER_INTEGRATION_MAIL_MESSAGE_ERR_NO_UNSUB_LINK')));
382 }
383
384 if (
385 $mailBody
386 && $configuration->getOption('APPROVE_CONFIRMATION')->getValue() === 'Y'
387 && !$configuration->getOption('APPROVE_CONFIRMATION_CONSENT')->getValue()
388 )
389 {
390 $result = new Result();
391 $result->addError(new Error(Loc::getMessage('SENDER_INTEGRATION_MAIL_MESSAGE_ERR_NO_APPROVE_CONFIRMATION_CONSENT')));
392
393 return $result;
394 }
395 }
396 parse_str(
397 $this->configuration->getOption('LINK_PARAMS')->getValue(),
398 $utmTags
399 );
400
401 $utm = [];
402 foreach ($utmTags as $utmTag => $value)
403 {
404 $utm[] = [
405 'CODE' => $utmTag,
406 'VALUE' => $value
407 ];
408 }
409
410 //TODO: compare with allowed email list
411 $emailFrom = $this->configuration->getOption('EMAIL_FROM')->getValue();
412 $emailFrom = (new Mail\Address($emailFrom))->get();
413 $this->configuration->getOption('EMAIL_FROM')->setValue($emailFrom);
414
415 $trackMail = $this->configuration->getOption('TRACK_MAIL')->getValue();
416
417 if (!$trackMail)
418 {
419 $this->configuration->getOption('TRACK_MAIL')->setValue('N');
420 }
421 return Entity\Message::create()
422 ->setCode($this->getCode())
423 ->setUtm($utm)
424 ->saveConfiguration($this->configuration);
425 }
426
433 public function copyConfiguration($id)
434 {
435 return Entity\Message::create()
436 ->setCode($this->getCode())
437 ->copyConfiguration($id);
438 }
439
445 protected function removePhp($html)
446 {
447 static $isCloud = null;
448 if ($isCloud === null)
449 {
451 Loader::includeModule('fileman');
452 }
453
454 if ($isCloud)
455 {
457 }
458
459 return $html;
460 }
461
467 public function getMailBody()
468 {
469 Loader::includeModule('fileman');
470
471 $msg = $this->configuration->getOption('MESSAGE')->getValue();
472 $template = $this->getTemplate();
473 if (!$template)
474 {
475 return $this->removePhp($msg);
476 }
477 if (!isset($template['FIELDS']) || !$template['FIELDS']['MESSAGE']['ON_DEMAND'])
478 {
479 return $this->removePhp($msg);
480 }
481
482 $templateHtml = null;
483 if (isset($template['FIELDS']) && isset($template['FIELDS']['MESSAGE']))
484 {
485 $templateHtml = $template['FIELDS']['MESSAGE']['VALUE'];
486 }
487 if (!$templateHtml && isset($template['HTML']))
488 {
489 $templateHtml = $template['HTML'];
490 }
491 if (!$templateHtml)
492 {
493 return $this->removePhp($msg);
494 }
495
496 $document = new Document;
497 $document->loadHTML($templateHtml);
498
499 try
500 {
501 if(!Block\Content\Engine::create($document)->setContent($msg)->fill())
502 {
503 return '';
504 }
505 }
506 catch (SystemException $exception)
507 {
508 throw new Posting\StopException();
509 }
510
511 StyleInliner::inlineDocument($document);
512 $msg = $document->saveHTML();
513 unset($document);
514
515 $msg = $this->removePhp($msg);
516 $msgTmp = Block\Editor::replaceCharset($msg, '#SENDER_MAIL_CHARSET#', true);
517 if ($msgTmp)
518 {
519 $msg = $msgTmp;
520 }
521
522 if (Option::get('sender', 'use_inliner_for_each_template_mail', 'N') != 'Y')
523 {
524 $this->configuration->set('BODY', $msg);
525 }
526
527 return $msg;
528 }
529
534 protected function getTemplate()
535 {
536 if (!$this->configuration->get('TEMPLATE_TYPE') || !$this->configuration->get('TEMPLATE_ID'))
537 {
538 return null;
539 }
540
542 ->withMessageCode(static::CODE)
543 ->withTypeId($this->configuration->get('TEMPLATE_TYPE'))
544 ->withId($this->configuration->get('TEMPLATE_ID'))
545 ->get();
546 }
547
553 protected static function fillHeadersByOptionHeaders(array $headers = array())
554 {
555 static $headerList = null;
556 if ($headerList === null)
557 {
558 $headerList = array();
559 // add headers from module options
560 $optionHeaders = Option::get('sender', 'mail_headers', '');
561 $optionHeaders = !empty($optionHeaders) ? unserialize($optionHeaders, ['allowed_classes' => false]) : array();
562 foreach ($optionHeaders as $optionHeader)
563 {
564 $optionHeader = trim($optionHeader);
565 if (!$optionHeader)
566 {
567 continue;
568 }
569
570 $optionHeaderParts = explode(':', $optionHeader);
571 $optionHeaderName = isset($optionHeaderParts[0]) ? $optionHeaderParts[0] : '';
572 $optionHeaderName = trim($optionHeaderName);
573 $optionHeaderValue = isset($optionHeaderParts[1]) ? $optionHeaderParts[1] : '';
574 $optionHeaderValue = trim($optionHeaderValue);
575 if (!$optionHeaderName || !$optionHeaderValue)
576 {
577 continue;
578 }
579
580 $headerList[$optionHeaderName] = $optionHeaderValue;
581 }
582 }
583
584 foreach ($headerList as $optionHeaderName => $optionHeaderValue)
585 {
586 $headers[$optionHeaderName] = $optionHeaderValue;
587 }
588
589 return $headers;
590 }
591}
static replaceCharset($html, $charset='#CHARSET#', $add=false)
Определения editor.php:1136
static removePhpFromHtml($html, $previousHtml=null, $canEditPhp=false, $canUseLpa=false)
Определения editormail.php:81
Определения result.php:20
Определения error.php:15
loadHTML($source)
Определения document.php:31
static fillHeadersByOptionHeaders(array $headers=array())
Определения messagemail.php:553
saveConfiguration(Message\Configuration $configuration)
Определения messagemail.php:347
static getPersonalizeList()
Определения posting.php:773
static create()
Определения selector.php:47
$template
Определения file_edit.php:49
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$result
Определения get_property_values.php:14
if(! $readOnly &&$adminList->EditAction()) if(! $readOnly &&($listID=$adminList->GroupAction()) $headerList)
Определения iblock_catalog_list.php:69
const CODE_MAIL
Определения ibase.php:17
Определения address.php:8
$GLOBALS['____1690880296']
Определения license.php:1
Определения adapter.php:9
$instance
Определения ps_b24_final.php:14