61 private static $oldProductAvailable = array();
62 private static $agentNoticeCreated =
false;
63 private static $agentRepeatedNoticeCreated =
false;
72 return 'b_catalog_subscribe';
84 'data_type' =>
'integer',
86 'autocomplete' =>
true,
89 'data_type' =>
'datetime',
94 'data_type' =>
'datetime',
96 'USER_CONTACT' => array(
97 'data_type' =>
'string',
100 'CONTACT_TYPE' => array(
101 'data_type' =>
'integer',
105 'data_type' =>
'integer',
108 'data_type' =>
'Bitrix\Main\UserTable',
109 'reference' => array(
'=this.USER_ID' =>
'ref.ID'),
112 'data_type' =>
'integer',
115 'data_type' =>
'Bitrix\Catalog\ProductTable',
116 'reference' => array(
'=this.ITEM_ID' =>
'ref.ID'),
118 'IBLOCK_ELEMENT' => array(
119 'data_type' =>
'Bitrix\Iblock\ElementTable',
120 'reference' => array(
'=this.ITEM_ID' =>
'ref.ID'),
122 'NEED_SENDING' => array(
123 'data_type' =>
'boolean',
124 'values' => array(
'N',
'Y'),
125 'default_value' =>
'N',
126 'validation' => array(__CLASS__,
'validateNeedSending'),
129 'data_type' =>
'string',
131 'validation' => array(__CLASS__,
'validateSiteId'),
133 'LANDING_SITE_ID' => array(
134 'data_type' =>
'integer',
147 new Entity\Validator\Length(
null, 1),
159 new Entity\Validator\Length(
null, 2),
171 $userId = (int)$userId;
176 $helper = $connection->getSqlHelper();
177 $connection->queryExecute(
'update '.$helper->quote(static::getTableName()).
' set '
178 .$helper->quote(
'DATE_TO').
' = '.$helper->getCurrentDateTimeFunction().
', '
179 .$helper->quote(
'USER_ID').
' = \'NULL\' where '.$helper->quote(
'USER_ID').
' = '.$userId
193 $productId = (int)$productId;
198 $helper = $connection->getSqlHelper();
199 $connection->queryExecute(
'delete from '.$helper->quote(static::getTableName()).
' where '
200 .$helper->quote(
'ITEM_ID').
' = '.$productId
213 public static function onSaleOrderSaved(
Event $event)
222 $userId = $order->getUserId();
223 $siteId = $order->getSiteId();
224 $basketObject = $order->getBasket();
225 $listProductId = array();
227 foreach ($basketObject->getBasketItems() as $item)
228 $listProductId[] = $item->getProductId();
230 if(!$userId || empty($listProductId))
233 $user = \CUser::getList(
'ID',
'ASC',
234 array(
'ID' => $userId) , array(
'FIELDS' => array(
'EMAIL'))
238 $listSubscribe = static::getList(array(
239 'select' => array(
'ID'),
241 '=USER_CONTACT' => $user[
'EMAIL'],
242 '=SITE_ID' => $siteId,
243 'ITEM_ID' => $listProductId,
246 $listSubscribeId = array();
247 foreach($listSubscribe as $subscribe)
248 $listSubscribeId[] = $subscribe[
'ID'];
250 static::unSubscribe($listSubscribeId);
264 $contactTypes = array();
266 $event =
new Event(
'catalog', static::EVENT_ADD_CONTACT_TYPE, array(&$contactTypes));
269 if(!is_array($contactTypes))
272 $availableFields = array(
'ID',
'NAME',
'RULE',
'HANDLER');
273 foreach($contactTypes as $typeId => $typeData)
275 $currentFields = array_keys($typeData);
276 $divergenceFields = array_diff($availableFields, $currentFields);
277 if(!empty($divergenceFields))
279 unset($contactTypes[$typeId]);
282 if(!is_string($typeData[
'NAME']) || !is_string($typeData[
'RULE']) || !is_callable($typeData[
'HANDLER']))
284 unset($contactTypes[$typeId]);
288 return $contactTypes;
299 $contactTypes[static::CONTACT_TYPE_EMAIL] = array(
300 'ID' => static::CONTACT_TYPE_EMAIL,
303 'HANDLER' =>
function(
Event $event)
306 $eventObject = new \CEvent;
307 foreach($eventData as $userContact => $dataList)
309 foreach($dataList as $data)
311 $eventObject->send($data[
'EVENT_NAME'], $data[
'SITE_ID'], $data);
329 return static::checkOldProductAvailable($productId, $fields);
341 return static::checkOldProductAvailable($productId, $fields);
352 $productId = (int)$productId;
357 $helper = $connection->getSqlHelper();
358 $connection->queryExecute(
'update '.$helper->quote(static::getTableName()).
' set '
359 .$helper->quote(
'NEED_SENDING').
' = \'Y\' where '.$helper->quote(
'ITEM_ID').
' = '.$productId
360 .
' and ('.$helper->quote(
'DATE_TO').
' is null or '.$helper->quote(
'DATE_TO').
' > '
361 .$helper->getCurrentDateTimeFunction().
')'
364 if (!static::$agentNoticeCreated)
367 static::$agentNoticeCreated =
true;
369 '\Bitrix\Catalog\SubscribeTable::sendNotice();',
372 static::AGENT_INTERVAL,
393 $productId = (int)$productId;
394 if ($productId <= 0 || (
string)Option::get(
'catalog',
'subscribe_repeated_notify') !=
'Y')
398 $helper = $connection->getSqlHelper();
399 $connection->queryExecute(
'update '.$helper->quote(static::getTableName()).
' set '
400 .$helper->quote(
'NEED_SENDING').
' = \'Y\' where '.$helper->quote(
'ITEM_ID').
' = '.$productId
401 .
' and ('.$helper->quote(
'DATE_TO').
' is null or '.$helper->quote(
'DATE_TO').
' > '
402 .$helper->getCurrentDateTimeFunction().
')'
405 if (!static::$agentRepeatedNoticeCreated)
408 static::$agentRepeatedNoticeCreated =
true;
410 'Bitrix\Catalog\SubscribeTable::sendRepeatedNotice();',
413 static::AGENT_INTERVAL,
435 return $subscribe ==
'Y' || ($subscribe ==
'D' && (string)Option::get(
'catalog',
'default_subscribe') ==
'Y');
447 if(!$productId || !$available)
452 static::$oldProductAvailable[$productId][
'AVAILABLE'] = $available;
464 if(static::checkLastUpdate())
465 return '\Bitrix\Catalog\SubscribeTable::sendNotice();';
467 list($listSubscribe, $totalCount) = static::getSubscriptionsData();
469 if(empty($listSubscribe))
471 static::$agentNoticeCreated =
false;
475 $anotherStep = (int)$totalCount[
'CNT'] > static::LIMIT_SEND;
477 list($dataSendToNotice, $listNotifiedSubscribeId) =
478 static::prepareDataForNotice($listSubscribe,
'CATALOG_PRODUCT_SUBSCRIBE_NOTIFY');
480 static::startEventNotification($dataSendToNotice);
482 if($listNotifiedSubscribeId)
483 static::setNeedSending($listNotifiedSubscribeId);
487 return '\Bitrix\Catalog\SubscribeTable::sendNotice();';
491 static::$agentNoticeCreated =
false;
503 if(static::checkLastUpdate())
504 return 'Bitrix\Catalog\SubscribeTable::sendRepeatedNotice();';
506 list($listSubscribe, $totalCount) = static::getSubscriptionsData();
508 if(empty($listSubscribe))
510 static::$agentRepeatedNoticeCreated =
false;
514 $anotherStep = (int)$totalCount[
'CNT'] > static::LIMIT_SEND;
516 list($dataSendToNotice, $listNotifiedSubscribeId) =
517 static::prepareDataForNotice($listSubscribe,
'CATALOG_PRODUCT_SUBSCRIBE_NOTIFY_REPEATED');
519 static::startEventNotification($dataSendToNotice);
521 if($listNotifiedSubscribeId)
522 static::setNeedSending($listNotifiedSubscribeId);
526 return 'Bitrix\Catalog\SubscribeTable::sendRepeatedNotice();';
530 static::$agentRepeatedNoticeCreated =
false;
544 $productId = (int)$productId;
545 if ($productId <= 0 || (empty(static::$oldProductAvailable[$productId]))
546 || !static::checkPermissionSubscribe($fields[
'SUBSCRIBE']))
554 static::runAgentToSendNotice($productId);
559 static::runAgentToSendRepeatedNotice($productId);
562 unset(static::$oldProductAvailable[$productId]);
576 'select' => array(
'TIMESTAMP_X'),
577 'order' => array(
'TIMESTAMP_X' =>
'DESC'),
581 if (empty($lastUpdate) || !($lastUpdate[
'TIMESTAMP_X'] instanceof
DateTime))
584 return (time() - $lastUpdate[
'TIMESTAMP_X']->getTimestamp() < static::AGENT_TIME_OUT);
592 '=NEED_SENDING' =>
'Y',
593 '!=PRODUCT.SUBSCRIBE' =>
'N',
596 array(
'=DATE_TO' =>
false),
597 array(
'>DATE_TO' => date($DB->dateFormatToPHP(\CLang::getDateFormat(
'FULL')), time()))
602 $notifyOption = Option::get(
'sale',
'subscribe_prod');
604 if($notifyOption <>
'')
605 $notify = unserialize($notifyOption, [
'allowed_classes' =>
false]);
606 if(is_array($notify))
608 $listSiteId = array();
609 foreach($notify as $siteId => $data)
611 if($data[
'use'] !=
'Y')
612 $listSiteId[] = $siteId;
615 $filter[
'!=SITE_ID'] = $listSiteId;
618 $listSubscribe = static::getList(array(
624 'PRODUCT_NAME' =>
'IBLOCK_ELEMENT.NAME',
625 'DETAIL_PAGE_URL' =>
'IBLOCK_ELEMENT.IBLOCK.DETAIL_PAGE_URL',
626 'IBLOCK_ID' =>
'IBLOCK_ELEMENT.IBLOCK_ID',
627 'TYPE' =>
'PRODUCT.TYPE',
631 'USER_NAME' =>
'USER.NAME',
632 'USER_LAST_NAME' =>
'USER.LAST_NAME',
635 'limit' => static::LIMIT_SEND,
638 $totalCount = static::getList(array(
639 'select' => array(
'CNT'),
644 return array($listSubscribe, $totalCount);
650 $itemIdGroupByIblock = array();
651 foreach($listSubscribe as $key => $subscribeData)
652 $itemIdGroupByIblock[$subscribeData[
'IBLOCK_ID']][$subscribeData[
'ITEM_ID']] = $subscribeData[
'ITEM_ID'];
654 $detailPageUrlGroupByItemId = array();
655 if(!empty($itemIdGroupByIblock))
657 foreach($itemIdGroupByIblock as $iblockId => $listItemId)
659 $queryObject = \CIBlockElement::getList(array(
'ID'=>
'ASC'),
660 array(
'IBLOCK_ID' => $iblockId,
'ID' => $listItemId),
false,
false, array(
'DETAIL_PAGE_URL'));
661 while($result = $queryObject->getNext())
662 $detailPageUrlGroupByItemId[$result[
'ID']] = $result[
'DETAIL_PAGE_URL'];
666 $dataSendToNotice = array();
667 $listNotifiedSubscribeId = array();
668 foreach($listSubscribe as $key => $subscribeData)
670 $pageUrl = self::getPageUrl($subscribeData, $detailPageUrlGroupByItemId);
676 $listNotifiedSubscribeId[] = $subscribeData[
'ID'];
678 $subscribeData[
'EVENT_NAME'] = $eventName;
679 $subscribeData[
'USER_NAME'] = $subscribeData[
'USER_NAME'] ?
680 $subscribeData[
'USER_NAME'] :
Loc::getMessage(
'EMAIL_TEMPLATE_USER_NAME');
681 $subscribeData[
'EMAIL_TO'] = $subscribeData[
'USER_CONTACT'];
682 $subscribeData[
'NAME'] = $subscribeData[
'PRODUCT_NAME'];
683 $subscribeData[
'PAGE_URL'] = $pageUrl;
684 $subscribeData[
'PRODUCT_ID'] = $subscribeData[
'ITEM_ID'];
685 $subscribeData[
'CHECKOUT_URL'] = \CHTTP::urlAddParams($pageUrl, array(
686 'action' =>
'BUY',
'id' => $subscribeData[
'PRODUCT_ID']));
687 $subscribeData[
'CHECKOUT_URL_PARAMETERS'] = \CHTTP::urlAddParams(
'', array(
688 'action' =>
'BUY',
'id' => $subscribeData[
'PRODUCT_ID']));
689 $subscribeData[
'UNSUBSCRIBE_URL'] = \CHTTP::urlAddParams(
690 self::getUnsubscribeUrl($subscribeData),
691 array(
'unSubscribe' =>
'Y',
'subscribeId' => $subscribeData[
'ID'],
692 'userContact' => $subscribeData[
'USER_CONTACT'],
'productId' => $subscribeData[
'PRODUCT_ID']));
693 $subscribeData[
'UNSUBSCRIBE_URL_PARAMETERS'] = \CHTTP::urlAddParams(
'',
694 array(
'unSubscribe' =>
'Y',
'subscribeId' => $subscribeData[
'ID'],
695 'userContact' => $subscribeData[
'USER_CONTACT'],
'productId' => $subscribeData[
'PRODUCT_ID']));
697 $dataSendToNotice[$subscribeData[
'CONTACT_TYPE']][$subscribeData[
'USER_CONTACT']][$key] = $subscribeData;
700 return array($dataSendToNotice, $listNotifiedSubscribeId);
703 private static function getPageUrl(array $subscribeData, array $detailPageUrlGroupByItemId)
707 if (!empty($subscribeData[
'LANDING_SITE_ID']))
709 $pageUrl = Loader::includeModule(
'landing') ?
712 elseif (!empty($detailPageUrlGroupByItemId[$subscribeData[
'ITEM_ID']]))
714 $pageUrl = self::getProtocol().self::getServerName($subscribeData[
'SITE_ID']).
715 $detailPageUrlGroupByItemId[$subscribeData[
'ITEM_ID']];
721 private static function getUnsubscribeUrl(array $subscribeData)
723 if (!empty($subscribeData[
'LANDING_SITE_ID']))
725 $unsubscribeUrl =
'';
726 if (Loader::includeModule(
'landing'))
728 $unsubscribeUrl = \Bitrix\Landing\Syspage::getSpecialPage(
729 $subscribeData[
'LANDING_SITE_ID'],
731 [
'SECTION' =>
'subscribe']
737 $unsubscribeUrl = self::getProtocol().self::getServerName(
738 $subscribeData[
'SITE_ID']).
'/personal/subscribe/';
741 return $unsubscribeUrl;
744 private static function getProtocol()
747 $context = $currentApplication->getContext();
749 if ($protocol = Option::get(
'main',
'mail_link_protocol'))
751 if (mb_strrpos($protocol,
'://') ===
false)
756 if ($context->getServer()->getServerName())
758 $protocol = ($context->getRequest()->isHttps() ?
'https://' :
'http://');
762 $protocol =
'https://';
766 unset($currentApplication);
772 private static function getServerName($siteId)
775 $iterator = \CSite::GetByID($siteId);
776 $site = $iterator->fetch();
779 $serverName = (string)$site[
'SERVER_NAME'];
781 if ($serverName ==
'')
783 $serverName = (defined(
'SITE_SERVER_NAME') && SITE_SERVER_NAME !=
'' ?
784 SITE_SERVER_NAME : (string)Option::get(
'main',
'server_name',
'', $siteId)
786 if ($serverName ==
'')
789 $context = $currentApplication->getContext();
790 $serverName = $context->getServer()->getServerName();
791 unset($currentApplication);
801 $contactTypes = static::getContactTypes();
802 foreach($contactTypes as $typeId => $typeData)
804 if (empty($dataSendToNotice[$typeId]))
809 $eventKey = EventManager::getInstance()
810 ->addEventHandler(
'catalog',
'OnSubscribeSubmit', $typeData[
'HANDLER']);
812 $event =
new Event(
'catalog',
'OnSubscribeSubmit', $dataSendToNotice[$typeId]);
815 EventManager::getInstance()->removeEventHandler(
'catalog',
'OnSubscribeSubmit', $eventKey);
819 private static function setNeedSending(array $listSubscribeId, $needSending =
'N')
821 if(empty($listSubscribeId))
825 $helper = $connection->getSqlHelper();
826 $connection->queryExecute(
'update '.$helper->quote(static::getTableName()).
' set '
827 .$helper->quote(
'NEED_SENDING').
' = \''.$needSending.
'\' where
'
828 .$helper->quote('ID
').' in (
'.implode(',
', $listSubscribeId).')
'
832 private static function unSubscribe(array $listSubscribeId)
834 if(empty($listSubscribeId))
837 $connection = Application::getConnection();
838 $helper = $connection->getSqlHelper();
839 $connection->queryExecute('update
'.$helper->quote(static::getTableName()).' set '
840 .$helper->quote('NEED_SENDING
').' = \
'N\', '.$helper->quote(
'DATE_TO').
' ='
841 .$helper->getCurrentDateTimeFunction().
' where '
842 .$helper->quote(
'ID').
' in ('.implode(
',', $listSubscribeId).
')'
static getConnection($name="")
static loadMessages($file)
static getMessage($code, $replace=null, $language=null)
static getList(array $parameters=array())
static createFromTimestamp($timestamp)