1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
message.php
См. документацию.
1<?php
2
3namespace Bitrix\Mail;
4
5use Bitrix\Mail\Integration\UI\EntitySelector\AddressBookProvider;
6use Bitrix\Main;
7use Bitrix\Main\Context;
8use Bitrix\Main\Localization\Loc;
9use Bitrix\UI\EntitySelector\Dialog;
10use Bitrix\UI\EntitySelector\ItemCollection;
11use CTimeZone;
12
14
16{
17
18 //const QUOTE_START_MARKER = '-- Bitrix24 Mail begin ---';
19 //const QUOTE_END_MARKER = '-- Bitrix24 Mail end ---';
20
21 const QUOTE_START_MARKER_HTML = '<div id="srvb24mqsm" style="font-family: \'srvb24mqsm\', serif;">&nbsp;</div>';
22 const QUOTE_END_MARKER_HTML = '<div id="qemb24msrv" style="font-family: \'qemb24msrv\', serif;">&nbsp;</div>';
23
24 const QUOTE_HTML_REGEX = '/<div\s[^>]+srvb24mqsm[^>]+>.*?<\/div>(.*)<div\s[^>]+qemb24msrv[^>]+>.*?<\/div>/is';
25
26 const QUOTE_PLACEHOLDER = '__QUOTE_PLACEHOLDER__';
27
28 protected $type;
29 protected $headers, $subject, $from, $to;
31 protected $secret;
32
33 public function __construct(array &$message, $type)
34 {
35 $this->type = $type;
36
37 $properties = array(
38 'headers', 'subject', 'from', 'to',
39 'text', 'html', 'attachments',
40 'secret'
41 );
42
43 foreach ($properties as $property)
44 {
45 if (isset($message[$property]))
46 $this->$property = $message[$property];
47 }
48 }
49
50 public static function stripQuotes($text): string
51 {
52 return preg_replace('/^("(.*)"|\'(.*)\')$/', '$2$3', $text);
53 }
54
55 private static function convertContactListToString($list): string
56 {
57 $string = '';
58
59 foreach ($list as $contact)
60 {
61 $name = static::stripQuotes($contact['name']);
62 $email = $contact['email'];
63
64 if ($name === $email)
65 {
66 $name = '';
67 }
68
69 $string .= Loc::getMessage('MAIL_QUOTE_MESSAGE_HEADER_CONTACT', ['#NAME#' => $name,'#EMAIL#' => $email]);
70
71 if (next($list))
72 {
73 $string .= ', ';
74 }
75 }
76
77 return $string;
78 }
79
80 final public static function getSelectedRecipientsForDialog($recipients = [], $updateData = false): ItemCollection
81 {
82 $options = [
83 'entities' => [
84 [
85 'id' => AddressBookProvider::PROVIDER_ENTITY_ID,
86 ],
87 ],
88 ];
89
90 $dialog = new Dialog($options);
91 $provider = $dialog->getEntity(AddressBookProvider::PROVIDER_ENTITY_ID)->getProvider();
92 $provider->setPreinstalledItems($recipients, $updateData);
93 $items = $provider->getItems([]);
94 $itemCollection = new ItemCollection();
95
96 foreach ($items as $item)
97 {
98 $itemCollection->add($item);
99 }
100
101 return $itemCollection;
102 }
103
104 final public static function wrapTheMessageWithAQuote($body, $subject, $timeString, $from = [], $to = [], $cc = [], bool $sanitized = false): string
105 {
106 $fieldDateInTimeStamp = makeTimestamp($timeString);
107 $titleDateFormat = Context::getCurrent()->getCulture()->getFullDateFormat()."&#013;H:i:s";
108 $formattedDate = FormatDate($titleDateFormat, $fieldDateInTimeStamp, (time() + CTimeZone::getOffset()));
109
110 $wrap = '';
111
112 $fromList = static::convertContactListToString($from);
113 $toList = static::convertContactListToString($to);
114 $ccList = static::convertContactListToString($cc);
115 if (!$sanitized)
116 {
117 $body = Helper\Message::sanitizeHtml($body);
118 }
119
120 if (empty($ccList))
121 {
122 $wrap .= Loc::getMessage('MAIL_QUOTE_MESSAGE_HEADER_WITHOUT_CC', [
123 '#DATE#' => $formattedDate,
124 '#SUBJECT#' => $subject,
125 '#BODY#' => $body,
126 '#FROM_LIST#' => $fromList,
127 '#TO_LIST#' => $toList,
128 '[blockquote]' => '<blockquote style="margin: 0 0 0 5px; padding: 5px 5px 5px 8px; border-left: 4px solid #e2e3e5; ">',
129 '[/blockquote]' => '</blockquote>'
130 ]);
131 }
132 else
133 {
134 $wrap .= Loc::getMessage('MAIL_QUOTE_MESSAGE_HEADER', [
135 '#DATE#' => $formattedDate,
136 '#SUBJECT#' => $subject,
137 '#BODY#' => $body,
138 '#FROM_LIST#' => $fromList,
139 '#TO_LIST#' => $toList,
140 '#CC_LIST#' => $ccList,
141 '[blockquote]' => '<blockquote style="margin: 0 0 0 5px; padding: 5px 5px 5px 8px; border-left: 4px solid #e2e3e5; ">',
142 '[/blockquote]' => '</blockquote>'
143 ]);
144 }
145
146 return $wrap;
147 }
148
155 final public static function getQuoteStartMarker($html = false)
156 {
157 return $html ? static::QUOTE_START_MARKER_HTML : static::QUOTE_START_MARKER;
158 }
159
166 final public static function getQuoteEndMarker($html = false)
167 {
168 return $html ? static::QUOTE_END_MARKER_HTML : static::QUOTE_END_MARKER;
169 }
170
176 public function attachmentsCount()
177 {
178 return is_array($this->attachments) ? count($this->attachments) : 0;
179 }
180
186 protected function parse()
187 {
188 if (isset($this->html))
189 {
190 $html = $this->html;
191
192 $html = str_replace(array("\r", "\n"), '', $html);
193 $html = preg_replace('/<br\s*\/?>/is', "\n", $html);
194
195 $html = str_ireplace('</div>', "</div>\n", $html);
196 $html = str_ireplace('</p>', "</p>\n", $html);
197 $html = preg_replace('/<\/h([1-6])>/i', "</h\\1>\n", $html);
198 $html = str_ireplace('</table>', "</table>\n", $html);
199 $html = str_ireplace('</tr>', "</tr>\n", $html);
200 $html = str_ireplace('</pre>', "</pre>\n", $html);
201
202 $html = preg_replace('/(\n\s*)?<div/i', "\n<div", $html);
203 $html = preg_replace('/(\n\s*)?<p(?=\s|>)/i', "\n<p", $html);
204 $html = preg_replace('/(\n\s*)?<h([1-6])/i', "\n<h\\2", $html);
205 $html = preg_replace('/(\n\s*)?<table/i', "\n<table", $html);
206 $html = preg_replace('/(\n\s*)?<tr/i', "\n<tr", $html);
207 $html = preg_replace('/(\n\s*)?<pre/i', "\n<pre", $html);
208
209 $html = preg_replace('/(\n\s*)?<hr[^>]*>(\s*\n)?/i', "\n<hr>\n", $html);
210
211 if ($this->type == 'reply' and $parts = $this->splitHtml($html))
212 {
213 list($before, $quote, $after) = $parts;
214 $html = sprintf('%s%s%s', $before, static::QUOTE_PLACEHOLDER, $after);
215 }
216
217 if ($this->attachmentsCount())
218 {
219 foreach ($this->attachments as $item)
220 {
221 $html = preg_replace(
222 sprintf('/<img[^>]+src\s*=\s*(\'|\")?\s*(cid:%s)\s*\1[^>]*>/is', preg_quote($item['contentId'], '/')),
223 sprintf('[ATTACHMENT=%s]', $item['uniqueId']),
224 $html
225 );
226 }
227 }
228
229 // TODO: Sanitizer
230 $html = preg_replace('/<style[^>]*>.*?<\/style>/is', '', $html);
231 $html = preg_replace('/<script[^>]*>.*?<\/script>/is', '', $html);
232 $html = preg_replace('/<title[^>]*>.*?<\/title>/is', '', $html);
233 $html = preg_replace('/<caption[^>]*>.*?<\/caption>/is', '', $html);
234
235 // TODO: Sanitizer
236 $html = preg_replace('/<a\s[^>]*href\s*=\s*([^\'\"\s>]+)\s*[^>]*>/is', '<a href="\1">', $html);
237
238 // TODO: TextParser
239 $html = preg_replace('/<strong[^>]*>(.*?)<\/strong>/is', '<b>\1</b>', $html);
240 $html = preg_replace('/<em[^>]*>(.*?)<\/em>/is', '<i>\1</i>', $html);
241 $html = preg_replace('/<blockquote[^>]*>(.*?)<\/blockquote>/is', '<quote>\1</quote>', $html);
242 $html = preg_replace('/<hr[^>]*>/is', '________________________________________', $html);
243 $html = preg_replace('/<del[^>]*>(.*?)<\/del>/is', '<s>\1</s>', $html);
244 $html = preg_replace('/<ins[^>]*>(.*?)<\/ins>/is', '<u>\1</u>', $html);
245 $html = preg_replace('/<h([1-6])[^>]*>(.*?)<\/h\1>/is', '<b>\2</b>', $html);
246 $html = preg_replace('/<dl[^>]*>(.*?)<\/dl>/is', '<ul>\1</ul>', $html);
247 $html = preg_replace('/<dt[^>]*>/is', '<li>', $html);
248 $html = preg_replace('/<dd[^>]*>/is', ' - ', $html);
249 $html = preg_replace('/<(sub|sup)[^>]*>(.*?)<\/\1>/is', '(\2)', $html);
250
251 // TODO: TextParser
252 $html = preg_replace('/<th[^>]*>(.*?)<\/th>/is', '<td>\1</td>', $html);
253
254 $sanitizer = new \CBXSanitizer();
255 //$sanitizer->setLevel(\CBXSanitizer::SECURE_LEVEL_MIDDLE);
256 $sanitizer->addTags(array(
257 'a' => array('href'),
258 'b' => array(),
259 'u' => array(),
260 's' => array(),
261 'i' => array(),
262 'img' => array('src'),
263 'font' => array('color', 'size', 'face'),
264 'ul' => array(),
265 'ol' => array(),
266 'li' => array(),
267 'table' => array(),
268 'tr' => array(),
269 'td' => array(),
270 'th' => array(),
271 'quote' => array(),
272 'br' => array(),
273 //'big' => array(),
274 //'small' => array(),
275 ));
276 $sanitizer->applyDoubleEncode(false);
277 $html = $sanitizer->sanitizeHtml($html);
278
279 $parser = new \CTextParser();
280 $text = $parser->convertHtmlToBB($html);
281
282 $text = html_entity_decode($text, ENT_QUOTES | ENT_HTML401, LANG_CHARSET);
283
284 // TODO: TextParser
285 $text = preg_replace('/<\/?([abuis]|img|font|ul|ol|li|table|tr|td|th|quote|br)(?=\s|>)[^>]*>/i', '', $text);
286
287 $text = preg_replace('/[\t\x20]+/', "\x20", $text);
288 }
289 else
290 {
292
293 $text = str_replace("\r\n", "\n", $text);
294 $text = str_replace("\r", "\n", $text);
295
296 if ($this->type == 'reply' and $parts = $this->splitText($text))
297 {
298 list($before, $quote, $after) = $parts;
299 $text = sprintf('%s%s%s', $before, static::QUOTE_PLACEHOLDER, $after);
300 }
301
302 if ($this->attachmentsCount())
303 {
304 foreach ($this->attachments as $item)
305 {
306 $text = str_replace(
307 sprintf('[cid:%s]', $item['contentId']),
308 sprintf('[ATTACHMENT=%s]', $item['uniqueId']),
309 $text
310 );
311 }
312 }
313 }
314
315 if ($this->type == 'reply' && mb_strpos($text, static::QUOTE_PLACEHOLDER))
316 {
317 $text = $this->removeReplyHead($text);
318 $text = preg_replace(sprintf('/\s*%s\s*/', preg_quote(static::QUOTE_PLACEHOLDER, '/')), "\n\n", $text);
319 }
320
321 if ($this->type == 'forward')
322 $text = $this->removeForwardHead($text);
323
324 // TODO: TextParser
325 $text = preg_replace('/\[tr\]\s*\[\/tr\]/is', '', $text);
326 $text = preg_replace('/\[table\]\s*\[\/table\]/is', '', $text);
327
328 $text = trim($text);
329 $text = preg_replace('/(\s*\n){2,}/', "\n\n", $text);
330
331 if (empty($text) && $this->attachmentsCount() == 1)
332 $text = sprintf('[ATTACHMENT=%s]', $item['uniqueId']);
333
334 if (!empty($this->secret))
335 $text = str_replace($this->secret, 'xxxxxxxx', $text);
336
337 return $text;
338 }
339
340 public static function parseMessage(array &$message)
341 {
342 $message = new static($message, null);
343
344 return $message->parse();
345 }
346
353 public static function parseReply(array &$message)
354 {
355 $reply = new static($message, 'reply');
356
357 return $reply->parse();
358 }
359
366 public static function parseForward(array &$message)
367 {
368 $forward = new static($message, 'forward');
369
370 return $forward->parse();
371 }
372
379 protected function splitHtml(&$html)
380 {
381 $parts = preg_split('/(<blockquote.+?<\/blockquote>)/is', $html, null, PREG_SPLIT_DELIM_CAPTURE);
382
383 if (count($parts) > 3)
384 {
385 $parts = array_merge(
386 array(join(array_slice($parts, 0, -2))),
387 array_slice($parts, -2)
388 );
389 }
390 else
391 {
392 if (count($parts) == 3)
393 $parts = preg_split('/(<blockquote.+<\/blockquote>)/is', $html, null, PREG_SPLIT_DELIM_CAPTURE);
394 }
395
396 if (count($parts) < 3)
397 $parts = preg_split(static::QUOTE_HTML_REGEX, $html, null, PREG_SPLIT_DELIM_CAPTURE);
398
399 if (count($parts) == 3)
400 return $parts;
401
402 return false;
403 }
404
411 protected function splitText(&$text)
412 {
413 $parts = preg_split('/((?:^>.*$\n?){2,})/m', $text, null, PREG_SPLIT_DELIM_CAPTURE);
414
415 if (count($parts) < 3)
416 $parts = preg_split('/((?:^\|.*$\n?){2,})/m', $text, null, PREG_SPLIT_DELIM_CAPTURE);
417
418 if (count($parts) < 3)
419 {
420 $outlookRegex = '/(
421 (?:^_{20,}\n(?:[\t\x20]*\n)?)?
422 (?:^(?:from|to|subject|sent|date):\x20[^\n]+$\n?){2,8}.*
423 )/ismx';
424 $parts = preg_split($outlookRegex, $text, null, PREG_SPLIT_DELIM_CAPTURE);
425 }
426
427 if (count($parts) == 3)
428 return $parts;
429
430 return false;
431 }
432
439 protected function scoreFullHead(&$head)
440 {
441 $score = 0;
442
443 if (preg_match_all('/^([^\:\n]{1,20}):[\t\x20]+(.+)$/mu', $head, $matches, PREG_SET_ORDER))
444 {
445 $subject = array(
446 'value' => $this->subject,
447 'strlen' => mb_strlen($this->subject),
448 'sgnlen' => mb_strlen(trim($this->subject))
449 );
450
451 $isHeader = function($key, $value) use (&$subject)
452 {
453 if (mb_strlen(trim($value)) >= 10 && $subject['sgnlen'] >= 10)
454 {
455 $dist = $subject['strlen'] - mb_strlen($value);
456
457 if (abs($dist) < 10)
458 {
459 if ($dist >= 0 && mb_strpos($subject['value'], $value) !== false)
460 {
461 return true;
462 }
463
464 if (max($subject['strlen'], mb_strlen($value)) < 256 && levenshtein($subject['value'], $value) < 10)
465 {
466 return true;
467 }
468 }
469 }
470
471 $date = preg_replace('/(?<=[\s\d])UT$/i', '+0000', trim($value));
472 if (preg_match('/\d{1,2}:\d{2}(:\d{2})?\x20?(am|pm)?/i', $date) && strtotime($date) !== false)
473 {
474 return true;
475 }
476
477 if (preg_match('/([a-z\d_](\.?[a-z\d_-]+)*)?[a-z\d_]@(([a-z\d][a-z\d-]*)?[a-z\d]\.?)+/i', $value))
478 {
479 return true;
480 }
481
482 return false;
483 };
484
485 foreach ($matches as $item)
486 {
487 $score += (int) $isHeader($item[1], $item[2]);
488 }
489 }
490
491 return $score;
492 }
493
500 protected function scoreShortHead(&$head)
501 {
502 $score = 0;
503
504 $regex = '/(?:^|\n)
505 (?<date>.{5,50}\d),?\x20
506 [^\d\n]{0,20}(?<time>\d{1,2}\:\d{2}(?:\:\d{2})?\x20?(?:am|pm)?),?\x20
507 (?<from>.+):\s*$
508 /ixu';
509 if (preg_match($regex, $head, $matches))
510 {
511 $matches['date'] = trim($matches['date']);
512 if (strtotime($matches['date']) !== false)
513 {
514 $score++;
515 }
516 else if (preg_match('/^[^\x20]+\x20+((?:[^\x20]+\x20+)?(.+))$/', $matches['date'], $date))
517 {
518 if (strtotime($date[1]) !== false || strtotime($date[2]) !== false)
519 $score++;
520 }
521
522 if (preg_match('/([a-z\d_](\.?[a-z\d_-]+)*)?[a-z\d_]@(([a-z\d][a-z\d-]*)?[a-z\d]\.?)+/i', $matches['from']))
523 $score++;
524 }
525
526 return $score;
527 }
528
535 protected function removeReplyHead(&$text)
536 {
537 list($before, $after) = explode(static::QUOTE_PLACEHOLDER, $text, 2);
538
539 if (!trim($before))
540 return $text;
541
542 $data = static::reduceTags($before);
543
553 $fullHeadRegex = '/(?:^|\n\n)
554 (?<hr>_{20,}\n(?:[\t\x20]*\n)?)?
555 (?<head>(?:[^\:\n]{1,20}:[\t\x20]+.+(?:\n|$)){2,6})\s*$
556 /xu';
557 if (preg_match($fullHeadRegex, $data, $matches))
558 {
559 $score = (int) !empty($matches['hr']);
560 $score += $this->scoreFullHead($matches['head']);
561
562 if ($score > 1)
563 {
564 $pattern = preg_replace(array('/.+/', '/\n/'), array('.+', '\n'), $matches[0]);
565 $before = preg_replace_callback(
566 sprintf('/%s$/', $pattern),
567 function($matches)
568 {
569 return Message::reduceHead($matches[0]);
570 },
571 $before
572 );
573
574 return sprintf('%s%s%s', $before, static::QUOTE_PLACEHOLDER, $after);
575 }
576 }
577
583 $shortHeadRegex = '/(?:^|\n)
584 (?<date>.{5,50}\d),?\x20
585 [^\d\n]{0,20}(?<time>\d{1,2}\:\d{2}(?:\:\d{2})?\x20?(?:am|pm)?),?\x20
586 (?<from>.+):\s*$
587 /ixu';
588 if (preg_match($shortHeadRegex, $data, $matches))
589 {
590 $score = 0;
591 $score += $this->scoreShortHead($matches[0]);
592
593 if ($score > 0)
594 {
595 $pattern = preg_replace(array('/.+/', '/\n/'), array('.+', '\n'), $matches[0]);
596 $before = preg_replace_callback(
597 sprintf('/%s$/', $pattern),
598 function($matches)
599 {
600 return Message::reduceHead($matches[0]);
601 },
602 $before
603 );
604
605 return sprintf('%s%s%s', $before, static::QUOTE_PLACEHOLDER, $after);
606 }
607 }
608
609 return $text;
610 }
611
618 protected function removeForwardHead(&$text)
619 {
620 if (!trim($text))
621 return $text;
622
623 $data = static::reduceTags($text);
624
625 $shortHeadRegex = '/(?:^|\n)\s*
626 -{3,}.{4,40}?-{3,}[\t\x20]*\n
627 (?<head>(?:[\t\x20]*\n)?
628 (?<date>.{5,50}\d),?\x20
629 [^\d\n]{0,20}(?<time>\d{1,2}\:\d{2}(?:\:\d{2})?\x20?(?:am|pm)?),?\x20
630 (?<from>.+):(?:\s*\n)?)
631 /ixu';
632
633 $hasMarker = preg_match($shortHeadRegex, $data);
634 $fullHeadRegex = '/(?:^|\n\n)\s*
635 (?<marker>-{3,}.{4,40}?-{3,}[\t\x20]*\n)'.($hasMarker ? '' : '?').'
636 (?<head>(?:[\t\x20]*\n)?
637 (?<lines>(?:[^\:\n]{1,20}:[\t\x20]+.+(?:\n|$)){2,6}))
638 \s*(?:\n|$)
639 /xu';
640
641 if (preg_match($fullHeadRegex, $data, $matches, PREG_OFFSET_CAPTURE))
642 {
643 $score = (int) !empty($matches['marker'][0]);
644 $score += $this->scoreFullHead($matches['lines'][0]);
645
646 if ($score > 1)
647 {
648 // @TODO: Main\Text\BinaryString::getSubstring()
649 $pattern = preg_replace(
650 array('/.+/', '/\n/'), array('.+', '\n'),
651 array(substr($data, 0, $matches['head'][1]), $matches['head'][0])
652 );
653
654 return preg_replace_callback(
655 sprintf('/^(%s)(%s)/', $pattern[0], $pattern[1]),
656 function($matches)
657 {
658 return sprintf("%s\n\n%s", $matches[1], Message::reduceHead($matches[2]));
659 },
660 $text
661 );
662 }
663 }
664
665 if (preg_match($shortHeadRegex, $data, $matches, PREG_OFFSET_CAPTURE))
666 {
667 $score = 0;
668 $score += $this->scoreShortHead($matches['head'][0]);
669
670 if ($score > 0)
671 {
672 // @TODO: Main\Text\BinaryString::getSubstring()
673 $pattern = preg_replace(
674 array('/.+/', '/\n/'), array('.+', '\n'),
675 array(substr($data, 0, $matches['head'][1]), $matches['head'][0])
676 );
677
678 return preg_replace_callback(
679 sprintf('/^(%s)(%s)/', $pattern[0], $pattern[1]),
680 function($matches)
681 {
682 return sprintf("%s\n\n%s", $matches[1], Message::reduceHead($matches[2]));
683 },
684 $text
685 );
686 }
687 }
688
689 return $text;
690 }
691
698 protected static function reduceTags(&$text)
699 {
700 $data = $text;
701
702 $data = preg_replace('/^(\[\/?(\*|[busi]|img|table|tr|td|th|quote|(url|size|color|font|list)(=.+?)?)\])+$/im', "\t", $data);
703 $data = preg_replace('/\[\/?(\*|[busi]|img|table|tr|td|th|quote|(url|size|color|font|list)(=.+?)?)\]/i', '', $data);
704
705 return $data;
706 }
707
714 public static function reduceHead(&$text)
715 {
716 preg_match_all('/\[\/?([busi]|img|table|tr|td|th|quote|(url|size|color|font|list)(=.+?)?)\]/is', $text, $tags);
717
718 $result = join($tags[0]);
719 unset($tags);
720
721 do
722 {
723 $result = preg_replace('/\[([busi]|img|table|tr|td|th|quote|url|size|color|font|list)(=.+?)?\]\[\/\1\]/is', '', $result, -1, $n2);
724 }
725 while ($n2 > 0);
726
727 return $result;
728 }
729
730}
if(!Loader::includeModule('messageservice')) $provider
Определения callback_ednaruimhpx.php:21
static getSelectedRecipientsForDialog($recipients=[], $updateData=false)
Определения message.php:80
$from
Определения message.php:29
removeForwardHead(&$text)
Определения message.php:618
static stripQuotes($text)
Определения message.php:50
static wrapTheMessageWithAQuote($body, $subject, $timeString, $from=[], $to=[], $cc=[], bool $sanitized=false)
Определения message.php:104
static reduceHead(&$text)
Определения message.php:714
const QUOTE_START_MARKER_HTML
Определения message.php:21
static parseReply(array &$message)
Определения message.php:353
parse()
Определения message.php:186
$headers
Определения message.php:29
scoreFullHead(&$head)
Определения message.php:439
$html
Определения message.php:30
static reduceTags(&$text)
Определения message.php:698
attachmentsCount()
Определения message.php:176
splitHtml(&$html)
Определения message.php:379
__construct(array &$message, $type)
Определения message.php:33
const QUOTE_END_MARKER_HTML
Определения message.php:22
$type
Определения message.php:28
scoreShortHead(&$head)
Определения message.php:500
$attachments
Определения message.php:30
$secret
Определения message.php:31
static getQuoteStartMarker($html=false)
Определения message.php:155
static getQuoteEndMarker($html=false)
Определения message.php:166
$to
Определения message.php:29
const QUOTE_HTML_REGEX
Определения message.php:24
splitText(&$text)
Определения message.php:411
static parseForward(array &$message)
Определения message.php:366
removeReplyHead(&$text)
Определения message.php:535
const QUOTE_PLACEHOLDER
Определения message.php:26
$text
Определения message.php:30
$subject
Определения message.php:29
static parseMessage(array &$message)
Определения message.php:340
static loadMessages($file)
Определения loc.php:65
$options
Определения commerceml2.php:49
$data['IS_AVAILABLE']
Определения .description.php:13
</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
const LANG_CHARSET
Определения include.php:65
FormatDate($format="", $timestamp=false, $now=false, ?string $languageId=null)
Определения tools.php:871
$name
Определения menu_edit.php:35
$email
Определения payment.php:49
$message
Определения payment.php:8
if(empty($signedUserToken)) $key
Определения quickway.php:257
$text
Определения template_pdf.php:79
</p ></td >< td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 2.0pt 0cm 2.0pt;height:9.0pt'>< p class=Normal align=center style='margin:0cm;margin-bottom:.0001pt;text-align:center;line-height:normal'>< a name=ТекстовоеПоле54 ></a ><?=($taxRate > count( $arTaxList) > 0) ? $taxRate."%"
Определения waybill.php:936
$items
Определения template.php:224
if(!Loader::includeModule('sale')) $pattern
Определения index.php:20
$matches
Определения index.php:22