Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
mailingchain.php
1<?php
8namespace Bitrix\Sender;
9
23
24Loc::loadMessages(__FILE__);
25
32{
33
34 const STATUS_NEW = 'N';
35 const STATUS_SEND = 'S';
36 const STATUS_PAUSE = 'P';
37 const STATUS_WAIT = 'W';
38 const STATUS_PLAN = 'T';
39 const STATUS_END = 'Y';
40 const STATUS_CANCEL = 'C';
41
45 public static function getTableName()
46 {
47 return 'b_sender_mailing_chain';
48 }
49
53 public static function getMap()
54 {
55 return array(
56 'ID' => array(
57 'data_type' => 'integer',
58 'autocomplete' => true,
59 'primary' => true,
60 ),
61 'MAILING_ID' => array(
62 'data_type' => 'integer',
63 'primary' => true,
64 'required' => true,
65 ),
66 'MESSAGE_CODE' => array(
67 'data_type' => 'string',
68 'required' => true,
69 'default_value' => function ()
70 {
71 return Message\iBase::CODE_MAIL;
72 },
73 ),
74 'MESSAGE_ID' => array(
75 'data_type' => 'integer',
76 ),
77 'POSTING_ID' => array(
78 'data_type' => 'integer',
79 ),
80 'PARENT_ID' => array(
81 'data_type' => 'integer',
82 ),
83 'CREATED_BY' => array(
84 'data_type' => 'integer',
85 ),
86 'DATE_INSERT' => array(
87 'data_type' => 'datetime',
88 'default_value' => new Type\DateTime(),
89 ),
90 'STATUS' => array(
91 'data_type' => 'string',
92 'required' => true,
93 'default_value' => static::STATUS_NEW,
94 ),
95 'REITERATE' => array(
96 'data_type' => 'string',
97 'default_value' => 'N',
98 ),
99 'LAST_EXECUTED' => array(
100 'data_type' => 'datetime',
101 ),
102
103 'TITLE' => array(
104 'data_type' => 'string',
105 'title' => Loc::getMessage('SENDER_ENTITY_MAILING_CHAIN_FIELD_TITLE_TITLE1'),
106 ),
107
108 'EMAIL_FROM' => array(
109 'data_type' => 'string',
110 'required' => true,
111 'title' => Loc::getMessage('SENDER_ENTITY_MAILING_CHAIN_FIELD_TITLE_EMAIL_FROM1'),
112 'validation' => array(__CLASS__, 'validateEmailForm'),
113 ),
114 'SUBJECT' => array(
115 'data_type' => 'string',
116 'required' => true,
117 'title' => Loc::getMessage('SENDER_ENTITY_MAILING_CHAIN_FIELD_TITLE_SUBJECT')
118 ),
119 'MESSAGE' => array(
120 'data_type' => 'string',
121 'required' => true,
122 'title' => Loc::getMessage('SENDER_ENTITY_MAILING_CHAIN_FIELD_TITLE_MESSAGE')
123 ),
124
125 'TEMPLATE_TYPE' => array(
126 'data_type' => 'string',
127 ),
128
129 'TEMPLATE_ID' => array(
130 'data_type' => 'string',
131 ),
132
133 'IS_TRIGGER' => array(
134 'data_type' => 'string',
135 'required' => true,
136 'default_value' => 'N',
137 ),
138
139 'TIME_SHIFT' => array(
140 'data_type' => 'integer',
141 'required' => true,
142 'default_value' => 0,
143 ),
144
145 'AUTO_SEND_TIME' => array(
146 'data_type' => 'datetime',
147 ),
148
149 'MONTHS_OF_YEAR' => array(
150 'data_type' => 'string',
151 ),
152 'DAYS_OF_MONTH' => array(
153 'data_type' => 'string',
154 ),
155 'DAYS_OF_WEEK' => array(
156 'data_type' => 'string',
157 ),
158 'TIMES_OF_DAY' => array(
159 'data_type' => 'string',
160 ),
161
162 'PRIORITY' => array(
163 'data_type' => 'string',
164 ),
165
166 'LINK_PARAMS' => array(
167 'data_type' => 'string',
168 ),
169
170 'MAILING' => array(
171 'data_type' => 'Bitrix\Sender\MailingTable',
172 'reference' => array('=this.MAILING_ID' => 'ref.ID'),
173 ),
174 'CURRENT_POSTING' => array(
175 'data_type' => 'Bitrix\Sender\PostingTable',
176 'reference' => array('=this.POSTING_ID' => 'ref.ID'),
177 ),
178 'POSTING' => array(
179 'data_type' => 'Bitrix\Sender\PostingTable',
180 'reference' => array('=this.ID' => 'ref.MAILING_CHAIN_ID'),
181 ),
182 'ATTACHMENT' => array(
183 'data_type' => 'Bitrix\Sender\MailingAttachmentTable',
184 'reference' => array('=this.ID' => 'ref.CHAIN_ID'),
185 ),
186 'CREATED_BY_USER' => array(
187 'data_type' => 'Bitrix\Main\UserTable',
188 'reference' => array('=this.CREATED_BY' => 'ref.ID'),
189 ),
190 'WAITING_RECIPIENT' => array(
191 'data_type' => 'boolean',
192 'default_value' => 'N',
193 'values' => array('N', 'Y')
194 ),
195 );
196 }
197
203 public static function validateEmailForm()
204 {
205 return array(
206 new Entity\Validator\Length(null, 50),
207 array(__CLASS__, 'checkEmail')
208 );
209 }
210
215 public static function checkEmail($value)
216 {
217 if(empty($value) || check_email($value))
218 return true;
219 else
220 return Loc::getMessage('SENDER_ENTITY_MAILING_CHAIN_VALID_EMAIL_FROM');
221 }
222
232 public static function copy(?int $id): ?int
233 {
234 $dataDb = static::getList(array('filter' => array('ID' => $id)));
235 if (!$data = $dataDb->fetch())
236 {
237 return null;
238 }
239
240 $copiedDb = static::add(array(
241 'MAILING_ID' => $data['MAILING_ID'],
242 'EMAIL_FROM' => $data['EMAIL_FROM'],
243 'TITLE' => $data['TITLE'],
244 'SUBJECT' => $data['SUBJECT'],
245 'MESSAGE' => $data['MESSAGE'],
246 'TEMPLATE_TYPE' => $data['TEMPLATE_TYPE'],
247 'TEMPLATE_ID' => $data['TEMPLATE_ID'],
248 'PRIORITY' => $data['PRIORITY'],
249 'LINK_PARAMS' => $data['LINK_PARAMS'],
250 ));
251
252 if (!$copiedDb->isSuccess())
253 {
254 return null;
255 }
256 $copiedId = $copiedDb->getId();
257
258 $attachmentDb = MailingAttachmentTable::getList(array(
259 'filter' => array('=CHAIN_ID' => $id)
260 ));
261 while($attachment = $attachmentDb->fetch())
262 {
263 $copiedFileId = \CFile::copyFile($attachment['FILE_ID']);
264 if (!$copiedFileId)
265 {
266 continue;
267 }
268
269 MailingAttachmentTable::add(array(
270 'CHAIN_ID' => $copiedId,
271 'FILE_ID' => $copiedFileId
272 ));
273 }
274
275 return $copiedId;
276 }
277
285 public static function initPosting(?int $mailingChainId): ?int
286 {
287 $postingId = null;
288 $chainPrimary = array('ID' => $mailingChainId);
289 $mailingChain = static::getRowById($chainPrimary);
290
291 if(!$mailingChain)
292 {
293 return null;
294 }
295
296 $needAddPosting = true;
297 if(!empty($mailingChain['POSTING_ID']))
298 {
299 $posting = PostingTable::getRowById(array('ID' => $mailingChain['POSTING_ID']));
300 if($posting)
301 {
302 if($posting['STATUS'] == PostingTable::STATUS_NEW)
303 {
304 $postingId = $mailingChain['POSTING_ID'];
305 $needAddPosting = false;
306 }
307 /*
308 elseif($arMailingChain['IS_TRIGGER'] == 'Y')
309 {
310 $postingId = $arMailingChain['POSTING_ID'];
311 $needAddPosting = false;
312 }
313 */
314 }
315 }
316
317 if($needAddPosting)
318 {
319 $consentSupported = false;
320 try
321 {
322 $consentSupported = Transport\Adapter::create($mailingChain['MESSAGE_CODE'])->isConsentSupported();
323 }
324 catch (ArgumentException $e)
325 {
326 }
327
328 $postingAddDb = PostingTable::add(array(
329 'MAILING_ID' => $mailingChain['MAILING_ID'],
330 'MAILING_CHAIN_ID' => $mailingChain['ID'],
331 'CONSENT_SUPPORT' => $consentSupported
332 ));
333 if ($postingAddDb->isSuccess())
334 {
335 $postingId = $postingAddDb->getId();
336 Model\LetterTable::update($mailingChainId, ['POSTING_ID' => $postingId]);
337 }
338 }
339
340 if($postingId && $mailingChain['IS_TRIGGER'] != 'Y')
341 {
342 if(!PostingTable::initGroupRecipients($postingId, true))
343 {
344 Model\LetterTable::update($mailingChainId, ['WAITING_RECIPIENT' => 'Y']);
345 }
346 }
347
348 return $postingId;
349 }
350
351
356 public static function onAfterAdd(Entity\Event $event)
357 {
358 $result = new Entity\EventResult;
359 $data = $event->getParameters();
360
361 /*
362 // Commented because letter-segments is not set yet.
363 if(!isset($data['fields']['IS_TRIGGER']) || $data['fields']['IS_TRIGGER'] != 'Y')
364 {
365 static::initPosting($data['primary']['ID']);
366 }
367 */
368
369 if(array_key_exists('STATUS', $data['fields']) || array_key_exists('AUTO_SEND_TIME', $data['fields']))
370 {
371 Runtime\Job::actualizeByLetterId($data['primary']['ID']);
372 }
373
374 if(isset($data['fields']['PARENT_ID']))
375 {
376 Trigger\Manager::actualizeHandlerForChild();
377 }
378
379 if(isset($data['fields']['IS_TRIGGER']) && $data['fields']['IS_TRIGGER'] == 'Y')
380 {
381 MailingTable::updateChainTrigger($data['fields']['CAMPAIGN_ID']);
382 }
383
384 return $result;
385 }
386
391 public static function onBeforeUpdate(Entity\Event $event)
392 {
393 $result = new Entity\EventResult;
394
395 Integration\EventHandler::onBeforeUpdateLetterTable($event, $result);
396
397 return $result;
398 }
399
404 public static function onAfterUpdate(Entity\Event $event)
405 {
406 $result = new Entity\EventResult;
407 $data = $event->getParameters();
408 if(array_key_exists('STATUS', $data['fields']) || array_key_exists('AUTO_SEND_TIME', $data['fields']))
409 {
410 if(array_key_exists('STATUS', $data['fields']) && $data['fields']['STATUS'] == static::STATUS_NEW)
411 {
412 static::initPosting($data['primary']['ID']);
413 }
414
415 Runtime\Job::actualizeByLetterId($data['primary']['ID']);
416 }
417
418 if(isset($data['fields']['PARENT_ID']))
419 {
420 Trigger\Manager::actualizeHandlerForChild();
421 }
422
423 return $result;
424 }
425
430 public static function onDelete(Entity\Event $event)
431 {
432 $result = new Entity\EventResult;
433 $data = $event->getParameters();
434
435 $deleteIdList = array();
436 if(!empty($data['primary']))
437 {
438 $itemDb = static::getList(array(
439 'select' => array('ID'),
440 'filter' => $data['primary']
441 ));
442 while($item = $itemDb->fetch())
443 {
444 $deleteIdList[] = $item['ID'];
445 }
446 }
447
448 foreach($deleteIdList as $chainId)
449 {
450 MailingAttachmentTable::deleteList(array('CHAIN_ID' => $chainId));
451 MailingTriggerTable::deleteList(array('MAILING_CHAIN_ID' => $chainId));
452 PostingTable::deleteList(array('MAILING_CHAIN_ID' => $chainId));
453 }
454
455 return $result;
456 }
457
465 public static function deleteList(array $filter)
466 {
467 $entity = static::getEntity();
468 $connection = $entity->getConnection();
469
470 \CTimeZone::disable();
471 $sql = sprintf(
472 'DELETE FROM %s WHERE %s',
473 $connection->getSqlHelper()->quote($entity->getDbTableName()),
474 Query::buildFilterSql($entity, $filter)
475 );
476 $res = $connection->query($sql);
477 \CTimeZone::enable();
478
479 return $res;
480 }
485 public static function onAfterDelete(Entity\Event $event)
486 {
487 Trigger\Manager::actualizeHandlerForChild();
488 }
489
495 public static function isReadyToSend($id)
496 {
497 $mailingChainDb = static::getList(array(
498 'select' => array('ID'),
499 'filter' => array(
500 '=ID' => $id,
501 '=MAILING.ACTIVE' => 'Y',
502 '=STATUS' => array(static::STATUS_NEW, static::STATUS_PAUSE),
503 ),
504 ));
505 $mailingChain = $mailingChainDb->fetch();
506
507 return !empty($mailingChain);
508 }
509
515 public static function isManualSentPartly($id)
516 {
517 $mailingChainDb = static::getList(array(
518 'select' => array('ID'),
519 'filter' => array(
520 '=ID' => $id,
521 '=MAILING.ACTIVE' => 'Y',
522 '=AUTO_SEND_TIME' => null,
523 '!REITERATE' => 'Y',
524 '=STATUS' => array(static::STATUS_SEND),
525 ),
526 ));
527 $mailingChain = $mailingChainDb->fetch();
528
529 return !empty($mailingChain);
530 }
531
539 public static function isAutoSend($id)
540 {
541 $mailingChainDb = static::getList(array(
542 'select' => array('ID'),
543 'filter' => array(
544 '=ID' => $id,
545 '!AUTO_SEND_TIME' => null,
546 '!REITERATE' => 'Y',
547 ),
548 ));
549 $mailingChain = $mailingChainDb->fetch();
550
551 return !empty($mailingChain);
552 }
553
560 public static function canReSendErrorRecipients($id)
561 {
562 $mailingChainDb = static::getList(array(
563 'select' => array('POSTING_ID'),
564 'filter' => array(
565 '=ID' => $id,
566 '!REITERATE' => 'Y',
567 '!POSTING_ID' => null,
568 '=STATUS' => static::STATUS_END,
569 ),
570 ));
571 if($mailingChain = $mailingChainDb->fetch())
572 {
573 $errorRecipientDb = PostingRecipientTable::getList(array(
574 'select' => array('ID'),
575 'filter' => array(
576 '=POSTING_ID' => $mailingChain['POSTING_ID'],
578 ),
579 'limit' => 1
580 ));
581 if($errorRecipientDb->fetch())
582 {
583 return true;
584 }
585 }
586
587 return false;
588 }
589
596 public static function prepareReSendErrorRecipients($id)
597 {
598 if(!static::canReSendErrorRecipients($id))
599 {
600 return;
601 }
602
603 $mailingChain = static::getRowById(array('ID' => $id));
604 $updateSql = 'UPDATE ' . PostingRecipientTable::getTableName() .
605 " SET STATUS='" . PostingRecipientTable::SEND_RESULT_NONE . "'" .
606 " WHERE POSTING_ID=" . intval($mailingChain['POSTING_ID']) .
607 " AND STATUS='" . PostingRecipientTable::SEND_RESULT_ERROR . "'";
608 Application::getConnection()->query($updateSql);
609 Model\PostingTable::update($mailingChain['POSTING_ID'], ['STATUS' => PostingTable::STATUS_PART]);
610 static::update(array('ID' => $id), array('STATUS' => static::STATUS_SEND));
611 }
612
616 public static function setStatusNew($mailingId)
617 {
618 static::update(array('MAILING_ID' => $mailingId), array('STATUS' => static::STATUS_NEW));
619 }
620
624 public static function getStatusList()
625 {
626 return array(
627 self::STATUS_NEW => Loc::getMessage('SENDER_CHAIN_STATUS_N'),
628 self::STATUS_SEND => Loc::getMessage('SENDER_CHAIN_STATUS_S'),
629 self::STATUS_PAUSE => Loc::getMessage('SENDER_CHAIN_STATUS_P'),
630 self::STATUS_WAIT => Loc::getMessage('SENDER_CHAIN_STATUS_W'),
631 self::STATUS_END => Loc::getMessage('SENDER_CHAIN_STATUS_Y'),
632 );
633 }
634
639 public static function getDefaultEmailFromList()
640 {
641 $addressFromList = array();
642 $siteEmailDb = SiteTable::getList(array('select'=>array('EMAIL')));
643 while($siteEmail = $siteEmailDb->fetch())
644 {
645 $addressFromList[] = $siteEmail['EMAIL'];
646 }
647
648 try
649 {
650 $mainEmail = Option::get('main', 'email_from');
651 if (!empty($mainEmail))
652 $addressFromList[] = $mainEmail;
653
654 $saleEmail = Option::get('sale', 'order_email');
655 if(!empty($saleEmail))
656 $addressFromList[] = $saleEmail;
657
658 $addressFromList = array_unique($addressFromList);
659 trimArr($addressFromList, true);
660
661 }
662 catch(\Exception $e)
663 {
664
665 }
666
667 return $addressFromList;
668 }
669
673 public static function getEmailFromList()
674 {
675 $addressFromList = static::getDefaultEmailFromList();
676 $email = Option::get('sender', 'address_from');
677 if(!empty($email))
678 {
679 $arEmail = explode(',', $email);
680 $addressFromList = array_merge($arEmail, $addressFromList);
681 $addressFromList = array_unique($addressFromList);
682 trimArr($addressFromList, true);
683 }
684
685 return $addressFromList;
686 }
687
691 public static function setEmailFromToList($email)
692 {
693 $emailList = Option::get('sender', 'address_from');
694 if(!empty($email))
695 {
696 $addressFromList = explode(',', $emailList);
697 $addressFromList = array_merge(array($email), $addressFromList);
698 $addressFromList = array_unique($addressFromList);
699 trimArr($addressFromList, true);
700 Option::set('sender', 'address_from', implode(',', $addressFromList));
701 }
702 }
703
707 public static function getEmailToMeList()
708 {
709 $addressToList = array();
710 $email = Option::get('sender', 'address_send_to_me');
711 if(!empty($email))
712 {
713 $addressToList = explode(',', $email);
714 $addressToList = array_unique($addressToList);
715 \TrimArr($addressToList, true);
716 }
717
718 return $addressToList;
719 }
720
724 public static function setEmailToMeList($email)
725 {
726 $emailList = Option::get('sender', 'address_send_to_me');
727 if(!empty($email))
728 {
729 $addressToList = explode(',', $emailList);
730 $addressToList = array_merge(array($email), $addressToList);
731 $addressToList = array_unique($addressToList);
732 trimArr($addressToList, true);
733 Option::set('sender', 'address_send_to_me', implode(',', $addressToList));
734 }
735 }
736
743 public static function onPresetTemplateList($templateType = null, $templateId = null)
744 {
745 $resultList = array();
746
747 if($templateType && $templateType !== 'MAILING')
748 {
749 return $resultList;
750 }
751
752 $filter = array();
753 if($templateId)
754 {
755 $filter['ID'] = $templateId;
756 }
757 $templateDb = static::getList(array(
758 'select' => array('ID', 'SUBJECT', 'MESSAGE'),
759 'filter' => $filter,
760 'order' => array('DATE_INSERT' => 'DESC'),
761 'limit' => 15
762 ));
763 while($template = $templateDb->fetch())
764 {
765 $resultList[] = array(
766 'TYPE' => 'MAILING',
767 'ID' => $template['ID'],
768 'NAME' => $template['SUBJECT'],
769 'ICON' => '',
770 'HTML' => $template['MESSAGE']
771 );
772 }
773
774 return $resultList;
775 }
776
784 public static function getMessageById($id)
785 {
786 $letter = new Letter($id);
787 return $letter->getMessage()->getConfiguration()->get('BODY');
788 }
789}
790
808{
809
813 public static function getTableName()
814 {
815 return 'b_sender_mailing_attachment';
816 }
817
821 public static function getMap()
822 {
823 return array(
824 'CHAIN_ID' => array(
825 'data_type' => 'integer',
826 'primary' => true,
827 ),
828 'FILE_ID' => array(
829 'data_type' => 'integer',
830 'primary' => true,
831 ),
832 );
833 }
834
842 public static function deleteList(array $filter)
843 {
844 $entity = static::getEntity();
845 $connection = $entity->getConnection();
846
847 \CTimeZone::disable();
848 $sql = sprintf(
849 'DELETE FROM %s WHERE %s',
850 $connection->getSqlHelper()->quote($entity->getDbTableName()),
851 Query::buildFilterSql($entity, $filter)
852 );
853 $res = $connection->query($sql);
854 \CTimeZone::enable();
855
856 return $res;
857 }
858}
static getConnection($name="")
static loadMessages($file)
Definition loc.php:64
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29
static onDelete(Entity\Event $event)
static onBeforeUpdate(Entity\Event $event)
static initPosting(?int $mailingChainId)
static deleteList(array $filter)
static onAfterAdd(Entity\Event $event)
static onPresetTemplateList($templateType=null, $templateId=null)
static onAfterUpdate(Entity\Event $event)
static onAfterDelete(Entity\Event $event)
static deleteList(array $filter)
Definition posting.php:338
static initGroupRecipients($postingId, $checkDuplicate=true)
Definition posting.php:239