Встала задача - уведомлять владельцев контракта об окончании показа баннера и об окончании контракта. Вот как я реализовал данную задачу.
[spoiler]
Будем считать баннер "умирает", если срок действия его активности по датам подходит к концу. Иначе говоря, поле "Активен по" заполнено. То же самое и для контракта.
Все делают два агента. Первый отвечает за баннеры, второй за контракты.
Теперь как добавлять функции агента:
AgentAdvNotifeBanner(array(-1, 6, 10), "VIEW");
AgentAdvNotifeContract(array(-1, 6, 10), "VIEW");
ставите галочку периодичный, период (да, важно (!), чтобы период стоял ровно сутки - 86400 сек, потому что сравнение по дате идет ровно).
Параметры:
array(-1, 6, 10) - за сколько дней до и после конечной даты оповестить владельца. Данный массив означает за 6 и за 10 до окончания и 1 день после.
"VIEW" - каким пользователям отправится оповещение. Это уровень доступа пользователей к контракту:
просмотр - VIEW
управление - ADD
изменение прав доступа - EDIT
Задача стоял отправить только по тем, кто может "видеть" баннер. Ничего сложного объединить группы. CAdvContract::GetContractPermissions возвращает простой массив. Ну лень было эту мелочь приписывать, честно.
Типы почтовых шаблонов:
ADV_BANNER_NOTIF_AFTER
Уведомление владельцев баннеров об окончательном прекращении показа
#NAME# - имя владельца
#EMAIL# - e-mail владельца
#BANNER_NAME# - название баннера
//это как раз то, что шлется после окончания (-1)
ADV_BANNER_NOTIF_BEFORE
Уведомление владельцев баннеров об окончании показа
#NAME# - имя владельца
#EMAIL# - e-mail владельца
#COUNT_DAY# - количество оставшихся дней
#BANNER_NAME# - название баннера
#DATE_TO# - дата отключения
//это то, что шлется до окончания (6, 10 дней)
Аналогично для контракта.
ADV_CONTRACT_NOTIF_AFTER
Уведомление владельцев контракта об окончательном прекращении
#NAME# - имя владельца
#EMAIL# - e-mail владельца
// тут нам имя баннера не надо, это единственное отличие
ADV_CONTRACT_NOTIF_BEFORE
Уведомление владельцев контракта об окончании действия
#NAME# - имя владельца
#EMAIL# - e-mail владельца
#COUNT_DAY# - количество оставшихся дней
#DATE_TO# - дата отключения
Отвечаю на вопрос почему прямой селект использован. А потому что не признает фильтр классов рекламы дату. Вот так то.
Пользуйтесь наздоровье.
Пара замечаний:
1. ID сайта прописан в коде - "ru", для функций отправки CEvent::Send. Не забудьте сменить, если ID отличается. Сейчас стало модно s1 писать.
2. Применяется лайт-версия дат. То есть без времени. Обращаю внимание, что если вы ставите дату окончания 21.02.2009. То контакт будет активен все 21.02. В базу заносится 21.02.2009 23:59:59. Для времени придется менять логику агента и возрастет нагрузка (имхо), так агенты дергаются раз в сутки всего.
[spoiler]
Будем считать баннер "умирает", если срок действия его активности по датам подходит к концу. Иначе говоря, поле "Активен по" заполнено. То же самое и для контракта.
Все делают два агента. Первый отвечает за баннеры, второй за контракты.
function AgentAdvNotifeBanner($arDays, $accessType) { global $DB; if (CModule::IncludeModule("advertising")): $arCFields = array(); foreach ($arDays as $day) { $arCFields["COUNT_DAY"] = $day; $arCFields["DATE_TO"] = $dateEnd = date($DB->DateFormatToPHP(CLang::GetDateFormat("FULL")), mktime(23, 59, 59, date("n"), date("j"), date("Y")) + $day*86400); $strSql = 'SELECT ID, CONTRACT_ID, NAME ' .'FROM b_adv_banner ' .'WHERE ' .'ACTIVE="Y" AND ' .'DATE_SHOW_TO = '.$DB->CharToDateFunction($dateEnd, "FULL").' '; $rsCID = $DB->Query($strSql, true); while ($arCID = $rsCID->Fetch()) { $arCFields["BANNER_NAME"] = $arCID["NAME"]; $arContractUsers = CAdvContract::GetContractPermissions($arCID["CONTRACT_ID"]); foreach ($arContractUsers[$accessType] as $arUser) { $arCFields["NAME"] = $arUser["USER_NAME"]." ".$arUser["USER_LAST_NAME"]; $arCFields["EMAIL"] = $arUser["USER_EMAIL"]; if ($day < 0) CEvent::Send("ADV_BANNER_NOTIF_AFTER", "ru", $arCFields); else CEvent::Send("ADV_BANNER_NOTIF_BEFORE", "ru", $arCFields); } } } endif; return "AgentAdvNotifeBanner(array(".implode(", ", $arDays)."), \"".$accessType."\");"; } |
function AgentAdvNotifeContract($arDays, $accessType) { global $DB; if (CModule::IncludeModule("advertising")): $arCFields = array(); foreach ($arDays as $day) { $arCFields["COUNT_DAY"] = $day; $arCFields["DATE_TO"] = $dateEnd = date($DB->DateFormatToPHP(CLang::GetDateFormat("FULL")), mktime(23, 59, 59, date("n"), date("j"), date("Y")) + $day*86400); $strSql = 'SELECT ID AS CONTRACT_ID ' .'FROM b_adv_contract ' .'WHERE ' .'ACTIVE="Y" AND ' .'DATE_SHOW_TO = '.$DB->CharToDateFunction($dateEnd, "FULL").' '; $rsCID = $DB->Query($strSql, true); while ($arCID = $rsCID->Fetch()) { $arContractUsers = CAdvContract::GetContractPermissions($arCID["CONTRACT_ID"]); foreach ($arContractUsers[$accessType] as $arUser) { $arCFields["NAME"] = $arUser["USER_NAME"]." ".$arUser["USER_LAST_NAME"]; $arCFields["EMAIL"] = $arUser["USER_EMAIL"]; if ($day < 0) CEvent::Send("ADV_CONTRACT_NOTIF_AFTER", "ru", $arCFields); else CEvent::Send("ADV_CONTRACT_NOTIF_BEFORE", "ru", $arCFields); } } } endif; return "AgentAdvNotifeContract(array(".implode(", ", $arDays)."), \"".$accessType."\");"; } |
Теперь как добавлять функции агента:
AgentAdvNotifeBanner(array(-1, 6, 10), "VIEW");
AgentAdvNotifeContract(array(-1, 6, 10), "VIEW");
ставите галочку периодичный, период (да, важно (!), чтобы период стоял ровно сутки - 86400 сек, потому что сравнение по дате идет ровно).
Параметры:
array(-1, 6, 10) - за сколько дней до и после конечной даты оповестить владельца. Данный массив означает за 6 и за 10 до окончания и 1 день после.
"VIEW" - каким пользователям отправится оповещение. Это уровень доступа пользователей к контракту:
просмотр - VIEW
управление - ADD
изменение прав доступа - EDIT
Задача стоял отправить только по тем, кто может "видеть" баннер. Ничего сложного объединить группы. CAdvContract::GetContractPermissions возвращает простой массив. Ну лень было эту мелочь приписывать, честно.
Типы почтовых шаблонов:
ADV_BANNER_NOTIF_AFTER
Уведомление владельцев баннеров об окончательном прекращении показа
#NAME# - имя владельца
#EMAIL# - e-mail владельца
#BANNER_NAME# - название баннера
//это как раз то, что шлется после окончания (-1)
ADV_BANNER_NOTIF_BEFORE
Уведомление владельцев баннеров об окончании показа
#NAME# - имя владельца
#EMAIL# - e-mail владельца
#COUNT_DAY# - количество оставшихся дней
#BANNER_NAME# - название баннера
#DATE_TO# - дата отключения
//это то, что шлется до окончания (6, 10 дней)
Аналогично для контракта.
ADV_CONTRACT_NOTIF_AFTER
Уведомление владельцев контракта об окончательном прекращении
#NAME# - имя владельца
#EMAIL# - e-mail владельца
// тут нам имя баннера не надо, это единственное отличие
ADV_CONTRACT_NOTIF_BEFORE
Уведомление владельцев контракта об окончании действия
#NAME# - имя владельца
#EMAIL# - e-mail владельца
#COUNT_DAY# - количество оставшихся дней
#DATE_TO# - дата отключения
Отвечаю на вопрос почему прямой селект использован. А потому что не признает фильтр классов рекламы дату. Вот так то.
Пользуйтесь наздоровье.
Пара замечаний:
1. ID сайта прописан в коде - "ru", для функций отправки CEvent::Send. Не забудьте сменить, если ID отличается. Сейчас стало модно s1 писать.
2. Применяется лайт-версия дат. То есть без времени. Обращаю внимание, что если вы ставите дату окончания 21.02.2009. То контакт будет активен все 21.02. В базу заносится 21.02.2009 23:59:59. Для времени придется менять логику агента и возрастет нагрузка (имхо), так агенты дергаются раз в сутки всего.