1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
posting.php
См. документацию.
1<?php
3
6
8{
9 public $LAST_ERROR = '';
10 //email count for one hit
11 public static $current_emails_per_hit = 0;
12
13 //get by ID
14 public static function GetByID($ID)
15 {
16 global $DB;
17 $ID = intval($ID);
18
19 $strSql = '
20 SELECT
21 P.*
22 ,' . $DB->DateToCharFunction('P.TIMESTAMP_X', 'FULL') . ' AS TIMESTAMP_X
23 ,' . $DB->DateToCharFunction('P.DATE_SENT', 'FULL') . ' AS DATE_SENT
24 ,' . $DB->DateToCharFunction('P.AUTO_SEND_TIME', 'FULL') . ' AS AUTO_SEND_TIME
25 FROM b_posting P
26 WHERE P.ID=' . $ID . '
27 ';
28
29 return $DB->Query($strSql);
30 }
31
32 //list of categories linked with message
33 public static function GetRubricList($ID)
34 {
35 global $DB;
36 $ID = intval($ID);
37
38 $strSql = '
39 SELECT
40 R.ID
41 ,R.NAME
42 ,R.SORT
43 ,R.LID
44 ,R.ACTIVE
45 FROM
46 b_list_rubric R
47 ,b_posting_rubric PR
48 WHERE
49 R.ID=PR.LIST_RUBRIC_ID
50 AND PR.POSTING_ID=' . $ID . '
51 ORDER BY
52 R.LID, R.SORT, R.NAME
53 ';
54
55 return $DB->Query($strSql);
56 }
57
58 //list of user group linked with message
59 public static function GetGroupList($ID)
60 {
61 global $DB;
62 $ID = intval($ID);
63
64 $strSql = '
65 SELECT
66 G.ID
67 ,G.NAME
68 FROM
69 b_group G
70 ,b_posting_group PG
71 WHERE
72 G.ID=PG.GROUP_ID
73 AND PG.POSTING_ID=' . $ID . '
74 ORDER BY
75 G.C_SORT, G.ID
76 ';
77
78 return $DB->Query($strSql);
79 }
80
81 // delete by ID
82 public static function Delete($ID)
83 {
84 global $DB;
85 $ID = intval($ID);
86
88
89 $res = $DB->Query("DELETE FROM b_posting_rubric WHERE POSTING_ID='" . $ID . "'");
90 if ($res)
91 {
92 $res = $DB->Query("DELETE FROM b_posting_group WHERE POSTING_ID='" . $ID . "' ");
93 }
94 if ($res)
95 {
96 $res = $DB->Query("DELETE FROM b_posting_email WHERE POSTING_ID='" . $ID . "' ");
97 }
98 if ($res)
99 {
100 $res = $DB->Query("DELETE FROM b_posting WHERE ID='" . $ID . "' ");
101 }
102
103 return $res;
104 }
105
106 public static function OnGroupDelete($group_id)
107 {
108 global $DB;
109 $group_id = intval($group_id);
110
111 return $DB->Query('DELETE FROM b_posting_group WHERE GROUP_ID=' . $group_id, true);
112 }
113
114 public static function DeleteFile($ID, $file_id=false)
115 {
116 global $DB;
117
118 $rsFile = CPosting::GetFileList($ID, $file_id);
119 while ($arFile = $rsFile->Fetch())
120 {
121 $DB->Query('DELETE FROM b_posting_file where POSTING_ID=' . intval($ID) . ' AND FILE_ID=' . intval($arFile['ID']));
122 CFile::Delete(intval($arFile['ID']));
123 }
124 }
125
126 public static function SplitFileName($file_name)
127 {
128 $found = [];
129 // exapmle(2).txt
130 if (preg_match('/^(.*)\\((\\d+?)\\)(\\..+?)$/', $file_name, $found))
131 {
132 $fname = $found[1];
133 $fext = $found[3];
134 $index = $found[2];
135 }
136 // example(2)
137 elseif (preg_match('/^(.*)\\((\\d+?)\\)$/', $file_name, $found))
138 {
139 $fname = $found[1];
140 $fext = '';
141 $index = $found[2];
142 }
143 // example.txt
144 elseif (preg_match('/^(.*)(\\..+?)$/', $file_name, $found))
145 {
146 $fname = $found[1];
147 $fext = $found[2];
148 $index = 0;
149 }
150 // example
151 else
152 {
153 $fname = $file_name;
154 $fext = '';
155 $index = 0;
156 }
157 return [$fname, $fext, $index];
158 }
159
160 public function SaveFile($ID, $file)
161 {
162 global $DB, $APPLICATION;
163 $ID = intval($ID);
164 $filesSize = 0;
165
166 $arFileName = CPosting::SplitFileName($file['name']);
167 //Check if file with this name already exists
168 $arSameNames = [];
169 $rsFile = CPosting::GetFileList($ID);
170 while ($arFile = $rsFile->Fetch())
171 {
172 $filesSize += $arFile['FILE_SIZE'];
173 $arSavedName = CPosting::SplitFileName($arFile['ORIGINAL_NAME']);
174 if ($arFileName[0] == $arSavedName[0] && $arFileName[1] == $arSavedName[1])
175 {
176 $arSameNames[$arSavedName[2]] = true;
177 }
178 }
179
180 $max_files_size = COption::GetOptionString('subscribe', 'max_files_size') * 1024 * 1024;
181 if ($max_files_size > 0)
182 {
183 $filesSize += $file['size'];
184 if ($filesSize > $max_files_size)
185 {
186 $this->LAST_ERROR = GetMessage('class_post_err_files_size', [
187 '#MAX_FILES_SIZE#' => CFile::FormatSize($max_files_size),
188 ]);
189 $APPLICATION->ThrowException($this->LAST_ERROR);
190 return false;
191 }
192 }
193
194 while (array_key_exists($arFileName[2], $arSameNames))
195 {
196 $arFileName[2]++;
197 }
198
199 if ($arFileName[2] > 0)
200 {
201 $file['name'] = $arFileName[0] . '(' . ($arFileName[2]) . ')' . $arFileName[1];
202 }
203
204 //save file
205 $file['MODULE_ID'] = 'subscribe';
206 $fid = intval(CFile::SaveFile($file, 'subscribe', true, true));
207 if (($fid > 0) && $DB->Query('INSERT INTO b_posting_file (POSTING_ID, FILE_ID) VALUES (' . $ID . ' ,' . $fid . ')'))
208 {
209 return true;
210 }
211 else
212 {
213 $this->LAST_ERROR = GetMessage('class_post_err_att');
214 $APPLICATION->ThrowException($this->LAST_ERROR);
215 return false;
216 }
217 }
218
219 public static function GetFileList($ID, $file_id=false)
220 {
221 global $DB;
222 $ID = intval($ID);
223 $file_id = intval($file_id);
224
225 $strSql = '
226 SELECT
227 F.ID
228 ,F.FILE_SIZE
229 ,F.ORIGINAL_NAME
230 ,F.SUBDIR
231 ,F.FILE_NAME
232 ,F.CONTENT_TYPE
233 ,F.HANDLER_ID
234 FROM
235 b_file F
236 ,b_posting_file PF
237 WHERE
238 F.ID=PF.FILE_ID
239 AND PF.POSTING_ID=' . $ID . '
240 ' . ($file_id > 0 ? 'AND PF.FILE_ID = ' . $file_id : '') . '
241 ORDER BY F.ID
242 ';
243
244 return $DB->Query($strSql);
245 }
246
247 //check fields before writing
248 public function CheckFields($arFields, $ID)
249 {
251 global $DB;
253 global $APPLICATION;
254
255 $this->LAST_ERROR = '';
256 $aMsg = [];
257
258 if (array_key_exists('FROM_FIELD', $arFields))
259 {
260 if (mb_strlen($arFields['FROM_FIELD']) < 3 || !check_email($arFields['FROM_FIELD']))
261 {
262 $aMsg[] = ['id' => 'FROM_FIELD', 'text' => GetMessage('class_post_err_email')];
263 }
264 }
265
266 if (!array_key_exists('DIRECT_SEND', $arFields) || $arFields['DIRECT_SEND'] == 'N')
267 {
268 if (array_key_exists('TO_FIELD', $arFields) && $arFields['TO_FIELD'] == '')
269 {
270 $aMsg[] = ['id' => 'TO_FIELD', 'text' => GetMessage('class_post_err_to')];
271 }
272 }
273
274 if (array_key_exists('SUBJECT', $arFields))
275 {
276 if ($arFields['SUBJECT'] == '')
277 {
278 $aMsg[] = ['id' => 'SUBJECT', 'text' => GetMessage('class_post_err_subj')];
279 }
280 }
281
282 if (array_key_exists('BODY', $arFields))
283 {
284 if ($arFields['BODY'] == '')
285 {
286 $aMsg[] = ['id' => 'BODY', 'text' => GetMessage('class_post_err_text')];
287 }
288 }
289
290 if (array_key_exists('AUTO_SEND_TIME', $arFields) && $arFields['AUTO_SEND_TIME'] !== false)
291 {
292 if ($DB->IsDate($arFields['AUTO_SEND_TIME'], false, false, 'FULL') !== true)
293 {
294 $aMsg[] = ['id' => 'AUTO_SEND_TIME', 'text' => GetMessage('class_post_err_auto_time')];
295 }
296 }
297
298 if (array_key_exists('CHARSET', $arFields))
299 {
300 $sCharset = COption::GetOptionString('subscribe', 'posting_charset');
301 $aCharset = explode(',', mb_strtolower($sCharset));
302 if (!in_array(mb_strtolower($arFields['CHARSET']), $aCharset, true))
303 {
304 $aMsg[] = ['id' => 'CHARSET', 'text' => GetMessage('class_post_err_charset')];
305 }
306 }
307
308 if (!empty($aMsg))
309 {
310 $e = new CAdminException($aMsg);
311 $APPLICATION->ThrowException($e);
312 $this->LAST_ERROR = $e->GetString();
313 return false;
314 }
315
316 return true;
317 }
318
319 //relation with categories
320 public function UpdateRubrics($ID, $aRubric)
321 {
322 global $DB;
323 $ID = intval($ID);
324
325 $DB->Query('DELETE FROM b_posting_rubric WHERE POSTING_ID=' . $ID);
326 $arID = [];
327 if (is_array($aRubric))
328 {
329 foreach ($aRubric as $i)
330 {
331 $arID[] = intval($i);
332 }
333 }
334 if (count($arID) > 0)
335 {
336 $DB->Query('
337 INSERT INTO b_posting_rubric (POSTING_ID, LIST_RUBRIC_ID)
338 SELECT ' . $ID . ', ID
339 FROM b_list_rubric
340 WHERE ID IN (' . implode(', ',$arID) . ')
341 '
342 );
343 }
344 }
345
346 //relation with user groups
347 public function UpdateGroups($ID, $aGroup)
348 {
349 global $DB;
350 $ID = intval($ID);
351
352 $DB->Query("DELETE FROM b_posting_group WHERE POSTING_ID='" . $ID . "'");
353 $arID = [];
354 if (is_array($aGroup))
355 {
356 foreach ($aGroup as $i)
357 {
358 $arID[] = intval($i);
359 }
360 }
361 if (count($arID) > 0)
362 {
363 $DB->Query('
364 INSERT INTO b_posting_group (POSTING_ID, GROUP_ID)
365 SELECT ' . $ID . ', ID
366 FROM b_group
367 WHERE ID IN (' . implode(', ',$arID) . ')
368 '
369 );
370 }
371 }
372
373 //Addition
374 public function Add($arFields)
375 {
376 global $DB;
377
378 if (!$this->CheckFields($arFields, 0))
379 {
380 return false;
381 }
382
383 if (!array_key_exists('MSG_CHARSET', $arFields))
384 {
385 $arFields['MSG_CHARSET'] = LANG_CHARSET;
386 }
387 $arFields['VERSION'] = '2';
388 $arFields['~TIMESTAMP_X'] = $DB->CurrentTimeFunction();
389
390 $ID = $DB->Add('b_posting', $arFields, ['BCC_FIELD','BODY']);
391 if ($ID > 0)
392 {
393 $this->UpdateRubrics($ID, $arFields['RUB_ID']);
394 $this->UpdateGroups($ID, $arFields['GROUP_ID']);
395 }
396 return $ID;
397 }
398
399 //Update
400 public function Update($ID, $arFields)
401 {
402 global $DB;
403 $ID = intval($ID);
404
405 if (!$this->CheckFields($arFields, $ID))
406 {
407 return false;
408 }
409
410 $arFields['~TIMESTAMP_X'] = $DB->CurrentTimeFunction();
411
412 $strUpdate = $DB->PrepareUpdate('b_posting', $arFields);
413 if ($strUpdate != '')
414 {
415 $strSql = 'UPDATE b_posting SET ' . $strUpdate . ' WHERE ID=' . $ID;
416 $arBinds = [
417 'BCC_FIELD' => $arFields['BCC_FIELD'],
418 //"SENT_BCC" => $arFields["SENT_BCC"],
419 'BODY' => $arFields['BODY'],
420 //"ERROR_EMAIL" => $arFields["ERROR_EMAIL"],
421 //"BCC_TO_SEND" => $arFields["BCC_TO_SEND"],
422 ];
423 if (!$DB->QueryBind($strSql, $arBinds))
424 {
425 return false;
426 }
427 }
428 if (is_set($arFields, 'RUB_ID'))
429 {
430 $this->UpdateRubrics($ID, $arFields['RUB_ID']);
431 }
432 if (is_set($arFields, 'GROUP_ID'))
433 {
434 $this->UpdateGroups($ID, $arFields['GROUP_ID']);
435 }
436
437 return true;
438 }
439
440 public function GetEmails($post_arr)
441 {
442 $aEmail = [];
443
444 //send to categories
445 $aPostRub = [];
446 $post_rub = static::GetRubricList($post_arr['ID']);
447 while ($post_rub_arr = $post_rub->Fetch())
448 {
449 $aPostRub[] = $post_rub_arr['ID'];
450 }
451
452 $subscr = CSubscription::GetList(
453 ['ID' => 'ASC'],
454 [
455 'RUBRIC_MULTI' => $aPostRub,
456 'CONFIRMED' => 'Y',
457 'ACTIVE' => 'Y',
458 'FORMAT' => $post_arr['SUBSCR_FORMAT'],
459 'EMAIL' => $post_arr['EMAIL_FILTER'],
460 ]
461 );
462 while (($subscr_arr = $subscr->Fetch()))
463 {
464 $aEmail[] = $subscr_arr['EMAIL'];
465 }
466
467 //send to user groups
468 $aPostGrp = [];
469 $post_grp = static::GetGroupList($post_arr['ID']);
470 while ($post_grp_arr = $post_grp->Fetch())
471 {
472 $aPostGrp[] = $post_grp_arr['ID'];
473 }
474
475 if (count($aPostGrp) > 0)
476 {
477 $user = CUser::GetList(
478 'id', 'asc',
479 ['GROUP_MULTI' => $aPostGrp, 'ACTIVE' => 'Y', 'EMAIL' => $post_arr['EMAIL_FILTER']]
480 );
481 while (($user_arr = $user->Fetch()))
482 {
483 $aEmail[] = $user_arr['EMAIL'];
484 }
485 }
486
487 //from additional emails
488 $BCC = $post_arr['BCC_FIELD'];
489 if ($post_arr['DIRECT_SEND'] == 'Y')
490 {
491 $BCC .= ($BCC ? ',' : '') . $post_arr['TO_FIELD'];
492 }
493 if ($BCC <> '')
494 {
495 $BCC = str_replace("\r\n", "\n", $BCC);
496 $BCC = str_replace("\n", ',', $BCC);
497 $aBcc = explode(',', $BCC);
498 foreach ($aBcc as $bccEmail)
499 {
500 $bccEmail = trim($bccEmail);
501 if ($bccEmail !== '')
502 {
503 $aEmail[] = $bccEmail;
504 }
505 }
506 }
507
508 $aEmail = array_unique($aEmail);
509
510 return $aEmail;
511 }
512
513 public static function AutoSend($ID=false, $limit=false, $site_id=false)
514 {
515 if ($ID === false)
516 {
517 //Here is cron job entry
518 $cPosting = new CPosting;
519 $rsPosts = $cPosting->GetList(
520 ['AUTO_SEND_TIME' => 'ASC', 'ID' => 'ASC'],
521 ['STATUS_ID' => 'P', 'AUTO_SEND_TIME_2' => ConvertTimeStamp(false, 'FULL')]
522 );
523 while ($arPosts = $rsPosts->Fetch())
524 {
525 if ($limit === true)
526 {
527 $maxcount = COption::GetOptionInt('subscribe', 'subscribe_max_emails_per_hit') - self::$current_emails_per_hit;
528 if ($maxcount <= 0)
529 {
530 break;
531 }
532 }
533 else
534 {
535 $maxcount = 0;
536 }
537 $cPosting->SendMessage($arPosts['ID'], 0, $maxcount);
538 }
539 }
540 else
541 {
542 if ($site_id && $site_id != SITE_ID)
543 {
544 return 'CPosting::AutoSend(' . $ID . ($limit ? ',true' : ',false') . ',"' . $site_id . '");';
545 }
546
547 //Here is agent entry
548 if ($limit === true)
549 {
550 $maxcount = COption::GetOptionInt('subscribe', 'subscribe_max_emails_per_hit') - self::$current_emails_per_hit;
551 if ($maxcount <= 0)
552 {
553 return 'CPosting::AutoSend(' . $ID . ',true' . ($site_id ? ',"' . $site_id . '"' : '') . ');';
554 }
555 }
556 else
557 {
558 $maxcount = 0;
559 }
560
561 $cPosting = new CPosting;
562 $res = $cPosting->SendMessage($ID, COption::GetOptionString('subscribe', 'posting_interval'), $maxcount, true);
563 if ($res == 'CONTINUE')
564 {
565 return 'CPosting::AutoSend(' . $ID . ($limit ? ',true' : ',false') . ($site_id ? ',"' . $site_id . '"' : '') . ');';
566 }
567 }
568 return '';
569 }
570
571 //Send message
572 public function SendMessage($ID, $timeout=0, $maxcount=0, $check_charset=false)
573 {
574 global $DB;
575
576 $eol = Mail\Mail::getMailEol();
577 $ID = intval($ID);
578 $timeout = intval($timeout);
579 $start_time = microtime(1);
580
581 @set_time_limit(0);
582 $this->LAST_ERROR = '';
583
584 $post = static::GetByID($ID);
585 if (!($post_arr = $post->Fetch()))
586 {
587 $this->LAST_ERROR .= GetMessage('class_post_err_notfound');
588 return false;
589 }
590
591 if ($post_arr['STATUS'] != 'P')
592 {
593 $this->LAST_ERROR .= GetMessage('class_post_err_status') . '<br>';
594 return false;
595 }
596
597 if (
598 $check_charset
599 && ($post_arr['MSG_CHARSET'] <> '')
600 && (mb_strtoupper($post_arr['MSG_CHARSET']) !== mb_strtoupper(LANG_CHARSET))
601 )
602 {
603 return 'CONTINUE';
604 }
605
606 if (CPosting::Lock($ID) === false)
607 {
608 return 'CONTINUE';
609 }
610
611 if ($post_arr['VERSION'] <> '2')
612 {
613 if (is_string($post_arr['BCC_TO_SEND']) && $post_arr['BCC_TO_SEND'] <> '')
614 {
615 $a = explode(',', $post_arr['BCC_TO_SEND']);
616 foreach ($a as $e)
617 {
618 $e = trim($e, " \t\n\r");
619 if ($e !== '')
620 {
621 $DB->Query('INSERT INTO b_posting_email (POSTING_ID, STATUS, EMAIL) VALUES (' . $ID . ", 'Y', '" . $DB->ForSQL($e) . "')", true);
622 }
623 }
624 }
625
626 if (is_string($post_arr['ERROR_EMAIL']) && $post_arr['ERROR_EMAIL'] <> '')
627 {
628 $a = explode(',', $post_arr['ERROR_EMAIL']);
629 foreach ($a as $e)
630 {
631 $e = trim($e, " \t\n\r");
632 if ($e !== '')
633 {
634 $DB->Query('INSERT INTO b_posting_email (POSTING_ID, STATUS, EMAIL) VALUES (' . $ID . ", 'E', '" . $DB->ForSQL($e) . "')", true);
635 }
636 }
637 }
638
639 if (is_string($post_arr['SENT_BCC']) && $post_arr['SENT_BCC'] <> '')
640 {
641 $a = explode(',', $post_arr['SENT_BCC']);
642 foreach ($a as $e)
643 {
644 $e = trim($e, " \t\n\r");
645 if ($e !== '')
646 {
647 $DB->Query('INSERT INTO b_posting_email (POSTING_ID, STATUS, EMAIL) VALUES (' . $ID . ", 'N', '" . $DB->ForSQL($e) . "')", true);
648 }
649 }
650 }
651
652 $DB->Query("UPDATE b_posting SET VERSION='2', BCC_TO_SEND=null, ERROR_EMAIL=null, SENT_BCC=null WHERE ID=" . $ID);
653 }
654
655 $tools = new CMailTools;
656 //MIME with attachments
657 if ($post_arr['BODY_TYPE'] == 'html' && COption::GetOptionString('subscribe', 'attach_images') == 'Y')
658 {
659 $post_arr['BODY'] = $tools->ReplaceImages($post_arr['BODY']);
660 }
661
662 if ($post_arr['CHARSET'] <> '')
663 {
664 $from_charset = $post_arr['MSG_CHARSET'] ?: SITE_CHARSET;
665 $post_arr['BODY'] = Encoding::convertEncoding($post_arr['BODY'], $from_charset, $post_arr['CHARSET']);
666 $post_arr['SUBJECT'] = Encoding::convertEncoding($post_arr['SUBJECT'], $from_charset, $post_arr['CHARSET']);
667 $post_arr['FROM_FIELD'] = Encoding::convertEncoding($post_arr['FROM_FIELD'], $from_charset, $post_arr['CHARSET']);
668 }
669
670 //Preparing message header, text, subject
671 $sBody = str_replace("\r\n", "\n", $post_arr['BODY']);
672 $sBody = implode(
673 "\n",
674 array_filter(
675 preg_split('/(.{512}[^ ]* )/', $sBody . ' ', -1, PREG_SPLIT_DELIM_CAPTURE)
676 )
677 ); //Some MTA has 4K limit for fgets function. So we have to split the message body.
678 if (COption::GetOptionString('main', 'CONVERT_UNIX_NEWLINE_2_WINDOWS', 'N') == 'Y')
679 {
680 $sBody = str_replace("\n", "\r\n", $sBody);
681 }
682
683 if (COption::GetOptionString('subscribe', 'allow_8bit_chars') <> 'Y')
684 {
685 $sSubject = CMailTools::EncodeSubject($post_arr['SUBJECT'], $post_arr['CHARSET']);
686 $sFrom = CMailTools::EncodeHeaderFrom($post_arr['FROM_FIELD'], $post_arr['CHARSET']);
687 }
688 else
689 {
690 $sSubject = $post_arr['SUBJECT'];
691 $sFrom = $post_arr['FROM_FIELD'];
692 }
693
694 if ($post_arr['BODY_TYPE'] == 'html')
695 {
696 //URN2URI
697 $tmpTools = new CMailTools;
698 $sBody = $tmpTools->ReplaceHrefs($sBody);
699 }
700
701 $bHasAttachments = false;
702 $sHeader = '';
703 $sBoundary = '';
704
705 if (count($tools->aMatches) > 0)
706 {
707 $bHasAttachments = true;
708
709 $sBoundary = '----------' . uniqid('');
710 $sHeader =
711 'From: ' . $sFrom . $eol
712 . 'X-Bitrix-Posting: ' . $post_arr['ID'] . $eol
713 . 'MIME-Version: 1.0' . $eol
714 . 'Content-Type: multipart/mixed; boundary="' . $sBoundary . '"' . $eol
715 . 'Content-Transfer-Encoding: 8bit';
716
717 $sBody =
718 '--' . $sBoundary . $eol
719 . 'Content-Type: ' . ($post_arr['BODY_TYPE'] == 'html' ? 'text/html' : 'text/plain') . ($post_arr['CHARSET'] <> '' ? '; charset=' . $post_arr['CHARSET'] : '') . $eol
720 . 'Content-Transfer-Encoding: 8bit' . $eol . $eol
721 . $sBody . $eol;
722
723 foreach ($tools->aMatches as $attachment)
724 {
725 if ($post_arr['CHARSET'] <> '')
726 {
727 $from_charset = $post_arr['MSG_CHARSET'] ?: SITE_CHARSET;
728 $attachment['DEST'] = Encoding::convertEncoding($attachment['DEST'], $from_charset, $post_arr['CHARSET']);
729 }
730
731 if (COption::GetOptionString('subscribe', 'allow_8bit_chars') <> 'Y')
732 {
733 $name = CMailTools::EncodeSubject($attachment['DEST'], $post_arr['CHARSET']);
734 }
735 else
736 {
737 $name = $attachment['DEST'];
738 }
739
740 $sBody .=
741 $eol . '--' . $sBoundary . $eol
742 . 'Content-Type: ' . $attachment['CONTENT_TYPE'] . '; name="' . $name . '"' . $eol
743 . 'Content-Transfer-Encoding: base64' . $eol
744 . 'Content-ID: <' . $attachment['ID'] . '>' . $eol . $eol
745 . chunk_split(
746 base64_encode(
747 file_get_contents($attachment['PATH'])
748 ), 72, $eol
749 );
750 }
751 }
752
753 $arFiles = [];
754 $maxFileSize = intval(COption::GetOptionInt('subscribe', 'max_file_size'));
755 $rsFile = CPosting::GetFileList($ID);
756 while ($arFile = $rsFile->Fetch())
757 {
758 if (
759 $maxFileSize == 0
760 || $arFile['FILE_SIZE'] <= $maxFileSize
761 )
762 {
763 $arFiles[] = $arFile;
764 }
765 }
766
767 if (!empty($arFiles))
768 {
769 if (!$bHasAttachments)
770 {
771 $bHasAttachments = true;
772 $sBoundary = '----------' . uniqid('');
773 $sHeader =
774 'From: ' . $sFrom . $eol
775 . 'X-Bitrix-Posting: ' . $post_arr['ID'] . $eol
776 . 'MIME-Version: 1.0' . $eol
777 . 'Content-Type: multipart/mixed; boundary="' . $sBoundary . '"' . $eol
778 . 'Content-Transfer-Encoding: 8bit';
779
780 $sBody =
781 '--' . $sBoundary . $eol
782 . 'Content-Type: ' . ($post_arr['BODY_TYPE'] == 'html' ? 'text/html' : 'text/plain') . ($post_arr['CHARSET'] <> '' ? '; charset=' . $post_arr['CHARSET'] : '') . $eol
783 . 'Content-Transfer-Encoding: 8bit' . $eol . $eol
784 . $sBody . $eol;
785 }
786
787 foreach ($arFiles as $arFile)
788 {
789 if ($post_arr['CHARSET'] <> '')
790 {
791 $from_charset = $post_arr['MSG_CHARSET'] ?: SITE_CHARSET;
792 $file_name = Encoding::convertEncoding($arFile['ORIGINAL_NAME'], $from_charset, $post_arr['CHARSET']);
793 }
794 else
795 {
796 $file_name = $arFile['ORIGINAL_NAME'];
797 }
798
799 $sBody .=
800 $eol . '--' . $sBoundary . $eol
801 . 'Content-Type: ' . $arFile['CONTENT_TYPE'] . '; name="' . $file_name . '"' . $eol
802 . 'Content-Transfer-Encoding: base64' . $eol
803 . 'Content-Disposition: attachment; filename="' . CMailTools::EncodeHeaderFrom($file_name, $post_arr['CHARSET']) . '"' . $eol . $eol;
804
805 $arTempFile = CFile::MakeFileArray($arFile['ID']);
806 $sBody .= chunk_split(
807 base64_encode(
808 file_get_contents($arTempFile['tmp_name'])
809 ),
810 72,
811 $eol
812 );
813 }
814 }
815
816 if ($bHasAttachments)
817 {
818 $sBody .= $eol . '--' . $sBoundary . '--' . $eol;
819 }
820 else
821 {
822 //plain message without MIME
823 $sHeader =
824 'From: ' . $sFrom . $eol
825 . 'X-Bitrix-Posting: ' . $post_arr['ID'] . $eol
826 . 'MIME-Version: 1.0' . $eol
827 . 'Content-Type: ' . ($post_arr['BODY_TYPE'] == 'html' ? 'text/html' : 'text/plain') . ($post_arr['CHARSET'] <> '' ? '; charset=' . $post_arr['CHARSET'] : '') . $eol
828 . 'Content-Transfer-Encoding: 8bit';
829 }
830
831 $mail_additional_parameters = trim(COption::GetOptionString('subscribe', 'mail_additional_parameters'));
832
833 $context = new Mail\Context();
834 $context->setCategory(Mail\Context::CAT_EXTERNAL);
835 $context->setPriority(Mail\Context::PRIORITY_LOW);
836
837 if ($post_arr['DIRECT_SEND'] == 'Y')
838 {
839 //personal delivery
840 $arEvents = GetModuleEvents('subscribe', 'BeforePostingSendMail', true);
841
842 $rsEmails = $DB->Query($DB->TopSql('
843 SELECT *
844 FROM b_posting_email
845 WHERE POSTING_ID = ' . $ID . " AND STATUS='Y'
846 ", $maxcount));
847
848 while ($arEmail = $rsEmails->Fetch())
849 {
850 //Event part
851 $arFields = [
852 'POSTING_ID' => $ID,
853 'EMAIL' => $arEmail['EMAIL'],
854 'SUBJECT' => $sSubject,
855 'BODY' => $sBody,
856 'HEADER' => $sHeader,
857 'EMAIL_EX' => $arEmail,
858 ];
859 foreach ($arEvents as $arEvent)
860 {
862 }
863 //Sending
864
865 if (is_array($arFields))
866 {
867 $to = CMailTools::EncodeHeaderFrom($arFields['EMAIL'], $post_arr['CHARSET']);
868 $result = bxmail($to, $arFields['SUBJECT'], $arFields['BODY'], $arFields['HEADER'], $mail_additional_parameters, $context);
869 }
870 else
871 {
872 $result = $arFields !== false;
873 }
874
875 //Result check and iteration
876 if ($result)
877 {
878 $DB->Query("UPDATE b_posting_email SET STATUS='N' WHERE ID = " . $arEmail['ID']);
879 }
880 else
881 {
882 $DB->Query("UPDATE b_posting_email SET STATUS='E' WHERE ID = " . $arEmail['ID']);
883 }
884
885 if ($timeout > 0 && microtime(1) - $start_time >= $timeout)
886 {
887 break;
888 }
889
890 self::$current_emails_per_hit++;
891 }
892 }
893 else
894 {
895 //BCC delivery
896 $rsEmails = $DB->Query($DB->TopSql('
897 SELECT *
898 FROM b_posting_email
899 WHERE POSTING_ID = ' . $ID . " AND STATUS='Y'
900 ", COption::GetOptionString('subscribe', 'max_bcc_count')));
901
902 $aStep = [];
903 while ($arEmail = $rsEmails->Fetch())
904 {
905 $aStep[$arEmail['ID']] = $arEmail['EMAIL'];
906 }
907
908 if (count($aStep) > 0)
909 {
910 $BCC = implode(',', $aStep);
911 $sHeaderStep = $sHeader . $eol . 'Bcc: ' . $BCC;
912 $result = bxmail($post_arr['TO_FIELD'], $sSubject, $sBody, $sHeaderStep, $mail_additional_parameters, $context);
913 if ($result)
914 {
915 $DB->Query("UPDATE b_posting_email SET STATUS='N' WHERE ID in (" . implode(', ', array_keys($aStep)) . ')');
916 }
917 else
918 {
919 $DB->Query("UPDATE b_posting_email SET STATUS='E' WHERE ID in (" . implode(', ', array_keys($aStep)) . ')');
920 $this->LAST_ERROR .= GetMessage('class_post_err_mail') . '<br>';
921 }
922 }
923 }
924
925 //set status and delivered and error emails
926 $arStatuses = static::GetEmailStatuses($ID);
927 if (!array_key_exists('Y', $arStatuses))
928 {
929 $STATUS = array_key_exists('E', $arStatuses) ? 'E' : 'S';
930 $DATE = $DB->GetNowFunction();
931 }
932 else
933 {
934 $STATUS = 'P';
935 $DATE = 'null';
936 }
937
939
940 $DB->Query("UPDATE b_posting SET STATUS='" . $STATUS . "', DATE_SENT=" . $DATE . ' WHERE ID=' . $ID);
941
942 return ($STATUS === 'P' ? 'CONTINUE' : true);
943 }
944
945 public static function GetEmailStatuses($ID)
946 {
947 global $DB;
948 $arStatuses = [];
949 $rs = $DB->Query('
950 SELECT STATUS, COUNT(*) CNT
951 FROM b_posting_email
952 WHERE POSTING_ID = ' . intval($ID) . '
953 GROUP BY STATUS
954 ');
955 while ($ar = $rs->Fetch())
956 {
957 $arStatuses[$ar['STATUS']] = $ar['CNT'];
958 }
959 return $arStatuses;
960 }
961
962 public static function GetEmailsByStatus($ID, $STATUS)
963 {
964 global $DB;
965
966 return $DB->Query('
967 SELECT *
968 FROM b_posting_email
969 WHERE POSTING_ID = ' . intval($ID) . "
970 AND STATUS = '" . $DB->ForSQL($STATUS) . "'
971 ORDER BY EMAIL
972 ");
973 }
974
975 public function ChangeStatus($ID, $status)
976 {
977 global $DB;
978
979 $ID = intval($ID);
980 $this->LAST_ERROR = '';
981
982 $strSql = 'SELECT STATUS, VERSION FROM b_posting WHERE ID=' . $ID;
983 $db_result = $DB->Query($strSql);
984 $arResult = $db_result->Fetch();
985 if (!$arResult)
986 {
987 $this->LAST_ERROR = GetMessage('class_post_err_notfound') . '<br>';
988 return false;
989 }
990
991 if ($arResult['STATUS'] == $status)
992 {
993 return true;
994 }
995
996 switch ($arResult['STATUS'] . $status)
997 {
998 case 'DP':
999 //BCC_TO_SEND fill
1000 $post = static::GetByID($ID);
1001 if (!($post_arr = $post->Fetch()))
1002 {
1003 $this->LAST_ERROR .= GetMessage('class_post_err_notfound') . '<br>';
1004 return false;
1005 }
1006
1007 $DB->Query('DELETE from b_posting_email WHERE POSTING_ID = ' . $ID);
1008
1009 $DB->Query("
1010 INSERT INTO b_posting_email (POSTING_ID, STATUS, EMAIL, SUBSCRIPTION_ID, USER_ID)
1011 SELECT DISTINCT
1012 PR.POSTING_ID, 'Y', S.EMAIL, min(S.ID), min(S.USER_ID)
1013 FROM
1014 b_posting_rubric PR
1015 INNER JOIN b_subscription_rubric SR ON SR.LIST_RUBRIC_ID = PR.LIST_RUBRIC_ID
1016 INNER JOIN b_subscription S ON S.ID = SR.SUBSCRIPTION_ID
1017 LEFT JOIN b_user U ON U.ID = S.USER_ID
1018 WHERE
1019 PR.POSTING_ID = " . $ID . "
1020 AND S.CONFIRMED = 'Y'
1021 AND S.ACTIVE = 'Y'
1022 AND (U.ID IS NULL OR U.ACTIVE = 'Y')
1023 " . ($post_arr['SUBSCR_FORMAT'] == '' || $post_arr['SUBSCR_FORMAT'] === 'NOT_REF' ? '' : "AND S.FORMAT = '" . ($post_arr['SUBSCR_FORMAT'] == 'text' ? 'text' : 'html') . "'") . "
1024 " . ($post_arr['EMAIL_FILTER'] == '' || $post_arr['EMAIL_FILTER'] === 'NOT_REF' ? '' : 'AND ' . GetFilterQuery('S.EMAIL', $post_arr['EMAIL_FILTER'], 'Y', ['@', '.', '_'])) . "
1025 GROUP BY
1026 PR.POSTING_ID, S.EMAIL
1027 ");
1028
1029 //send to user groups
1030 $res = $DB->Query('SELECT * FROM b_posting_group WHERE POSTING_ID = ' . $ID . ' AND GROUP_ID = 2');
1031 if ($res->Fetch())
1032 {
1033 $DB->Query('
1034 INSERT INTO b_posting_email (POSTING_ID, STATUS, EMAIL, SUBSCRIPTION_ID, USER_ID)
1035 SELECT
1036 ' . $ID . ", 'Y', U.EMAIL, NULL, MIN(U.ID)
1037 FROM
1038 b_user U
1039 WHERE
1040 U.ACTIVE = 'Y'
1041 and U.EMAIL IS NOT NULL
1042 " . ($post_arr['EMAIL_FILTER'] == '' || $post_arr['EMAIL_FILTER'] === 'NOT_REF' ? '' : 'AND ' . GetFilterQuery('U.EMAIL', $post_arr['EMAIL_FILTER'], 'Y', ['@', '.', '_'])) . '
1043 and U.EMAIL not in (SELECT EMAIL FROM b_posting_email WHERE POSTING_ID = ' . $ID . ')
1044 GROUP BY U.EMAIL
1045 ');
1046 }
1047 else
1048 {
1049 $DB->Query("
1050 INSERT INTO b_posting_email (POSTING_ID, STATUS, EMAIL, SUBSCRIPTION_ID, USER_ID)
1051 SELECT
1052 PG.POSTING_ID, 'Y', U.EMAIL, NULL, MIN(U.ID)
1053 FROM
1054 b_posting_group PG
1055 INNER JOIN b_user_group UG ON UG.GROUP_ID = PG.GROUP_ID
1056 INNER JOIN b_user U ON U.ID = UG.USER_ID
1057 WHERE
1058 PG.POSTING_ID = " . $ID . '
1059 and (UG.DATE_ACTIVE_FROM is null or UG.DATE_ACTIVE_FROM <= ' . $DB->CurrentTimeFunction() . ')
1060 and (UG.DATE_ACTIVE_TO is null or UG.DATE_ACTIVE_TO >= ' . $DB->CurrentTimeFunction() . ")
1061 and U.ACTIVE = 'Y'
1062 and U.EMAIL IS NOT NULL
1063 " . ($post_arr['EMAIL_FILTER'] == '' || $post_arr['EMAIL_FILTER'] === 'NOT_REF' ? '' : 'AND ' . GetFilterQuery('U.EMAIL', $post_arr['EMAIL_FILTER'], 'Y', ['@', '.', '_'])) . '
1064 and U.EMAIL not in (SELECT EMAIL FROM b_posting_email WHERE POSTING_ID = ' . $ID . ')
1065 GROUP BY PG.POSTING_ID, U.EMAIL
1066 ');
1067 }
1068
1069 //from additional emails
1070 $BCC = $post_arr['BCC_FIELD'];
1071 if ($post_arr['DIRECT_SEND'] == 'Y')
1072 {
1073 $BCC .= ($BCC ? ',' : '') . $post_arr['TO_FIELD'];
1074 }
1075 $BCC = str_replace("\r\n", "\n", $BCC);
1076 $BCC = str_replace("\n", ',', $BCC);
1077 $aBcc = explode(',', $BCC);
1078 foreach ($aBcc as $email)
1079 {
1080 $email = trim($email, " \t\n\r");
1081 if ($email !== '')
1082 {
1083 $DB->Query("
1084 INSERT INTO b_posting_email (POSTING_ID, STATUS, EMAIL, SUBSCRIPTION_ID, USER_ID)
1085 SELECT
1086 P.ID, 'Y', '" . ($DB->ForSQL($email)) . "', NULL, NULL
1087 FROM
1088 b_posting P
1089 WHERE
1090 P.ID = " . $ID . "
1091 and '" . ($DB->ForSQL($email)) . "' not in (SELECT EMAIL FROM b_posting_email WHERE POSTING_ID = " . $ID . ')
1092 ');
1093 }
1094 }
1095
1096 $res = $DB->Query('SELECT count(*) CNT from b_posting_email WHERE POSTING_ID = ' . $ID);
1097 $ar = $res->Fetch();
1098
1099 if ($ar['CNT'] > 0)
1100 {
1101 $DB->Query("UPDATE b_posting SET STATUS='" . $status . "', VERSION='2', BCC_TO_SEND=null, ERROR_EMAIL=null, SENT_BCC=null WHERE ID=" . $ID);
1102 }
1103 else
1104 {
1105 $this->LAST_ERROR .= GetMessage('class_post_err_status4');
1106 return false;
1107 }
1108 break;
1109 case 'PW':
1110 case 'WP':
1111 case 'PE':
1112 case 'PS':
1113 $DB->Query("UPDATE b_posting SET STATUS='" . $status . "' WHERE ID=" . $ID);
1114 break;
1115 case 'EW'://This is the way to resend error e-mails
1116 case 'EP':
1117 if ($arResult['VERSION'] == '2')
1118 {
1119 $DB->Query("UPDATE b_posting_email SET STATUS='Y' WHERE POSTING_ID=" . $ID . " AND STATUS='E'");
1120 $DB->Query("UPDATE b_posting SET STATUS='" . $status . "' WHERE ID=" . $ID);
1121 }
1122 else
1123 {
1124 //Send it in old fashion way
1125 $DB->Query("UPDATE b_posting SET STATUS='" . $status . "', BCC_TO_SEND=ERROR_EMAIL, ERROR_EMAIL=null WHERE ID=" . $ID);
1126 }
1127 break;
1128 case 'ED':
1129 case 'SD':
1130 case 'WD':
1131 $DB->Query("UPDATE b_posting SET STATUS='" . $status . "', VERSION='2', SENT_BCC=null, ERROR_EMAIL=null, BCC_TO_SEND=null, DATE_SENT=null WHERE ID=" . $ID);
1132 break;
1133 default:
1134 $this->LAST_ERROR = GetMessage('class_post_err_status2');
1135 return false;
1136 }
1137
1138 return true;
1139 }
1140
1141 public function GetList($aSort=[], $arFilter=[], $arSelect=[], $arNavStartParams=false)
1142 {
1143 global $DB;
1145 $helper = $connection->getSqlHelper();
1146
1147 static $arSelectFields = false;
1148 if (!$arSelectFields)
1149 {
1150 $arSelectFields = [
1151 'STATUS_TITLE' => "case when P.STATUS='S' then '" . $DB->ForSql(GetMessage('POST_STATUS_SENT')) . "'
1152 when P.STATUS='P' then '" . $DB->ForSql(GetMessage('POST_STATUS_PART')) . "'
1153 when P.STATUS='E' then '" . $DB->ForSql(GetMessage('POST_STATUS_ERROR')) . "'
1154 when P.STATUS='W' then '" . $DB->ForSql(GetMessage('POST_STATUS_WAIT')) . "'
1155 else '" . $DB->ForSql(GetMessage('POST_STATUS_DRAFT')) . "' end",
1156 'ID' => 'P.ID',
1157 'STATUS' => 'P.STATUS',
1158 'FROM_FIELD' => 'P.FROM_FIELD',
1159 'TO_FIELD' => 'P.TO_FIELD',
1160 'EMAIL_FILTER' => 'P.EMAIL_FILTER',
1161 'SUBJECT' => 'P.SUBJECT',
1162 'BODY_TYPE' => 'P.BODY_TYPE',
1163 'DIRECT_SEND' => 'P.DIRECT_SEND',
1164 'CHARSET' => 'P.CHARSET',
1165 'MSG_CHARSET' => 'P.MSG_CHARSET',
1166 'SUBSCR_FORMAT' => 'P.SUBSCR_FORMAT',
1167 'TIMESTAMP_X' => $DB->DateToCharFunction('P.TIMESTAMP_X'),
1168 'DATE_SENT' => $DB->DateToCharFunction('P.DATE_SENT'),
1169 ];
1170 }
1171
1172 $this->LAST_ERROR = '';
1173 $arSqlSearch = [];
1174 $strSqlSearch = '';
1175 if (is_array($arFilter))
1176 {
1177 foreach ($arFilter as $key => $val)
1178 {
1179 if (!is_array($val) && ((string)$val === '' || $val === 'NOT_REF'))
1180 {
1181 continue;
1182 }
1183
1184 switch (strtoupper($key))
1185 {
1186 case 'MSG_CHARSET':
1187 $arSqlSearch[] = "P.MSG_CHARSET = '" . $DB->ForSql($val) . "'";
1188 break;
1189 case 'ID':
1190 $arSqlSearch[] = GetFilterQuery('P.ID', $val, 'N');
1191 break;
1192 case 'TIMESTAMP_1':
1193 if ($DB->IsDate($val))
1194 {
1195 $arSqlSearch[] = 'P.TIMESTAMP_X>=' . $DB->CharToDateFunction($val, 'SHORT');
1196 }
1197 else
1198 {
1199 $this->LAST_ERROR .= GetMessage('POST_WRONG_TIMESTAMP_FROM') . '<br>';
1200 }
1201 break;
1202 case 'TIMESTAMP_2':
1203 if ($DB->IsDate($val))
1204 {
1205 $arSqlSearch[] = 'P.TIMESTAMP_X < ' . $helper->addDaysToDateTime(1, $DB->CharToDateFunction($val, 'SHORT'));
1206 }
1207 else
1208 {
1209 $this->LAST_ERROR .= GetMessage('POST_WRONG_TIMESTAMP_TILL') . '<br>';
1210 }
1211 break;
1212 case 'DATE_SENT_1':
1213 if ($DB->IsDate($val))
1214 {
1215 $arSqlSearch[] = 'P.DATE_SENT>=' . $DB->CharToDateFunction($val, 'SHORT');
1216 }
1217 else
1218 {
1219 $this->LAST_ERROR .= GetMessage('POST_WRONG_DATE_SENT_FROM') . '<br>';
1220 }
1221 break;
1222 case 'DATE_SENT_2':
1223 if ($DB->IsDate($val))
1224 {
1225 $arSqlSearch[] = 'P.DATE_SENT < ' . $helper->addDaysToDateTime(1, $DB->CharToDateFunction($val, 'SHORT'));
1226 }
1227 else
1228 {
1229 $this->LAST_ERROR .= GetMessage('POST_WRONG_DATE_SENT_TILL') . '<br>';
1230 }
1231 break;
1232 case 'STATUS':
1233 $arSqlSearch[] = GetFilterQuery(['P.STATUS', $arSelectFields['STATUS_TITLE']], $val, 'Y', [], 'N', 'N');
1234 break;
1235 case 'STATUS_ID':
1236 $arSqlSearch[] = GetFilterQuery('P.STATUS', $val, 'N');
1237 break;
1238 case 'SUBJECT':
1239 $arSqlSearch[] = GetFilterQuery('P.SUBJECT', $val);
1240 break;
1241 case 'FROM':
1242 $arSqlSearch[] = GetFilterQuery('P.FROM_FIELD', $val, 'Y', ['@', '_', '.']);
1243 break;
1244 case 'TO':
1245 $r = GetFilterQuery('PE.EMAIL', $val, 'Y', ['@', '_', '.']);
1246 if ($r <> '')
1247 {
1248 $arSqlSearch[] = "EXISTS (SELECT * FROM b_posting_email PE WHERE PE.POSTING_ID=P.ID AND PE.STATUS='N' AND " . $r . ')';
1249 }
1250 break;
1251 case 'BODY_TYPE':
1252 $arSqlSearch[] = ($val == 'html') ? "P.BODY_TYPE='html'" : "P.BODY_TYPE='text'";
1253 break;
1254 case 'RUB_ID':
1255 if (is_array($val) && count($val) > 0)
1256 {
1257 $rub_id = [];
1258 foreach ($val as $i => $v)
1259 {
1260 $v = intval($v);
1261 if ($v > 0)
1262 {
1263 $rub_id[$v] = $v;
1264 }
1265 }
1266 if (count($rub_id))
1267 {
1268 $arSqlSearch[] = 'EXISTS (SELECT * from b_posting_rubric PR WHERE PR.POSTING_ID = P.ID AND PR.LIST_RUBRIC_ID in (' . implode(', ', $rub_id) . '))';
1269 }
1270 }
1271 break;
1272 case 'BODY':
1273 $arSqlSearch[] = GetFilterQuery('P.BODY', $val);
1274 break;
1275 case 'AUTO_SEND_TIME_1':
1276 if ($DB->IsDate($val, false, false, 'FULL'))
1277 {
1278 $arSqlSearch[] = '(P.AUTO_SEND_TIME is not null and P.AUTO_SEND_TIME>=' . $DB->CharToDateFunction($val, 'FULL') . ' )';
1279 }
1280 elseif ($DB->IsDate($val, false, false, 'SHORT'))
1281 {
1282 $arSqlSearch[] = '(P.AUTO_SEND_TIME is not null and P.AUTO_SEND_TIME>=' . $DB->CharToDateFunction($val, 'SHORT') . ' )';
1283 }
1284 else
1285 {
1286 $this->LAST_ERROR .= GetMessage('POST_WRONG_AUTO_FROM') . '<br>';
1287 }
1288 break;
1289 case 'AUTO_SEND_TIME_2':
1290 if ($DB->IsDate($val, false, false, 'FULL'))
1291 {
1292 $arSqlSearch[] = '(P.AUTO_SEND_TIME is not null and P.AUTO_SEND_TIME<=' . $DB->CharToDateFunction($val, 'FULL') . ' )';
1293 }
1294 elseif ($DB->IsDate($val, false, false, 'SHORT'))
1295 {
1296 $arSqlSearch[] = '(P.AUTO_SEND_TIME is not null and P.AUTO_SEND_TIME<=' . $DB->CharToDateFunction($val, 'SHORT') . ' )';
1297 }
1298 else
1299 {
1300 $this->LAST_ERROR .= GetMessage('POST_WRONG_AUTO_TILL') . '<br>';
1301 }
1302 break;
1303 }
1304 }
1305 }
1306
1307 $arOrder = [];
1308 foreach ($aSort as $key => $ord)
1309 {
1310 $key = mb_strtoupper($key);
1311 $ord = (mb_strtoupper($ord) !== 'ASC' ? 'DESC' : 'ASC');
1312 switch ($key)
1313 {
1314 case 'ID':
1315 $arOrder[$key] = 'P.ID ' . $ord;
1316 break;
1317 case 'TIMESTAMP':
1318 $arOrder[$key] = 'P.TIMESTAMP_X ' . $ord;
1319 break;
1320 case 'SUBJECT':
1321 $arOrder[$key] = 'P.SUBJECT ' . $ord;
1322 break;
1323 case 'BODY_TYPE':
1324 $arOrder[$key] = 'P.BODY_TYPE ' . $ord;
1325 break;
1326 case 'STATUS':
1327 $arOrder[$key] = 'P.STATUS ' . $ord;
1328 break;
1329 case 'DATE_SENT':
1330 $arOrder[$key] = 'P.DATE_SENT ' . $ord;
1331 break;
1332 case 'AUTO_SEND_TIME':
1333 $arOrder[$key] = 'P.AUTO_SEND_TIME ' . $ord;
1334 break;
1335 case 'FROM_FIELD':
1336 $arOrder[$key] = 'P.FROM_FIELD ' . $ord;
1337 break;
1338 case 'TO_FIELD':
1339 $arOrder[$key] = 'P.TO_FIELD ' . $ord;
1340 break;
1341 }
1342 }
1343 if (!$arOrder)
1344 {
1345 $arOrder['ID'] = 'P.ID DESC';
1346 }
1347 $strSqlOrder = ' ORDER BY ' . implode(', ', $arOrder);
1348
1349 if (!is_array($arSelect) || empty($arSelect))
1350 {
1351 $arSelect = array_keys($arSelectFields);
1352 }
1353
1354 $arSqlSelect = [];
1355 foreach ($arSelect as $selectField)
1356 {
1357 if (isset($arSelectFields[$selectField]))
1358 {
1359 $arSqlSelect[$selectField] = $arSelectFields[$selectField] . ' as ' . $selectField;
1360 }
1361 }
1362 if (!$arSqlSelect)
1363 {
1364 $arSqlSelect['ID'] = $arSelectFields['ID'] . ' as ID';
1365 }
1366
1367 $strSqlSearch = GetFilterSqlSearch($arSqlSearch);
1368 $strSql = '
1369 SELECT ' . implode(', ', $arSqlSelect) . '
1370 FROM b_posting P
1371 WHERE
1372 ' . $strSqlSearch . '
1373 ' . $strSqlOrder;
1374
1375 if (is_array($arNavStartParams))
1376 {
1377 $nTopCount = (isset($arNavStartParams['nTopCount']) ? (int)$arNavStartParams['nTopCount'] : 0);
1378 if ($nTopCount > 0)
1379 {
1380 $res = $DB->Query($DB->TopSql(
1381 $strSql,
1382 $nTopCount
1383 ));
1384 }
1385 else
1386 {
1387 $res_cnt = $DB->Query('
1388 SELECT COUNT(P.ID) as C
1389 FROM b_posting P
1390 WHERE
1391 ' . $strSqlSearch . '
1392 ');
1393 $res_cnt = $res_cnt->Fetch();
1394 $res = new CDBResult();
1395 $res->NavQuery($strSql, $res_cnt['C'], $arNavStartParams);
1396 }
1397 }
1398 else
1399 {
1400 $res = $DB->Query($strSql);
1401 }
1402
1403 $res->is_filtered = (IsFiltered($strSqlSearch));
1404
1405 return $res;
1406 }
1407
1408 public static function Lock($ID = 0)
1409 {
1411
1412 return $connection->lock('post_' . $ID);
1413 }
1414
1415 public static function UnLock($ID = 0)
1416 {
1418
1419 return $connection->unlock('post_' . $ID);
1420 }
1421}
$connection
Определения actionsdefinitions.php:38
global $APPLICATION
Определения include.php:80
$arResult
Определения generate_coupon.php:16
static getConnection($name="")
Определения application.php:638
const PRIORITY_LOW
Определения context.php:15
const CAT_EXTERNAL
Определения context.php:12
static getMailEol()
Определения mail.php:856
static GetOptionString($module_id, $name, $def="", $site=false, $bExactSite=false)
Определения option.php:8
Определения dbresult.php:88
Определения mailtools.php:4
static EncodeHeaderFrom($text, $charset)
Определения mailtools.php:51
static EncodeSubject($text, $charset)
Определения mailtools.php:46
ReplaceHrefs($text)
Определения mailtools.php:131
Определения posting.php:8
ChangeStatus($ID, $status)
Определения posting.php:975
static GetFileList($ID, $file_id=false)
Определения posting.php:219
static Delete($ID)
Определения posting.php:82
static $current_emails_per_hit
Определения posting.php:11
static SplitFileName($file_name)
Определения posting.php:126
static GetByID($ID)
Определения posting.php:14
SendMessage($ID, $timeout=0, $maxcount=0, $check_charset=false)
Определения posting.php:572
UpdateGroups($ID, $aGroup)
Определения posting.php:347
SaveFile($ID, $file)
Определения posting.php:160
static GetEmailStatuses($ID)
Определения posting.php:945
static DeleteFile($ID, $file_id=false)
Определения posting.php:114
static Lock($ID=0)
Определения posting.php:1408
static UnLock($ID=0)
Определения posting.php:1415
static GetRubricList($ID)
Определения posting.php:33
UpdateRubrics($ID, $aRubric)
Определения posting.php:320
$LAST_ERROR
Определения posting.php:9
static GetEmailsByStatus($ID, $STATUS)
Определения posting.php:962
GetEmails($post_arr)
Определения posting.php:440
GetList($aSort=[], $arFilter=[], $arSelect=[], $arNavStartParams=false)
Определения posting.php:1141
static OnGroupDelete($group_id)
Определения posting.php:106
static GetGroupList($ID)
Определения posting.php:59
Add($arFields)
Определения posting.php:374
Update($ID, $arFields)
Определения posting.php:400
static AutoSend($ID=false, $limit=false, $site_id=false)
Определения posting.php:513
static GetList($aSort=[], $arFilter=[], $arNavStartParams=false)
Определения subscription.php:9
$start_time
Определения clock_selector.php:9
$arFields
Определения dblapprove.php:5
$res
Определения filter_act.php:7
GetFilterSqlSearch($arSqlSearch=array(), $FilterLogic="FILTER_logic")
Определения filter_tools.php:397
GetFilterQuery($field, $val, $procent="Y", $ex_sep=array(), $clob="N", $div_fields="Y", $clob_upper="N")
Определения filter_tools.php:383
IsFiltered($strSqlSearch)
Определения filter_tools.php:337
$result
Определения get_property_values.php:14
if($ajaxMode) $ID
Определения get_user.php:27
global $DB
Определения cron_frame.php:29
$context
Определения csv_new_setup.php:223
const SITE_CHARSET
Определения include.php:62
const LANG_CHARSET
Определения include.php:65
$status
Определения session.php:10
ExecuteModuleEventEx($arEvent, $arParams=[])
Определения tools.php:5214
GetModuleEvents($MODULE_ID, $MESSAGE_ID, $bReturnArray=false)
Определения tools.php:5177
IncludeModuleLangFile($filepath, $lang=false, $bReturnArray=false)
Определения tools.php:3778
is_set($a, $k=false)
Определения tools.php:2133
GetMessage($name, $aReplace=null)
Определения tools.php:3397
check_email($email, $strict=false, $domainCheck=false)
Определения tools.php:4571
bxmail($to, $subject, $message, $additional_headers="", $additional_parameters="", Main\Mail\Context $context=null)
Определения tools.php:4999
$name
Определения menu_edit.php:35
Определения address.php:8
$user
Определения mysql_to_pgsql.php:33
$email
Определения payment.php:49
$arFiles
Определения options.php:60
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
$ar
Определения options.php:199
if(empty($signedUserToken)) $key
Определения quickway.php:257
$i
Определения factura.php:643
</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
else $a
Определения template.php:137
$post
Определения template.php:8
$arStatuses
Определения options.php:1642
$val
Определения options.php:1793
$site_id
Определения sonet_set_content_view.php:9
const SITE_ID
Определения sonet_set_content_view.php:12
$rs
Определения action.php:82
$arFilter
Определения user_search.php:106