Your IP : 216.73.216.240
<?php
use AcyMailing\Classes\FollowupClass;
use AcyMailing\Controllers\CampaignsController;
use AcyMailing\Helpers\AutomationHelper;
use AcyMailing\Libraries\acymPlugin;
use AcyMailing\Classes\CampaignClass;
use AcyMailing\Classes\FieldClass;
class plgAcymBirthday extends acymPlugin
{
const MAILTYPE = 'birthday';
const FOLLOWTRIGGER = 'birthday';
protected $dataSources = [];
public function onAcymDefineUserStatusCheckTriggers(&$triggers)
{
$triggers[] = 'on_birthday';
}
public function onAcymDeclareTriggers(&$triggers, &$defaultValues)
{
$dataSources = [];
acym_trigger('onAcymDeclareDataSourcesBirthdayTrigger', [&$dataSources]);
$this->dataSources = $dataSources;
$sourceOptions = [];
$defaultSource = empty($defaultValues['on_birthday']['source']) ? 'acymailing' : $defaultValues['on_birthday']['source'];
$defaultField = empty($defaultValues['on_birthday']['field']) ? '' : $defaultValues['on_birthday']['field'];
$defaultDayBefore = empty($defaultValues['on_birthday']['day_before']) ? '0' : $defaultValues['on_birthday']['day_before'];
$defaultBeforeHour = empty($defaultValues['on_birthday']['hour']) ? '12' : $defaultValues['on_birthday']['hour'];
$defaultBeforeMinutes = empty($defaultValues['on_birthday']['minutes']) ? '00' : $defaultValues['on_birthday']['minutes'];
foreach ($this->dataSources as $key => $oneSource) {
$sourceOptions[] = acym_selectOption($key, $oneSource['source_name']);
}
$triggers['user']['on_birthday'] = new stdClass();
$triggers['user']['on_birthday']->name = acym_translation('ACYM_ON_USER_BIRTHDAY');
$hour = [];
$minutes = [];
$i = 0;
while ($i <= 59) {
$j = $i < 10 ? '0'.$i : $i;
if ($i <= 23) {
$hour[$j] = $j;
}
$minutes[$j] = $j;
$i++;
}
$option = '<div class="grid-x grid-margin-x margin-y">
<div class="cell grid-x">
<div class="cell medium-shrink" style="display: none">
'.acym_translation('ACYM_SOURCE').' : ';
$option .= acym_select($sourceOptions, '[triggers][user][on_birthday][source]', $defaultSource, 'data-class="intext_select acym__select"');
$option .= '
</div>
</div>';
if (empty($this->dataSources[$defaultSource]['fields']) && !empty($this->dataSources[$defaultSource]['no_fields_error_message'])) {
$option .= '<div class="cell grid-x"><span class="cell small-1 vertical-align-middle"><i class="acymicon-exclamation-circle acym__color__orange"></i></span><span class="cell small-11"><b>'.acym_translation(
$this->dataSources[$defaultSource]['no_fields_error_message']
).'</b></span></div>';
} else {
$option .= '<div class="cell grid-x">
<div class="cell medium-shrink">
'.acym_translation('ACYM_FIELD').' : ';
$fieldsOption = $this->getFieldsForTable('acymailing');
$option .= acym_select(
$fieldsOption,
'[triggers][user][on_birthday][field]',
$defaultField,
'data-class="intext_select acym__select"'
);
$hourSelector = acym_select(
$hour,
'[triggers][user][on_birthday][hour]',
$defaultBeforeHour,
'data-class="intext_select acym__select"'
);
$minuteSelector = acym_select(
$minutes,
'[triggers][user][on_birthday][minutes]',
$defaultBeforeMinutes,
'data-class="intext_select acym__select"'
);
$option .= '
</div>
</div>
<div class="cell grid-x">
<div class="cell auto word-break acym__automation__trigger__action__birthday">
'.acym_translationSprintf(
'ACYM_TRIGGER_EVENT_BEFORE_BIRTHDAY',
'<input type="number" name="[triggers][user][on_birthday][day_before]" class="intext_input" min="0" value="'.acym_escape($defaultDayBefore).'">',
$hourSelector,
$minuteSelector
).'
</div>
</div>
<span class="cell margin-top-1 acym__color__dark-gray word-break">'.acym_translation('ACYM_BIRTHDAY_TRIGGER_INFO').'</span>';
}
$option .= '</div>';
$triggers['user']['on_birthday']->option = $option;
}
public function onAcymExecuteTrigger(&$step, &$execute, &$data)
{
if (!empty($step->next_execution) && $step->next_execution > $data['time']) return;
$triggers = $step->triggers;
if (empty($triggers['on_birthday'])) return;
$sourceName = $triggers['on_birthday']['source'];
$fieldId = $triggers['on_birthday']['field'];
$dayBefore = $triggers['on_birthday']['day_before'];
$hour = $triggers['on_birthday']['hour'];
$minutes = $triggers['on_birthday']['minutes'];
$dateNowWithTimeZone = acym_date('now', 'Y-m-d h:i:s');
$now = new DateTime($dateNowWithTimeZone);
$triggerDate = new DateTime($dateNowWithTimeZone);
$triggerDate->setTime($hour, $minutes);
if (!empty($now->date) && !empty($triggerDate->date) && $now->date < $triggerDate->date) {
$step->next_execution = acym_getTime('today '.$hour.':'.$minutes);
return;
} else {
$step->next_execution = acym_getTime('tomorrow '.$hour.':'.$minutes);
}
$dataSources = [];
acym_trigger('onAcymDeclareDataSourcesBirthdayTrigger', [&$dataSources]);
$this->dataSources = $dataSources;
$format = '';
$query = '';
if (empty($this->dataSources[$sourceName]['fields'])) return;
foreach ($this->dataSources[$sourceName]['fields'] as $oneField) {
if ($oneField['id'] === $fieldId) {
$format = $oneField['format'];
$query = $oneField['query'];
}
}
if (empty($format) || empty($query)) return;
$users = acym_loadObjectList($query);
if (empty($users)) return;
foreach ($users as $oneUser) {
if (empty($oneUser->date)) continue;
$userBirthday = DateTime::createFromFormat($format, $oneUser->date);
if (empty($userBirthday)) continue;
$userBirthday->sub(new DateInterval('P'.$dayBefore.'D'));
if ($now->format('m-d') === $userBirthday->format('m-d')) {
$execute = true;
$data['userIds'][] = $oneUser->user_id;
}
}
}
protected function getFieldsForTable($dataSource)
{
if (empty($this->dataSources[$dataSource]['fields'])) return [];
$fieldsOption = [];
foreach ($this->dataSources[$dataSource]['fields'] as $oneField) {
$fieldsOption[] = acym_selectOption($oneField['id'], $oneField['name']);
}
return $fieldsOption;
}
public function onAcymDeclareSummary_triggers(&$automation)
{
if (!empty($automation->triggers['on_birthday'])) {
$dataSources = [];
acym_trigger('onAcymDeclareDataSourcesBirthdayTrigger', [&$dataSources]);
if (empty($dataSources[$automation->triggers['on_birthday']['source']]['fields']) && !empty($dataSources[$automation->triggers['on_birthday']['source']]['no_fields_error_message'])) {
$automation->triggers['on_birthday'] = acym_translation($dataSources[$automation->triggers['on_birthday']['source']]['no_fields_error_message']);
return;
}
$fieldToDsiplay = [];
foreach ($dataSources[$automation->triggers['on_birthday']['source']]['fields'] as $field) {
if ($field['id'] != $automation->triggers['on_birthday']['field']) continue;
$fieldToDsiplay = $field;
}
$date = empty($automation->triggers['on_birthday']['day_before'])
? acym_translation('ACYM_ON_USER_BIRTHDAY')
: acym_translationSprintf(
'ACYM_X_DAYS_BEFORE_BIRTHDAY',
$automation->triggers['on_birthday']['day_before']
);
$time = acym_translationSprintf('ACYM_AT_DATE_TIME', $automation->triggers['on_birthday']['hour'], $automation->triggers['on_birthday']['minutes']);
$end = acym_translationSprintf('ACYM_FOR_THE_X_FIELD_X', $dataSources[$automation->triggers['on_birthday']['source']]['source_name'], $fieldToDsiplay['name']);
$automation->triggers['on_birthday'] = $date.' '.$time.' '.$end;
}
}
public function getNewEmailsTypeBlock(&$extraBlocks)
{
if (acym_isAdmin()) {
$birthdayMailLink = acym_completeLink('campaigns&task=edit&step=chooseTemplate&campaign_type='.self::MAILTYPE);
} else {
$birthdayMailLink = acym_frontendLink('frontcampaigns&task=edit&step=chooseTemplate&campaign_type='.self::MAILTYPE);
}
$extraBlocks[] = [
'name' => acym_translation('ACYM_BIRTHDAY'),
'description' => acym_translation('ACYM_BIRTHDAY_MAIL_DESC'),
'icon' => 'acymicon-calendar',
'link' => $birthdayMailLink,
'level' => 2,
];
}
public function getCampaignTypes(&$types)
{
$types[self::MAILTYPE] = self::MAILTYPE;
}
public function getCampaignSpecificSendSettings($type, $sendingParams, &$specificSettings)
{
if ($type != self::MAILTYPE) return;
$defaultNumber = 1;
if (!empty($sendingParams) && isset($sendingParams[self::MAILTYPE.'_number'])) {
$defaultNumber = $sendingParams[self::MAILTYPE.'_number'];
}
$inputTime = '<input type="number" min="0" stp="1" name="acym_birthday_time_number" class="intext_input" value="'.$defaultNumber.'">';
$timeSelectOptions = [
'days' => acym_translation('ACYM_DAYS'),
'weeks' => acym_translation('ACYM_WEEKS'),
'months' => acym_translation('ACYM_MONTHS'),
];
$selectedtType = 'days';
if (!empty($sendingParams) && isset($sendingParams[self::MAILTYPE.'_type'])) {
$selectedtType = $sendingParams[self::MAILTYPE.'_type'];
}
$timeSelect = '<div class="cell medium-2 margin-left-1 margin-right-1">';
$timeSelect .= acym_select($timeSelectOptions, 'acym_birthday_time_frame', $selectedtType, 'class="acym__select"');
$timeSelect .= '</div>';
$timeRelativeOptions = [
'before' => acym_translation('ACYM_BEFORE'),
'after' => acym_translation('ACYM_AFTER'),
];
$selectedRelative = 'before';
if (!empty($sendingParams) && isset($sendingParams[self::MAILTYPE.'_relative'])) {
$selectedRelative = $sendingParams[self::MAILTYPE.'_relative'];
}
$inputRelative = '<div class="cell medium-2 margin-left-1 margin-right-1">';
$inputRelative .= acym_select($timeRelativeOptions, 'acym_birthday_relative', $selectedRelative, 'class="acym__select"');
$inputRelative .= '</div>';
$whenSettings = '<div class="cell grid-x acym_vcenter">';
$whenSettings .= acym_translationSprintf('ACYM_SEND_IT_BEFORE_USER_BIRTHDAY', $inputTime, $timeSelect, $inputRelative);
$whenSettings .= '</div>';
$fieldClass = new FieldClass();
$dateFields = $fieldClass->getFieldsByType(['date']);
$pluginFields = [];
foreach ($dateFields as $oneField) {
$pluginFields[$oneField->id] = acym_translation($oneField->name);
}
$availablePlugins = [
get_class($this) => 'AcyMailing',
];
acym_trigger('onAcymGetPluginField', [&$availablePlugins]);
$onlyAcymailing = count($availablePlugins) === 1;
$selectedPlugin = '';
$availableFields = [
'' => acym_translation('ACYM_SELECT_FIELD'),
];
if (!empty($sendingParams) && !empty($sendingParams[self::MAILTYPE.'_plugin'])) {
$selectedPlugin = $sendingParams[self::MAILTYPE.'_plugin'];
}
if (!empty($selectedPlugin)) {
$installed = false;
acym_trigger('onAcymCheckInstalled', [&$installed], $selectedPlugin);
if (!$installed) {
acym_trigger('getBirthdayField', [&$availableFields], get_class($this));
acym_enqueueMessage(
acym_translation('ACYM_WARNING_CAMPAIGN_BASED_ON_ANOTHER_PLUGIN'),
'error'
);
} else {
acym_trigger('getBirthdayField', [&$availableFields], $selectedPlugin);
}
} elseif ($onlyAcymailing) {
acym_trigger('getBirthdayField', [&$availableFields], get_class($this));
}
if (count($availableFields) == 1) {
$availableFields = ['' => acym_translation('ACYM_NO_FIELD_AVAILABLE')];
}
$inputField = '<div class="cell medium-2 margin-left-1 margin-right-1" >';
$inputField .= acym_select($availablePlugins, 'acym_plugin_field', !empty($selectedPlugin) ? $selectedPlugin : '', 'class="acym__select"');
$inputField .= '</div><div class="cell medium-8"></div>';
$additionalSettings = '<div class="cell grid-x acym_vcenter margin-left-3 margin-bottom-1" '.($onlyAcymailing ? 'style="display:none"' : '').'>';
$additionalSettings .= acym_translationSprintf('ACYM_CHOOSE_PLUGIN_TO_SELECT_BIRTHDAY_FIELD', $inputField);
$additionalSettings .= '</div>';
$selectedField = '';
if (!empty($sendingParams) && isset($sendingParams[self::MAILTYPE.'_field'])) {
$selectedField = $sendingParams[self::MAILTYPE.'_field'];
}
$inputField = '<div class="cell medium-2 margin-left-1 margin-right-1">';
$inputField .= acym_select($availableFields, 'acym_birthday_field', $selectedField, 'class="acym__select"');
$inputField .= '</div><div class="cell medium-8"></div>';
$additionalSettings .= '<div class="cell grid-x acym_vcenter margin-left-3 margin-bottom-1" id="acym_div_date_field"'.(empty($selectedPlugin) && !$onlyAcymailing
? 'style="display:none"' : '').'>';
$additionalSettings .= acym_translationSprintf('ACYM_BIRTHDAY_FIELD_PLUGIN', $inputField);
$additionalSettings .= '</div>';
$specificSettings[] = [
'whenSettings' => $whenSettings,
'additionnalSettings' => $additionalSettings,
];
}
public function saveCampaignSpecificSendSettings($type, &$specialSendings)
{
if ($type != self::MAILTYPE) return;
$inputTime = acym_getVar('int', 'acym_birthday_time_number', 0);
$typeTime = acym_getVar('string', 'acym_birthday_time_frame', 'day');
$relative = acym_getVar('string', 'acym_birthday_relative', 'before');
$plugin = acym_getVar('string', 'acym_plugin_field', 0);
$field = acym_getVar('string', 'acym_birthday_field', 0);
$specialSendings[] = [
self::MAILTYPE.'_number' => $inputTime,
self::MAILTYPE.'_type' => $typeTime,
self::MAILTYPE.'_relative' => $relative,
self::MAILTYPE.'_plugin' => $plugin,
self::MAILTYPE.'_field' => $field,
];
}
public function onAcymSendCampaignSpecial($campaign, &$filters, &$pluginIsExisting)
{
if ($campaign->sending_type != self::MAILTYPE) return;
$sendingTime = (int)$campaign->sending_params[self::MAILTYPE.'_number'];
if ($campaign->sending_params[self::MAILTYPE.'_type'] == 'weeks') {
$sendingTime *= 7;
} elseif ($campaign->sending_params[self::MAILTYPE.'_type'] == 'months') {
$sendingTime *= 30;
}
$filter = [
'birthday' => [
'days' => $sendingTime,
'field' => $campaign->sending_params[self::MAILTYPE.'_field'],
'relative' => $campaign->sending_params[self::MAILTYPE.'_relative'],
'plugin' => isset($campaign->sending_params[self::MAILTYPE.'_plugin']) ? $campaign->sending_params[self::MAILTYPE.'_plugin'] : get_class($this),
],
];
$installed = false;
acym_trigger('onAcymCheckInstalled', [&$installed], $filter['birthday']['plugin']);
if (!$installed) {
$pluginIsExisting = false;
return;
}
$filters[] = $filter;
}
public function onAcymProcessFilter_birthday(&$query, $options, $num = null)
{
if ($options['plugin'] !== get_class($this)) return;
$dateToCheck = $this->processDateToCheck($options);
$fieldClass = new FieldClass();
$birthdayField = $fieldClass->getOneById($options['field']);
if (empty($birthdayField)) return;
$query->join['birthday_field'.$num] = '#__acym_user_has_field AS uf'.$num.' ON uf'.$num.'.user_id = user.id';
$query->where[] = 'uf'.$num.'.field_id = '.intval($birthdayField->id);
$query->where[] = 'uf'.$num.'.value LIKE '.acym_escapeDB('%'.date_format($dateToCheck, '-m-d'));
}
public function specialActionOnDelete($typeElement, $elements)
{
if ($typeElement != 'field') return;
$campaignClass = new CampaignClass();
$fieldClass = new FieldClass();
$birthdayMails = $campaignClass->getCampaignsByTypes([self::MAILTYPE]);
foreach ($elements as $oneElement) {
if ($fieldClass->getFieldTypeById($oneElement) !== 'date') continue;
foreach ($birthdayMails as $oneBirthdayMail) {
if ($oneBirthdayMail->sending_params['birthday_field'] != $oneElement) continue;
$oneBirthdayMail->sending_params['birthday_field'] = '';
$oneBirthdayMail->draft = 1;
$campaignClass->save($oneBirthdayMail);
}
}
}
public function onAcymDisplayCampaignListingSpecificTabs(&$tabs)
{
$tabs['specificListing&type='.self::MAILTYPE] = 'ACYM_BIRTHDAY_EMAIL';
}
public function onAcymSpecificListingActive(&$exists, $task)
{
if ($task == self::MAILTYPE) {
$exists = true;
}
}
public function onAcymCampaignDataSpecificListing(&$data, $type)
{
if ($type == self::MAILTYPE) {
$data['typeWorkflowTab'] = 'specificListing&type='.self::MAILTYPE;
$data['element_to_display'] = acym_translation('ACYM_BIRTHDAY_EMAIL');
$campaignController = new CampaignsController();
$campaignController->prepareEmailsListing($data, $type);
}
}
public function onAcymCampaignAddFiltersSpecificListing(&$filters, $type)
{
if ($type == self::MAILTYPE) {
$filters[] = 'campaign.sending_type = '.acym_escapeDB(self::MAILTYPE);
}
}
public function filterSpecificMailsToSend(&$specialMails, $time)
{
$this->filterSpecialMailsDailySend($specialMails, $time, self::MAILTYPE);
}
public function getFollowupTriggerBlock(&$blocks)
{
$blocks[] = [
'name' => acym_translation('ACYM_BIRTHDAY'),
'description' => acym_translation('ACYM_BIRTHDAY_MAIL_FOLLOW_DESC'),
'icon' => 'acymicon-calendar',
'link' => acym_completeLink('campaigns&task=edit&step=followupCondition&trigger='.self::FOLLOWTRIGGER),
'level' => 2,
'alias' => self::FOLLOWTRIGGER,
];
}
public function getFollowupTriggers(&$triggers)
{
$triggers[self::FOLLOWTRIGGER] = acym_translation('ACYM_BIRTHDAY');
}
public function getAcymAdditionalConditionFollowup(&$additionalCondition, $trigger, $followup, $statusArray)
{
if ($trigger == self::FOLLOWTRIGGER) {
$fieldClass = new FieldClass();
$dateFields = $fieldClass->getFieldsByType(['date']);
$fields = [];
foreach ($dateFields as $oneField) {
$fields[$oneField->id] = acym_translation($oneField->name);
}
$fieldsSelect = acym_select(
$fields,
'followup[condition][birthday_field]',
!empty($followup->condition) ? $followup->condition['birthday_field'] : '',
'class="acym__select" required'
);
$fieldsSelect = '<span class="cell large-2 medium-4 margin-left-1">'.$fieldsSelect.'</span>';
$additionalCondition['birthday_field'] = acym_translationSprintf('ACYM_BIRTHDAY_FIELD', acym_info('ACYM_BIRTHDAY_FIELD_CUSTOM_FIELD_TYPE_DATE').$fieldsSelect);
}
}
public function getFollowupConditionSummary(&$return, $condition, $trigger, $statusArray)
{
if ($trigger == self::FOLLOWTRIGGER && !empty($condition['birthday_field'])) {
$fieldClass = new FieldClass();
$field = $fieldClass->getOneById($condition['birthday_field']);
$return[] = acym_translationSprintf('ACYM_BIRTHDAY_FIELD_IS', $field->name);
}
}
public function onAcymGetFollowupDailyBases(&$triggers)
{
$triggers[] = self::FOLLOWTRIGGER;
}
public function onAcymFollowupDailyBasesNeedToBeTriggered($followup)
{
if (self::FOLLOWTRIGGER == $followup->trigger) {
$automationHelper = new AutomationHelper();
$fieldClass = new FieldClass();
$birthdayField = $fieldClass->getOneById($followup->condition['birthday_field']);
if (empty($birthdayField)) return;
$dateNowWithTimeZone = acym_date('now', 'Y-m-d h:i:s');
$dateToCheck = new DateTime($dateNowWithTimeZone);
$automationHelper->join['birthday_field'] = '#__acym_user_has_field AS uf ON uf.user_id = user.id';
$automationHelper->where[] = 'uf.field_id = '.$birthdayField->id;
$automationHelper->where[] = 'uf.value LIKE '.acym_escapeDB('%-'.date_format($dateToCheck, 'm-d'));
$userIds = acym_loadResultArray($automationHelper->getQuery(['user.id']));
$followupClass = new FollowupClass();
foreach ($userIds as $userId) {
$followupClass->addFollowupEmailsQueue($followup->trigger, $userId);
}
}
}
public function getBirthdayField(&$availableFields)
{
$fieldClass = new FieldClass();
$dateFields = $fieldClass->getFieldsByType(['date']);
foreach ($dateFields as $oneField) {
$availableFields[$oneField->id] = acym_translation($oneField->name);
}
}
public function getJsonBirthdayField()
{
$availableFields = [];
$this->getBirthdayField($availableFields);
echo json_encode(['fields' => $availableFields]);
exit;
}
}