diff --git a/deployed/acym/administrator/components/com_acym/acym.php b/deployed/acym/administrator/components/com_acym/acym.php
new file mode 100644
index 00000000..f26fdeee
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/acym.php
@@ -0,0 +1,89 @@
+This version of AcyMailing requires at least PHP 5.4.0, it is time to update the PHP version of your server!
';
+ exit;
+}
+
+if (!include_once(rtrim(JPATH_ADMINISTRATOR, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR.'components'.DIRECTORY_SEPARATOR.'com_acym'.DIRECTORY_SEPARATOR.'helpers'.DIRECTORY_SEPARATOR.'helper.php')) {
+ echo "Could not load Acy helper file";
+
+ return;
+}
+
+if (acym_isDebug()) {
+ acym_displayErrors();
+}
+
+$ctrl = acym_getVar('cmd', 'ctrl', 'dashboard');
+$task = acym_getVar('cmd', 'task');
+
+$config = acym_config();
+
+if ((($config->get('migration') == 0 && acym_existsAcyMailing59() && acym_getVar('string', 'task') != 'migrationDone') || $config->get('walk_through') == 1) && !acym_isNoTemplate()) {
+ $ctrl = 'dashboard';
+}
+
+
+if (!include_once(ACYM_CONTROLLER.$ctrl.'.php')) {
+ acym_redirect(acym_completeLink('dashboard'));
+
+ return;
+}
+
+$className = ucfirst($ctrl).'Controller';
+$controller = new $className();
+
+if (empty($task)) {
+ $task = acym_getVar('cmd', 'defaulttask', $controller->defaulttask);
+ acym_setVar('task', $task);
+}
+
+if (file_exists(ACYM_BACK.'extensions')) {
+ $updateHelper = acym_get('helper.update');
+ $updateHelper->installExtensions();
+}
+
+acym_addScript(
+ true,
+ 'var TOGGLE_URL_ACYM = "index.php?option='.ACYM_COMPONENT.'&'.acym_noTemplate().'&ctrl=toggle&'.acym_getFormToken().'";
+ var AJAX_URL_ACYM = "index.php?option='.ACYM_COMPONENT.'&'.acym_noTemplate().'&'.acym_getFormToken().'";
+ var AJAX_URL_ACYBA = "'.ACYM_ACYWEBSITE.'";
+ var MEDIA_URL_ACYM = "'.ACYM_MEDIA_URL.'";
+ var CMS_ACYM = "'.ACYM_CMS.'";
+ var FOUNDATION_FOR_EMAIL = "'.ACYM_CSS.'libraries/foundation_email.min.css?v='.filemtime(ACYM_MEDIA.'css'.DS.'libraries'.DS.'foundation_email.min.css').'";
+ var ACYM_FIXES_FOR_EMAIL = "'.ACYM_CSS.'email.min.css?v='.filemtime(ACYM_MEDIA.'css'.DS.'email.min.css').'";
+ var ACYM_REGEX_EMAIL = /^'.acym_getEmailRegex(true).'$/i;
+ var ACYM_JS_TXT = '.acym_getJSMessages().';
+ var ACYM_JOOMLA_MEDIA_IMAGE = "'.ACYM_LIVE.'";'
+);
+
+JHtml::_('jquery.framework');
+acym_addScript(false, 'https://code.jquery.com/ui/1.11.4/jquery-ui.min.js');
+
+acym_addScript(false, ACYM_JS.'libraries/foundation.min.js?v='.filemtime(ACYM_MEDIA.'js'.DS.'libraries'.DS.'foundation.min.js'));
+acym_addScript(false, ACYM_JS.'libraries/select2.min.js?v='.filemtime(ACYM_MEDIA.'js'.DS.'libraries'.DS.'select2.min.js'));
+
+acym_addStyle(false, 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css');
+
+acym_addStyle(false, ACYM_CSS.'libraries/introjs.min.css?v='.filemtime(ACYM_MEDIA.'css'.DS.'libraries'.DS.'introjs.min.css'));
+acym_addScript(false, ACYM_JS.'libraries/intro.min.js?v='.filemtime(ACYM_MEDIA.'js'.DS.'libraries'.DS.'intro.min.js'));
+
+acym_addScript(false, ACYM_JS.'global.min.js?v='.filemtime(ACYM_MEDIA.'js'.DS.'global.min.js'));
+acym_addScript(false, ACYM_JS.'back_global.min.js?v='.filemtime(ACYM_MEDIA.'js'.DS.'back_global.min.js'));
+acym_addStyle(false, ACYM_CSS.'back_global.min.css?v='.filemtime(ACYM_MEDIA.'css'.DS.'back_global.min.css'));
+if (file_exists(ACYM_MEDIA.'js'.DS.'back'.DS.$ctrl.'.min.js')) {
+ acym_addScript(false, ACYM_JS.'back/'.$ctrl.'.min.js?v='.filemtime(ACYM_MEDIA.'js'.DS.'back'.DS.$ctrl.'.min.js'));
+}
+
+$controller->loadScripts($task);
+$controller->$task();
diff --git a/deployed/acym/administrator/components/com_acym/acym.xml b/deployed/acym/administrator/components/com_acym/acym.xml
new file mode 100644
index 00000000..55e57a73
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/acym.xml
@@ -0,0 +1,69 @@
+
+'.$field->name.'
';
+ }
+
+ if ($field->id == 1) {
+ $nameAttribute = ' name="user[name]"';
+ $return .= ' ';
+ } elseif ($field->id == 2) {
+ $nameAttribute = ' name="user[email]"';
+ $return .= ' ';
+ } elseif ($field->type == 'text') {
+ $field->option->authorized_content->message = $field->option->error_message_invalid;
+ $authorizedContent = ' data-authorized-content="'.acym_escape(json_encode($field->option->authorized_content)).'"';
+ $return .= ' ';
+ } elseif ($field->type == 'textarea') {
+ $return .= '';
+ } elseif ($field->type == 'radio') {
+ if ($displayFront) {
+ $return .= ''.$field->name.'
';
+ $defaultValue = empty($defaultValue) ? null : (is_array($defaultValue) ? $defaultValue[0] : $defaultValue);
+ foreach ($valuesArray as $key => $value) {
+ $defaultValue = $defaultValue == $key ? 'checked' : '';
+ $return .= '
'.$value.' ';
+ }
+ $return .= '
';
+ } else {
+ $return .= '';
+ $return .= '
'.$field->name.'
';
+ $return .= acym_radio($valuesArray, $name.'[]', empty($defaultValue) ? null : (is_array($defaultValue) ? $defaultValue[0] : $defaultValue), null, ($field->required ? ['data-required' => $requiredJson] : []));
+ $return .= '
';
+ }
+ } elseif ($field->type == 'checkbox') {
+ $return .= '';
+ } elseif ($field->type == 'single_dropdown') {
+ $return .= acym_select($valuesArray, $name, empty($defaultValue) ? '' : $defaultValue, 'class="acym__custom__fields__select__form"'.$style.$required);
+ } elseif ($field->type == 'multiple_dropdown') {
+ $defaultValue = is_array($defaultValue) ? $defaultValue : explode(',', $defaultValue);
+
+ $attributes = [
+ 'class' => 'acym__custom__fields__select__multiple__form',
+ 'style' => $size,
+ ];
+ if ($field->required) $attributes['data-required'] = $requiredJson;
+
+ $return .= acym_selectMultiple($valuesArray, $name, empty($defaultValue) ? [] : $defaultValue, $attributes);
+ } elseif ($field->type == 'date') {
+ $defaultValue = is_array($defaultValue) ? implode('/', $defaultValue) : $defaultValue;
+ $return .= acym_displayDateFormat($field->option->format, $name.'[]', $defaultValue);
+ } elseif ($field->type == 'file') {
+ $defaultValue = is_array($defaultValue) ? $defaultValue[0] : $defaultValue;
+ if ($displayFront) {
+ $return .= ''.$field->name.'
';
+ $return .= ' ';
+ } else {
+ $return .= acym_inputFile($name.'[]', $defaultValue, '', '', $required);
+ }
+ } elseif ($field->type == 'phone') {
+ $defaultValue = !empty($defaultValue) ? explode(',', $defaultValue) : '';
+
+ if ($displayOutside) $return .= ''.$field->name.'
';
+ $return .= '';
+ $return .= acym_generateCountryNumber($name.'[code]', empty($defaultValue) ? '' : $defaultValue[0]);
+ $return .= '
';
+ $return .= ' ';
+ } elseif ($field->type == 'custom_text') {
+ $return .= $field->option->custom_text;
+ }
+
+
+ if ($field->type == 'date' || ($displayOutside && (in_array($field->id, [1, 2]) || in_array($field->type, ['text', 'textarea', 'single_dropdown', 'multiple_dropdown', 'phone', 'custom_text'])))) {
+ $return .= ' ';
+ }
+
+ return $return;
+ }
+}
+
diff --git a/deployed/acym/administrator/components/com_acym/classes/history.php b/deployed/acym/administrator/components/com_acym/classes/history.php
new file mode 100644
index 00000000..de907d92
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/classes/history.php
@@ -0,0 +1,86 @@
+user_id = intval($userId);
+ $history->action = strip_tags($action);
+ $history->data = implode("\n", $data);
+ if (strlen($history->data) > 100000) {
+ $history->data = substr($history->data, 0, 10000);
+ }
+
+ static $date = null;
+ if (empty($date)) {
+ $date = time();
+ }
+
+ $history->date = ++$date;
+ while ($this->alreadyExists($history->user_id, $history->date)) {
+ $history->date++;
+ }
+
+ $date = $history->date;
+
+ $history->mail_id = $mailid;
+ $config = acym_config();
+ if ($config->get('anonymous_tracking', 0) == 0) {
+ $history->ip = acym_getIP();
+ }
+
+ if (!empty($_SERVER)) {
+ $source = [];
+ if ($config->get('anonymous_tracking', 0) == 0) {
+ $vars = ['HTTP_REFERER', 'HTTP_USER_AGENT', 'HTTP_HOST', 'SERVER_ADDR', 'REMOTE_ADDR', 'REQUEST_URI', 'QUERY_STRING'];
+ } else {
+ $vars = ['HTTP_REFERER', 'HTTP_HOST', 'SERVER_ADDR', 'REQUEST_URI', 'QUERY_STRING'];
+ }
+
+ foreach ($vars as $oneVar) {
+ if (!empty($_SERVER[$oneVar])) {
+ $source[] = $oneVar.'::'.strip_tags($_SERVER[$oneVar]);
+ }
+ }
+ $history->source = implode("\n", $source);
+ }
+
+ return acym_insertObject('#__acym_history', $history);
+ }
+
+ function alreadyExists($userId, $date)
+ {
+ $result = acym_loadResult('SELECT user_id FROM #__acym_history WHERE user_id = '.intval($userId).' AND date = '.acym_escapeDB($date));
+
+ return !empty($result);
+ }
+
+ public function getHistoryOfOneById($id)
+ {
+ $query = 'SELECT h.*, m.id, m.subject FROM #__acym_'.$this->table.' AS h ';
+ $query .= 'LEFT JOIN #__acym_mail AS m ON h.mail_id = m.id ';
+ $query .= 'WHERE h.user_id = '.intval($id);
+ $query .= ' ORDER BY h.date DESC';
+
+ return acym_loadObjectList($query);
+ }
+}
+
diff --git a/deployed/acym/administrator/components/com_acym/classes/index.html b/deployed/acym/administrator/components/com_acym/classes/index.html
new file mode 100644
index 00000000..fa6d84e8
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/classes/index.html
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/deployed/acym/administrator/components/com_acym/classes/list.php b/deployed/acym/administrator/components/com_acym/classes/list.php
new file mode 100644
index 00000000..4c4d2dc8
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/classes/list.php
@@ -0,0 +1,515 @@
+ 'active = 1',
+ 'inactive' => 'active = 0',
+ 'visible' => 'visible = 1',
+ 'invisible' => 'visible = 0',
+ ];
+ if (empty($allowedStatus[$settings['status']])) {
+ die('Injection denied');
+ }
+ $filters[] = 'list.'.$allowedStatus[$settings['status']];
+ }
+
+ if (!empty($filters)) {
+ $query .= ' WHERE ('.implode(') AND (', $filters).')';
+ $queryCount .= ' WHERE ('.implode(') AND (', $filters).')';
+ }
+
+ if (!empty($settings['ordering']) && !empty($settings['ordering_sort_order'])) {
+ $query .= ' ORDER BY list.'.acym_secureDBColumn($settings['ordering']).' '.acym_secureDBColumn(strtoupper($settings['ordering_sort_order']));
+ }
+
+ $settings['offset'] = $settings['offset'] < 0 ? 0 : $settings['offset'];
+
+ $results['lists'] = acym_loadObjectList($query, '', $settings['offset'], $settings['listsPerPage']);
+ foreach ($results['lists'] as $i => $oneList) {
+ array_push($listsId, $oneList->id);
+ $results['lists'][$i]->subscribers = 0;
+ $results['lists'][$i]->sendable = 0;
+ }
+
+ if (empty($listsId)) {
+ $countUserByList = [];
+ } else {
+ acym_arrayToInteger($listsId);
+ $query = 'SELECT userList.list_id, COUNT(userList.user_id) AS users, SUM(acyuser.confirmed) AS sendable
+ FROM #__acym_user_has_list AS userList
+ JOIN #__acym_user AS acyuser
+ ON acyuser.id = userList.user_id
+ WHERE userList.list_id IN ('.implode(',', $listsId).')
+ AND userList.status = 1
+ AND acyuser.active = 1
+ GROUP BY userList.list_id';
+
+ $countUserByList = acym_loadObjectList($query);
+ }
+
+ foreach ($results['lists'] as $i => $list) {
+ $results['lists'][$i]->tags = [];
+ foreach ($countUserByList as $userList) {
+ if ($list->id == $userList->list_id) {
+ $results['lists'][$i]->subscribers = $userList->users;
+ $results['lists'][$i]->sendable = $userList->sendable;
+ }
+ }
+ }
+
+ $results['total'] = acym_loadResult($queryCount);
+
+ $listsPerStatus = acym_loadObjectList($queryStatus.' GROUP BY score', 'score');
+ for ($i = 0 ; $i < 4 ; $i++) {
+ $listsPerStatus[$i] = empty($listsPerStatus[$i]) ? 0 : $listsPerStatus[$i]->number;
+ }
+
+ $results['status'] = [
+ 'all' => array_sum($listsPerStatus),
+ 'active' => $listsPerStatus[1] + $listsPerStatus[3],
+ 'inactive' => $listsPerStatus[0] + $listsPerStatus[2],
+ 'visible' => $listsPerStatus[2] + $listsPerStatus[3],
+ 'invisible' => $listsPerStatus[0] + $listsPerStatus[1],
+ ];
+
+ return $results;
+ }
+
+ public function getListsWithIdNameCount($settings)
+ {
+ $filters = [];
+
+ if (isset($settings['ids'])) {
+ if (empty($settings['ids'])) {
+ return ['lists' => [], 'total' => 0];
+ } else {
+ acym_arrayToInteger($settings['ids']);
+ $filters[] = 'list.id IN ('.implode(',', $settings['ids']).')';
+ }
+ }
+
+
+ $config = acym_config();
+ $confirmed = $config->get('require_confirmation', 1) == 1 ? ' AND user.confirmed = 1 ' : '';
+ $query = 'SELECT list.id, list.name, list.color, list.active, COUNT(userList.user_id) AS subscribers
+ FROM #__acym_list AS list
+ LEFT JOIN #__acym_user_has_list AS userList
+ JOIN #__acym_user AS user
+ ON user.id = userList.user_id
+ AND userList.status = 1
+ AND user.active = 1 '.$confirmed.'
+ ON list.id = userList.list_id';
+
+ $queryCount = 'SELECT COUNT(list.id)
+ FROM #__acym_list AS list';
+
+ if (!empty($settings['search'])) {
+ $filters[] = 'list.name LIKE '.acym_escapeDB('%'.$settings['search'].'%');
+ }
+
+ if (!empty($settings['already'])) {
+ acym_arrayToInteger($settings['already']);
+ $filters[] = 'list.id NOT IN('.implode(',', $settings['already']).')';
+ }
+
+ if (!empty($filters)) {
+ $query .= ' WHERE ('.implode(') AND (', $filters).')';
+ $queryCount .= ' WHERE ('.implode(') AND (', $filters).')';
+ }
+
+ $query .= ' GROUP BY list.id ';
+
+ $results['lists'] = acym_loadObjectList($query, '', $settings['offset'], $settings['listsPerPage']);
+ $results['total'] = acym_loadResult($queryCount);
+
+ return $results;
+ }
+
+ public function getOneById($id)
+ {
+ return acym_loadObject('SELECT * FROM #__acym_list WHERE id = '.intval($id).' LIMIT 1');
+ }
+
+ public function getOneByName($name)
+ {
+ return acym_loadObject('SELECT * FROM #__acym_list WHERE name='.acym_escapeDB($name));
+ }
+
+ public function getListsByIds($ids)
+ {
+
+ if (!is_array($ids)) $ids = [$ids];
+ acym_arrayToInteger($ids);
+ if (empty($ids)) return [];
+
+ $query = 'SELECT * FROM #__acym_list WHERE id IN ('.implode(', ', $ids).')';
+
+ return acym_loadObjectList($query);
+ }
+
+ public function getAllListUsers()
+ {
+ $query = 'SELECT #__acym_user_has_list.list_id, count(*)
+ FROM #__acym_list AS list
+ JOIN #__acym_user_has_list
+ ON list.id = #__acym_user_has_list.list_id
+ JOIN #__acym_user
+ ON #__acym_user.id = #__acym_user_has_list.user_id
+ GROUP BY list.id';
+
+ return acym_loadObjectList($query);
+ }
+
+ public function getMatchingSubscribersByListId($settings, $id)
+ {
+ $query = 'SELECT user.* FROM #__acym_user AS user JOIN #__acym_user_has_list AS userList ON user.id = userList.user_id';
+ $queryCount = 'SELECT COUNT(user.id) FROM #__acym_user AS user JOIN #__acym_user_has_list AS userList ON user.id = userList.user_id';
+ $queryStatus = 'SELECT COUNT(id) AS number, active FROM #__acym_user AS user JOIN #__acym_user_has_list AS userList ON user.id = userList.user_id';
+
+ $filters = [];
+ $filters[] = 'userList.list_id = '.intval($id);
+ $filters[] = 'userList.status = 1';
+
+ if (!empty($settings['search'])) {
+ $searchValue = acym_escapeDB('%'.$settings['search'].'%');
+ $filters[] = 'user.email LIKE '.$searchValue.' OR user.name LIKE '.$searchValue;
+ }
+
+ if (!empty($filters)) {
+ $queryStatus .= ' WHERE ('.implode(') AND (', $filters).')';
+ }
+
+ if (!empty($settings['status'])) {
+ $allowedStatus = [
+ 'active' => 'active = 1',
+ 'inactive' => 'active = 0',
+ ];
+ if (empty($allowedStatus[$settings['status']])) {
+ die('Injection denied');
+ }
+ $filters[] = 'user.'.$allowedStatus[$settings['status']];
+ }
+
+ if (!empty($filters)) {
+ $query .= ' WHERE ('.implode(') AND (', $filters).')';
+ $queryCount .= ' WHERE ('.implode(') AND (', $filters).')';
+ }
+
+ $query .= ' ORDER BY user.id DESC';
+
+ $results['users'] = acym_loadObjectList($query, '', $settings['offset'], $settings['usersPerPage']);
+ $results['total'] = acym_loadResult($queryCount);
+
+ $usersPerStatus = acym_loadObjectList($queryStatus.' GROUP BY active', 'active');
+
+ for ($i = 0 ; $i < 2 ; $i++) {
+ $usersPerStatus[$i] = empty($usersPerStatus[$i]) ? 0 : $usersPerStatus[$i]->number;
+ }
+
+ $results['status'] = [
+ 'all' => array_sum($usersPerStatus),
+ 'active' => $usersPerStatus[1],
+ 'inactive' => $usersPerStatus[0],
+ ];
+
+ return $results;
+ }
+
+ public function getSubscribersCountByListId($id)
+ {
+ $config = acym_config();
+ $confirmed = $config->get('require_confirmation', 1) == 1 ? ' AND users.confirmed = 1 ' : '';
+
+ $query = 'SELECT COUNT(userLists.user_id) AS subscribers
+ FROM #__acym_user_has_list AS userLists
+ JOIN #__acym_user AS users ON userLists.user_id = users.id
+ WHERE userLists.list_id = '.intval($id).'
+ AND userLists.status = 1
+ AND users.active = 1 '.$confirmed.'
+ GROUP BY userLists.list_id';
+
+ $result = acym_loadResult($query);
+
+ return empty($result) ? 0 : $result;
+ }
+
+ public function getSubscribersCount($listsIds)
+ {
+ acym_arrayToInteger($listsIds);
+ if (empty($listsIds)) return 0;
+
+ $query = 'SELECT COUNT(DISTINCT user.id)
+ FROM #__acym_user AS user
+ JOIN #__acym_user_has_list AS userList ON user.id = userList.user_id
+ WHERE userList.list_id IN ('.implode(",", $listsIds).') AND userList.status = 1 AND user.active = 1';
+
+ $config = acym_config();
+ if ($config->get('require_confirmation', 1) == 1) {
+ $query .= ' AND user.confirmed = 1';
+ }
+
+ $nbSubscribers = acym_loadResult($query);
+
+ return $nbSubscribers;
+ }
+
+ public function getSubscribersIdsById($listId, $returnUnsubscribed = false)
+ {
+ $query = 'SELECT user_id FROM #__acym_user_has_list WHERE list_id = '.intval($listId);
+
+ if (!$returnUnsubscribed) {
+ $query .= ' AND status = 1';
+ }
+
+ return acym_loadResultArray($query);
+ }
+
+ public function getSubscribersByListId($listId)
+ {
+ return acym_loadObjectList('SELECT user.* FROM #__acym_user AS user LEFT JOIN #__acym_user_has_list AS user_list ON user.id = user_list.user_id WHERE user_list.list_id = '.intval($listId));
+ }
+
+ public function delete($elements)
+ {
+ if (!is_array($elements)) {
+ $elements = [$elements];
+ }
+
+ if (empty($elements)) {
+ return 0;
+ }
+
+ foreach ($elements as $id) {
+ acym_query('DELETE FROM #__acym_mail_has_list WHERE list_id = '.intval($id));
+ acym_query('DELETE FROM #__acym_user_has_list WHERE list_id = '.intval($id));
+ acym_query('DELETE FROM #__acym_tag WHERE `id_element` = '.intval($id).' AND `type` = "list"');
+ }
+
+ return parent::delete($elements);
+ }
+
+ public function save($list)
+ {
+ if (isset($list->tags)) {
+ $tags = $list->tags;
+ unset($list->tags);
+ }
+
+ if (empty($list->id)) {
+ if (empty($list->cms_user_id)) $list->cms_user_id = acym_currentUserId();
+
+ $list->creation_date = acym_date('now', 'Y-m-d H:i:s', false);
+ }
+
+ foreach ($list as $oneAttribute => $value) {
+ if (empty($value)) continue;
+
+ $list->$oneAttribute = strip_tags($value);
+ }
+
+ $listID = parent::save($list);
+
+ if (!empty($listID) && isset($tags)) {
+ $tagClass = acym_get('class.tag');
+ $tagClass->setTags('list', $listID, $tags);
+ }
+
+ return $listID;
+ }
+
+ function getAll($key = 'id')
+ {
+ $lists = acym_loadObjectList('SELECT * FROM #__acym_list', $key);
+
+ return $lists;
+ }
+
+ function getAllWithIdName()
+ {
+ $lists = acym_loadObjectList('SELECT id, name FROM #__acym_list', 'id');
+
+ $listsToReturn = [];
+
+ foreach ($lists as $key => $list) {
+ $listsToReturn[$key] = $list->name;
+ }
+
+ return $listsToReturn;
+ }
+
+ function getAllForSelect()
+ {
+ $lists = acym_loadObjectList('SELECT * FROM #__acym_list', 'id');
+
+ $return = [];
+
+ $return[] = acym_translation('ACYM_SELECT_A_LIST');
+
+ foreach ($lists as $key => $list) {
+ $return[$key] = $list->name;
+ }
+
+ return $return;
+ }
+
+ public function setVisible($elements, $status)
+ {
+ if (!is_array($elements)) {
+ $elements = [$elements];
+ }
+
+ if (empty($elements)) {
+ return;
+ }
+
+ acym_arrayToInteger($elements);
+ $status = empty($status) ? 0 : 1;
+ acym_query('UPDATE #__acym_list SET visible = '.intval($status).' WHERE id IN ('.implode(',', $elements).')');
+ }
+
+ public function sendWelcome($userID, $listIDs)
+ {
+ if (acym_isAdmin()) {
+ return;
+ }
+
+ acym_arrayToInteger($listIDs);
+ if (empty($listIDs)) {
+ return;
+ }
+
+ $messages = acym_loadObjectList('SELECT `welcome_id` FROM #__acym_list WHERE `id` IN ('.implode(',', $listIDs).') AND `active` = 1');
+
+ if (empty($messages)) {
+ return;
+ }
+
+ $alreadySent = [];
+ $config = acym_config();
+ $mailerHelper = acym_get('helper.mailer');
+ $mailerHelper->report = $config->get('welcome_message', 1);
+ foreach ($messages as $oneMessage) {
+ $mailid = $oneMessage->welcome_id;
+ if (empty($mailid)) continue;
+
+ if (isset($alreadySent[$mailid])) {
+ continue;
+ }
+
+ $mailerHelper->trackEmail = true;
+ $mailerHelper->sendOne($mailid, $userID);
+ $alreadySent[$mailid] = true;
+ }
+ }
+
+ public function sendUnsubscribe($userID, $listIDs)
+ {
+ if (acym_isAdmin()) {
+ return;
+ }
+
+ acym_arrayToInteger($listIDs);
+ if (empty($listIDs)) {
+ return;
+ }
+
+ $messages = acym_loadObjectList('SELECT `unsubscribe_id` FROM #__acym_list WHERE `id` IN ('.implode(',', $listIDs).') AND `active` = 1');
+
+ if (empty($messages)) {
+ return;
+ }
+
+ $alreadySent = [];
+ $config = acym_config();
+ $mailerHelper = acym_get('helper.mailer');
+ $mailerHelper->report = $config->get('unsub_message', 1);
+ foreach ($messages as $oneMessage) {
+ if (!empty($oneMessage->unsubscribe_id)) {
+ $mailid = $oneMessage->unsubscribe_id;
+
+ if (isset($alreadySent[$mailid])) {
+ continue;
+ }
+
+ $mailerHelper->trackEmail = true;
+ $mailerHelper->sendOne($mailid, $userID);
+ $alreadySent[$mailid] = true;
+ }
+ }
+ }
+
+ public function addDefaultList()
+ {
+ $listId = acym_loadResult('SELECT `id` FROM #__acym_list LIMIT 1');
+ if (empty($listId)) {
+ $defaultList = new stdClass();
+ $defaultList->name = 'Newsletters';
+ $defaultList->color = '#3366ff';
+
+ $this->save($defaultList);
+ }
+ }
+
+
+ public function getTotalSubCount($ids)
+ {
+ acym_arrayToInteger($ids);
+ $query = "SELECT COUNT(DISTINCT hasList.user_id)
+ FROM #__acym_user_has_list AS hasList
+ JOIN #__acym_user AS user
+ ON hasList.user_id = user.id
+ WHERE hasList.status = 1
+ AND user.active = 1
+ AND hasList.list_id IN (".implode(',', $ids).")";
+
+
+ $config = acym_config();
+ if ($config->get('require_confirmation', 1) == 1) {
+ $query .= ' AND user.confirmed = 1 ';
+ }
+
+ return intval(acym_loadResult($query));
+ }
+}
+
diff --git a/deployed/acym/administrator/components/com_acym/classes/mail.php b/deployed/acym/administrator/components/com_acym/classes/mail.php
new file mode 100644
index 00000000..95a128fe
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/classes/mail.php
@@ -0,0 +1,799 @@
+decode(acym_loadObjectList($query, '', $settings['offset'], $settings['mailsPerPage']));
+ $results['total'] = acym_loadResult($queryCount);
+
+ $mailsPerStatus = acym_loadObjectList($queryStatus.' GROUP BY type', 'type');
+ $nbAllMail = 0;
+ foreach ($mailsPerStatus as $oneMailType) {
+ $nbAllMail += $oneMailType->number;
+ }
+
+ $results['status'] = [
+ 'all' => $nbAllMail,
+ 'standard' => !empty($mailsPerStatus['standard']->number) ? $mailsPerStatus['standard']->number : 0,
+ 'welcome' => !empty($mailsPerStatus['welcome']->number) ? $mailsPerStatus['welcome']->number : 0,
+ 'unsubscribe' => !empty($mailsPerStatus['unsubscribe']->number) ? $mailsPerStatus['unsubscribe']->number : 0,
+ ];
+
+ return $results;
+ }
+
+ public function getAll()
+ {
+ return $this->decode(acym_loadObjectList('SELECT * FROM #__acym_mail'));
+ }
+
+ public function getOneById($id)
+ {
+ $mail = $this->decode(acym_loadObject('SELECT * FROM #__acym_mail WHERE id = '.intval($id)));
+
+ if (!empty($mail)) {
+ $tagsClass = acym_get('class.tag');
+ $mail->tags = $tagsClass->getAllTagsByElementId('mail', $id);
+ }
+
+ return $mail;
+ }
+
+ public function getOneByName($name)
+ {
+ $mail = $this->decode(acym_loadObject('SELECT * FROM #__acym_mail WHERE `name` = '.acym_escapeDB($name)));
+
+ if (!empty($mail)) {
+ $tagsClass = acym_get('class.tag');
+ $mail->tags = $tagsClass->getAllTagsByElementId('mail', $mail->id);
+ }
+
+ return $mail;
+ }
+
+ public function getMailsByType($typeMail, $settings)
+ {
+ if (empty($settings['key'])) {
+ $settings['key'] = '';
+ }
+ if (empty($settings['offset'])) {
+ $settings['offset'] = 0;
+ }
+ if (empty($settings['mailsPerPage'])) {
+ $settings['mailsPerPage'] = 12;
+ }
+
+ $query = 'SELECT * FROM #__acym_mail AS mail';
+ $queryCount = 'SELECT count(*) FROM #__acym_mail AS mail';
+
+ $filters = [];
+ $filters[] = 'mail.type = '.acym_escapeDB($typeMail);
+
+ if (!empty($settings['search'])) {
+ $filters[] = 'mail.name LIKE '.acym_escapeDB('%'.$settings['search'].'%');
+ }
+
+ $query .= ' WHERE ('.implode(') AND (', $filters).')';
+ $queryCount .= ' WHERE ('.implode(') AND (', $filters).')';
+
+ $query .= ' ORDER BY id DESC';
+
+ $results['mails'] = $this->decode(acym_loadObjectList($query, $settings['key'], $settings['offset'], $settings['mailsPerPage']));
+ $results['total'] = acym_loadResult($queryCount);
+
+ return $results;
+ }
+
+ public function getAllListsWithCountSubscribersByMailIds($ids)
+ {
+ acym_arrayToInteger($ids);
+ if (empty($ids)) {
+ return [];
+ }
+
+ $query = 'SELECT mailLists.list_id, mailLists.mail_id, list.*, COUNT(userLists.user_id) AS subscribers
+ FROM #__acym_mail_has_list AS mailLists
+ JOIN #__acym_list AS list ON mailLists.list_id = list.id
+ LEFT JOIN #__acym_user_has_list AS userLists
+ JOIN #__acym_user AS acyuser ON userLists.user_id = acyuser.id
+ AND userLists.status = 1
+ AND acyuser.active = 1 ';
+
+ $config = acym_config();
+ if ($config->get('require_confirmation', 1) == 1) {
+ $query .= ' AND acyuser.confirmed = 1 ';
+ }
+
+ $query .= 'ON list.id = userLists.list_id
+ WHERE mailLists.mail_id IN ('.implode(",", $ids).')
+ GROUP BY mailLists.list_id, mailLists.mail_id';
+
+ return acym_loadObjectList($query);
+ }
+
+ public function getAllListsByMailId($id)
+ {
+ $mail = $this->getOneById($id);
+ if (empty($mail)) return [];
+
+ if ('welcome' === $mail->type) {
+ $query = 'SELECT * FROM #__acym_list WHERE welcome_id = '.intval($id);
+ } else {
+ $query = 'SELECT list.*
+ FROM #__acym_mail_has_list AS mailLists
+ JOIN #__acym_list AS list ON mailLists.list_id = list.id
+ WHERE mailLists.mail_id = '.intval($id).'
+ GROUP BY mailLists.list_id, mailLists.mail_id';
+ }
+
+
+ return acym_loadObjectList($query, 'id');
+ }
+
+ public function save($mail)
+ {
+ if (isset($mail->tags)) {
+ $tags = $mail->tags;
+ unset($mail->tags);
+ }
+
+ if (empty($mail->id)) {
+ $mail->creation_date = acym_date('now', 'Y-m-d H:i:s', false);
+ if (empty($mail->creator_id)) $mail->creator_id = acym_currentUserId();
+ }
+
+ $mail = $this->encode($mail);
+
+ $mail->autosave = null;
+
+ foreach ($mail as $oneAttribute => $value) {
+ if (empty($value) || in_array($oneAttribute, ['thumbnail', 'settings'])) {
+ continue;
+ }
+
+ if (in_array($oneAttribute, ['body', 'headers'])) {
+ $mail->$oneAttribute = preg_replace('# ]*value="[^"]*"[^>]*>#Uis', '', $mail->$oneAttribute);
+
+ $mail->$oneAttribute = str_replace(' contenteditable="true"', '', $mail->$oneAttribute);
+ } else {
+ $mail->$oneAttribute = strip_tags($mail->$oneAttribute);
+ }
+ }
+
+ $mailID = parent::save($mail);
+
+ if (!empty($mailID) && isset($tags)) {
+ $tagClass = acym_get('class.tag');
+ $tagClass->setTags('mail', $mailID, $tags);
+ }
+
+ return $mailID;
+ }
+
+ public function autoSave($mail)
+ {
+ if (empty($mail->id)) return false;
+
+ $mail->autosave = str_replace(' contenteditable="true"', '', $mail->autosave);
+ $mail = $this->encode($mail);
+
+ return parent::save($mail);
+ }
+
+ public function delete($elements)
+ {
+ if (!is_array($elements)) $elements = [$elements];
+
+ if (empty($elements)) return 0;
+
+ $this->deleteMediaFolder($elements);
+ acym_arrayToInteger($elements);
+
+ $allThumbnailToDelete = acym_loadResultArray('SELECT thumbnail FROM #__acym_mail WHERE id IN ('.implode(',', $elements).')');
+
+ $link = 'wordpress' === ACYM_CMS ? WP_CONTENT_DIR.DS.'uploads'.DS.'acymailing'.DS : ACYM_MEDIA.'images';
+
+ foreach ($allThumbnailToDelete as $one) {
+ if (!empty($one) && file_exists($link.$one)) {
+ unlink($link.$one);
+ }
+ }
+
+ acym_query('UPDATE #__acym_list SET welcome_id = null WHERE welcome_id IN ('.implode(',', $elements).')');
+ acym_query('UPDATE #__acym_list SET unsubscribe_id = null WHERE unsubscribe_id IN ('.implode(',', $elements).')');
+ acym_query('DELETE FROM #__acym_queue WHERE mail_id IN ('.implode(',', $elements).')');
+ acym_query('DELETE FROM #__acym_mail_has_list WHERE mail_id IN ('.implode(',', $elements).')');
+ acym_query('DELETE FROM #__acym_tag WHERE `type` = "mail" AND `id_element` IN ('.implode(',', $elements).')');
+ acym_query('DELETE FROM #__acym_user_stat WHERE mail_id IN ('.implode(',', $elements).')');
+ acym_query('DELETE FROM #__acym_url_click WHERE mail_id IN ('.implode(',', $elements).')');
+ acym_query('DELETE FROM #__acym_mail_stat WHERE mail_id IN ('.implode(',', $elements).')');
+
+ return parent::delete($elements);
+ }
+
+ public function deleteMediaFolder($elements)
+ {
+ if (empty($elements)) return;
+
+ acym_arrayToInteger($elements);
+ $results = acym_loadResultArray('SELECT media_folder FROM #__acym_mail WHERE id IN ('.implode(',', $elements).')');
+
+ foreach ($results as $template) {
+ if (empty($template) || !file_exists(ACYM_TEMPLATE.$template)) continue;
+ acym_deleteFolder(ACYM_TEMPLATE.$template);
+ }
+ }
+
+ public function deleteOneAttachment($mailid, $idAttachment)
+ {
+ $mailid = intval($mailid);
+ if (empty($mailid)) {
+ return false;
+ }
+ $mail = $this->getOneById($mailid);
+
+ $attachments = $mail->attachments;
+ if (empty($attachments)) {
+ return false;
+ }
+ $decodedAttach = json_decode($attachments, true);
+ unset($decodedAttach[$idAttachment]);
+ $attachdb = json_encode($decodedAttach);
+
+ return acym_query('UPDATE #__acym_mail SET attachments = '.acym_escapeDB($attachdb).' WHERE id = '.intval($mailid).' LIMIT 1');
+ }
+
+ public function createTemplateFile($id)
+ {
+ if (empty($id)) {
+ return '';
+ }
+ $cssfile = ACYM_TEMPLATE.'css'.DS.'template_'.$id.'.css';
+
+ $template = $this->getOneById($id);
+ if (empty($template->id)) {
+ return '';
+ }
+ $css = $this->buildCSS($template->stylesheet);
+
+ if (empty($css)) {
+ return '';
+ }
+
+ acym_createDir(ACYM_TEMPLATE.'css');
+
+ if (acym_writeFile($cssfile, $css)) {
+ return $cssfile;
+ } else {
+ acym_enqueueNotification('Could not create the file '.$cssfile, 'error');
+
+ return '';
+ }
+ }
+
+ public function buildCSS($stylesheet)
+ {
+ $inline = '';
+
+ if (preg_match_all('#@import[^;]*;#is', $stylesheet, $results)) {
+ foreach ($results[0] as $oneResult) {
+ $inline .= trim($oneResult)."\n";
+ $stylesheet = str_replace($oneResult, '', $stylesheet);
+ }
+ }
+
+ $inline .= $stylesheet;
+
+ return $inline;
+ }
+
+ public function getAllTemplatesForSelect()
+ {
+ $query = 'SELECT `id`, `subject`, `name` FROM #__acym_mail WHERE `template` IN(0, 2) AND `name` != "acy_report"';
+
+ $mails = $this->decode(acym_loadObjectList($query, 'id'));
+
+ $return = [];
+ $return[] = acym_translation('ACYM_SELECT_A_MAIL');
+ $return[-1] = acym_translation('ACYM_ALL_MAILS');
+
+ foreach ($mails as $id => $mail) {
+ $return[$id] = empty($mail->subject) ? $mail->name : $mail->subject;
+ }
+
+ return $return;
+ }
+
+ function doupload()
+ {
+ $importFile = acym_getVar('none', 'uploadedfile', '', 'files');
+
+ $fileError = $importFile['error'];
+ if ($fileError > 0) {
+ switch ($fileError) {
+ case 1:
+ acym_enqueueNotification(acym_translation_sprintf('ACYM_FILE_UPLOAD_ERROR_1'), 'error');
+
+ return false;
+ case 2:
+ acym_enqueueNotification(acym_translation_sprintf('ACYM_FILE_UPLOAD_ERROR_2'), 'error');
+
+ return false;
+ case 3:
+ acym_enqueueNotification(acym_translation_sprintf('ACYM_FILE_UPLOAD_ERROR_3'), 'error');
+
+ return false;
+ case 4:
+ acym_enqueueNotification(acym_translation_sprintf('ACYM_FILE_UPLOAD_ERROR_4'), 'error');
+
+ return false;
+ default:
+ acym_enqueueNotification(acym_translation_sprintf('ACYM_FILE_UPLOAD_ERROR_5', $fileError), 'error');
+
+ return false;
+ }
+ }
+ if (empty($importFile['name'])) {
+ acym_enqueueNotification(acym_translation('ACYM_BROWSE_FILE'), 'error');
+
+ return false;
+ }
+
+ $uploadPath = acym_cleanPath(ACYM_ROOT.ACYM_MEDIA_FOLDER.DS.'templates');
+
+ if (!is_writable($uploadPath)) {
+ @chmod($uploadPath, '0755');
+ if (!is_writable($uploadPath)) {
+ acym_enqueueNotification(acym_translation_sprintf('ACYM_WRITABLE_FOLDER', $uploadPath), 'warning');
+ }
+ }
+
+ if (!(bool)ini_get('file_uploads')) {
+ acym_enqueueNotification(acym_translation_sprintf('ACYM_FILE_UPLOAD_ERROR_6'), 'error');
+
+ return false;
+ }
+
+ if (!extension_loaded('zlib')) {
+ acym_raiseError(E_WARNING, 'SOME_ERROR_CODE', acym_translation('WARNINSTALLZLIB'));
+
+ return false;
+ }
+
+ $filename = strtolower(acym_makeSafeFile($importFile['name']));
+ $extension = strtolower(substr($filename, strrpos($filename, '.') + 1));
+
+ if (!in_array($extension, ['zip', 'tar.gz'])) {
+ acym_enqueueNotification(acym_translation_sprintf('ACYM_ACCEPTED_TYPE', $extension, 'zip,tar.gz'), 'error');
+
+ return false;
+ }
+
+ $jpath = acym_getCMSConfig('tmp_path', ACYM_MEDIA.'tmp'.DS);
+ $tmp_dest = acym_cleanPath($jpath.DS.$filename);
+ $tmp_src = $importFile['tmp_name'];
+
+ $uploaded = acym_uploadFile($tmp_src, $tmp_dest);
+ if (!$uploaded) {
+ acym_enqueueNotification(acym_translation_sprintf('ACYM_FILE_UPLOAD_ERROR_7', $tmp_src, $tmp_dest), 'error');
+
+ return false;
+ }
+
+ $tmpdir = uniqid().'_template';
+
+ $extractdir = acym_cleanPath(dirname($tmp_dest).DS.$tmpdir);
+
+ $result = acym_extractArchive($tmp_dest, $extractdir);
+ acym_deleteFile($tmp_dest);
+
+ $allFiles = acym_getFiles($extractdir, '.', true, true, [], []);
+ foreach ($allFiles as $oneFile) {
+ if (preg_match('#\.(jpg|gif|png|jpeg|ico|bmp|html|htm|css)$#i', $oneFile)) {
+ continue;
+ }
+ if (acym_deleteFile($oneFile)) {
+ acym_enqueueNotification(acym_translation_sprintf('ACYM_FILE_UPLOAD_ERROR_8', $oneFile), 'warning');
+ }
+ }
+
+ if (!$result) {
+ acym_enqueueNotification(acym_translation_sprintf('ACYM_FILE_UPLOAD_ERROR_9', $tmp_dest, $extractdir), 'error');
+
+ return false;
+ }
+
+ if ($this->detecttemplates($extractdir)) {
+
+ $messages = $this->templateNames;
+ array_unshift($messages, acym_translation_sprintf('ACYM_TEMPLATES_INSTALL', count($this->templateNames)));
+ acym_enqueueNotification($messages, 'success');
+ if (is_dir($extractdir)) acym_deleteFolder($extractdir);
+
+ return true;
+ }
+
+ acym_enqueueNotification(acym_translation_sprintf('ACYM_FILE_UPLOAD_ERROR_10'), 'error');
+ if (is_dir($extractdir)) acym_deleteFolder($extractdir);
+
+ return false;
+ }
+
+ function detecttemplates($folder)
+ {
+ $allFiles = acym_getFiles($folder);
+ if (!empty($allFiles)) {
+ foreach ($allFiles as $oneFile) {
+ if (preg_match('#^.*(html|htm)$#i', $oneFile)) {
+ if ($this->installtemplate($folder.DS.$oneFile)) return true;
+ }
+ }
+ }
+
+ $status = false;
+ $allFolders = acym_getFolders($folder);
+ if (!empty($allFolders)) {
+ foreach ($allFolders as $oneFolder) {
+ $status = $this->detecttemplates($folder.DS.$oneFolder) || $status;
+ }
+ }
+
+ return $status;
+ }
+
+ function installtemplate($filepath)
+ {
+ $fileContent = acym_fileGetContent($filepath);
+
+ $newTemplate = new stdClass();
+ $newTemplate->name = trim(preg_replace('#[^a-z0-9]#i', ' ', substr(dirname($filepath), strpos($filepath, '_template'))));
+ if (preg_match('#< *title[^>]*>(.*)< */ *title *>#Uis', $fileContent, $results) && !empty($results[1])) $newTemplate->name = $results[1];
+
+ if (preg_match('#< *meta *name="description" *content="([^"]*)"#Uis', $fileContent, $results) && !empty($results[1])) $newTemplate->description = $results[1];
+ if (preg_match('#< *meta *name="fromname" *content="([^"]*)"#Uis', $fileContent, $results) && !empty($results[1])) $newTemplate->fromname = $results[1];
+ if (preg_match('#< *meta *name="fromemail" *content="([^"]*)"#Uis', $fileContent, $results) && !empty($results[1])) $newTemplate->fromemail = $results[1];
+ if (preg_match('#< *meta *name="replyname" *content="([^"]*)"#Uis', $fileContent, $results) && !empty($results[1])) $newTemplate->replyname = $results[1];
+ if (preg_match('#< *meta *name="replyemail" *content="([^"]*)"#Uis', $fileContent, $results) && !empty($results[1])) $newTemplate->replyemail = $results[1];
+
+ $newFolder = preg_replace('#[^a-z0-9]#i', '_', strtolower($newTemplate->name));
+ $newTemplateFolder = $newFolder;
+ $i = 1;
+ while (is_dir(ACYM_TEMPLATE.$newTemplateFolder)) {
+ $newTemplateFolder = $newFolder.'_'.$i;
+ $i++;
+ }
+ $newTemplate->media_folder = $newTemplateFolder;
+
+ $moveResult = acym_copyFolder(dirname($filepath), ACYM_TEMPLATE.$newTemplateFolder);
+ if ($moveResult !== true) {
+ acym_display([acym_translation_sprintf('ACYM_ERROR_COPYING_FOLDER_TO', dirname($filepath), ACYM_TEMPLATE.$newTemplateFolder), $moveResult], 'error');
+
+ return false;
+ }
+
+ if (!file_exists(ACYM_TEMPLATE.$newTemplateFolder.DS.'index.html')) {
+ $indexFile = '';
+ acym_writeFile(ACYM_TEMPLATE.$newTemplateFolder.DS.'index.html', $indexFile);
+ }
+
+ $fileContent = str_replace(
+ [
+ 'src="./',
+ 'src="../',
+ 'src="images/',
+ ],
+ [
+ 'src="'.ACYM_TEMPLATE_URL.$newTemplateFolder.'/',
+ 'src="'.ACYM_TEMPLATE_URL,
+ 'src="'.ACYM_TEMPLATE_URL.$newTemplateFolder.'/images/',
+ ],
+ $fileContent
+ );
+
+ $fileContent = preg_replace('#(src|background)[ ]*=[ ]*\"(?!(https?://|/))(?:\.\./|\./)?#', '$1="'.ACYM_TEMPLATE_URL.$newTemplateFolder.'/', $fileContent);
+
+ if (preg_match('#< *body[^>]*>(.*)< */ *body *>#Uis', $fileContent, $results)) {
+ $newTemplate->body = $results[1];
+ } else {
+ $newTemplate->body = $fileContent;
+ }
+
+ $newTemplate->stylesheet = '';
+ if (preg_match_all('#< *style[^>]*>(.*)< */ *style *>#Uis', $fileContent, $results)) {
+ $newTemplate->stylesheet .= preg_replace('#()#s', '', implode("\n", $results[1]));
+ }
+ $cssFiles = [];
+ $cssFiles[ACYM_TEMPLATE.$newTemplateFolder] = acym_getFiles(ACYM_TEMPLATE.$newTemplateFolder, '\.css$');
+ $subFolders = acym_getFolders(ACYM_TEMPLATE.$newTemplateFolder);
+ foreach ($subFolders as $oneFolder) {
+ $cssFiles[ACYM_TEMPLATE.$newTemplateFolder.DS.$oneFolder] = acym_getFiles(ACYM_TEMPLATE.$newTemplateFolder.DS.$oneFolder, '\.css$');
+ }
+
+ foreach ($cssFiles as $cssFolder => $cssFile) {
+ if (empty($cssFile)) continue;
+ $newTemplate->stylesheet .= "\n".acym_fileGetContent($cssFolder.DS.reset($cssFile));
+ }
+
+ if (!empty($newTemplate->stylesheet)) {
+ if (preg_match('#body *\{[^\}]*background-color:([^;\}]*)[;\}]#Uis', $newTemplate->stylesheet, $backgroundresults)) {
+ $newTemplate->stylesheet = preg_replace('#(body *\{[^\}]*)background-color:[^;\}]*[;\}]#Uis', '$1', $newTemplate->stylesheet);
+ }
+
+ $quickstyle = ['tag_h1' => 'h1', 'tag_h2' => 'h2', 'tag_h3' => 'h3', 'tag_h4' => 'h4', 'tag_h5' => 'h5', 'tag_h6' => 'h6', 'tag_a' => 'a', 'tag_ul' => 'ul', 'tag_li' => 'li', 'acym_unsub' => '\.acym_unsub', 'acym_online' => '\.acym_online', 'acym_title' => '\.acym_title', 'acym_content' => '\.acym_content', 'acym_readmore' => '\.acym_readmore'];
+ foreach ($quickstyle as $styledb => $oneStyle) {
+ if (preg_match('#[^a-z\. ,] *'.$oneStyle.' *{([^}]*)}#Uis', $newTemplate->stylesheet, $quickstyleresults)) {
+ $newTemplate->stylesheet = str_replace($quickstyleresults[0], '', $newTemplate->stylesheet);
+ }
+ }
+ }
+
+ $foldersForPicts = [$newTemplateFolder];
+ $otherFolders = acym_getFolders(ACYM_TEMPLATE.$newTemplateFolder);
+ foreach ($otherFolders as $oneFold) {
+ $foldersForPicts[] = $newTemplateFolder.DS.$oneFold;
+ }
+ $allPictures = [];
+ foreach ($foldersForPicts as $oneFolder) {
+ $allPictures[$oneFolder] = acym_getFiles(ACYM_TEMPLATE.$oneFolder);
+ }
+
+ $uploadsFolder = ACYM_UPLOAD_FOLDER_THUMBNAIL;
+
+ $config = acym_config();
+ $newConfig = new stdClass();
+ $thumbNb = intval($config->get('numberThumbnail', 2));
+
+ foreach ($allPictures as $folder => $pictfolders) {
+ foreach ($pictfolders as $onePict) {
+ if (!preg_match('#\.(jpg|gif|png|jpeg|ico|bmp)$#i', $onePict)) continue;
+ if (preg_match('#(thumbnail|screenshot|muestra)#i', $onePict)) {
+ $thumbNb++;
+ $newNamePict = 'thumbnail_'.$thumbNb.'.png';
+ copy(ACYM_TEMPLATE.str_replace(DS, '/', $folder).'/'.$onePict, $uploadsFolder.$newNamePict);
+ $newTemplate->thumbnail = $newNamePict;
+ }
+ }
+ }
+
+ $newConfig->numberThumbnail = $thumbNb;
+ $config->save($newConfig);
+
+ $newTemplate->drag_editor = 0;
+ $newTemplate->type = "standard";
+ $newTemplate->template = 1;
+ $newTemplate->library = 0;
+ $newTemplate->creation_date = acym_date('now', 'Y-m-d H:i:s', false);
+
+ $tempid = $this->save($newTemplate);
+
+ $this->templateId = $tempid;
+ $this->templateNames[] = $newTemplate->name;
+
+ return true;
+ }
+
+ public function sendAutomation($mailId, $userIds, $sendingDate, $automationAdmin = [])
+ {
+
+ if (empty($mailId)) return acym_translation_sprintf('ACYM_EMAILS_ADDED_QUEUE', 0);
+ if (empty($sendingDate)) return acym_translation('ACYM_WRONG_DATE');
+ if (empty($userIds)) return acym_translation('ACYM_USER_NOT_FOUND');
+ acym_arrayToInteger($userIds);
+
+ if (isset($automationAdmin['automationAdmin']) && $automationAdmin['automationAdmin']) {
+ $userClass = acym_get('class.user');
+ $mailerHelper = acym_get('helper.mailer');
+ $mail = $this->getOneById($mailId);
+ $user = $userClass->getOneById($automationAdmin['user_id']);
+
+ if (empty($mail) || empty($user)) return false;
+
+ $acympluginHelper = acym_get('helper.plugin');
+ $extractedTags = $acympluginHelper->extractTags($mail, 'subtag');
+ if (!empty($extractedTags)) {
+ foreach ($extractedTags as $dtext => $oneTag) {
+ if (empty($oneTag->info) || $oneTag->info != 'current' || empty($user->{$oneTag->id})) continue;
+
+ $mailerHelper->addParam(str_replace(['{', '}'], '', $dtext), $user->{$oneTag->id});
+ }
+ }
+
+ $mailSent = 0;
+
+ foreach ($userIds as $userId) {
+ if ($mailerHelper->sendOne($mail->id, $userId)) $mailSent++;
+ }
+
+ return $mailSent;
+ }
+
+ $result = acym_query(
+ 'INSERT IGNORE INTO #__acym_queue (`mail_id`, `user_id`, `sending_date`)
+ SELECT '.intval($mailId).', user.id, '.acym_escapeDB($sendingDate).'
+ FROM #__acym_user AS user
+ WHERE user.active = 1 AND user.id IN ('.implode(',', $userIds).')'
+ );
+
+
+ $mailStatClass = acym_get('class.mailstat');
+ $mailStat = $mailStatClass->getOneRowByMailId($mailId);
+
+ if (empty($mailStat)) {
+ $mailStat = new stdClass();
+ $mailStat->mail_id = intval($mailId);
+ $mailStat->total_subscribers = intval($result);
+ $mailStat->send_date = $sendingDate;
+ } else {
+ $mailStat->total_subscribers += intval($result);
+ }
+
+ unset($mailStat->sent);
+ $mailStatClass->save($mailStat);
+
+ if ($result === 0) {
+ return acym_translation('ACYM_CAMPAIGN_ALREADY_QUEUED');
+ }
+
+ return $result;
+ }
+
+ public function encode($mails = [])
+ {
+ $isArray = true;
+ if (!is_array($mails)) {
+ $mails = [$mails];
+
+ $isArray = false;
+ }
+
+ $return = array_map([$this, 'utf8Encode'], $mails);
+
+ return $isArray ? $return : $return[0];
+ }
+
+ public function decode($mails = [])
+ {
+ $isArray = true;
+ if (!is_array($mails)) {
+ $mails = [$mails];
+
+ $isArray = false;
+ }
+
+ $return = array_map([$this, 'utf8Decode'], $mails);
+
+ return $isArray ? $return : $return[0];
+ }
+
+ protected function utf8Decode($mail)
+ {
+ if (!empty($mail)) {
+ foreach (self::FIELDS_ENCODING as $oneField) {
+
+ if (is_array($mail)) {
+ if (empty($mail[$oneField])) continue;
+ $value = &$mail[$oneField];
+ } else {
+ if (empty($mail->$oneField)) continue;
+ $value = &$mail->$oneField;
+ }
+
+ $value = utf8_decode($value);
+ }
+ }
+
+ return $mail;
+ }
+
+ protected function utf8Encode($mail)
+ {
+ if (!empty($mail)) {
+ foreach (self::FIELDS_ENCODING as $oneField) {
+
+ if (is_array($mail)) {
+ if (empty($mail[$oneField])) continue;
+ $value = &$mail[$oneField];
+ } else {
+ if (empty($mail->$oneField)) continue;
+ $value = &$mail->$oneField;
+ }
+
+ $value = utf8_encode($value);
+ }
+ }
+
+ return $mail;
+ }
+}
+
diff --git a/deployed/acym/administrator/components/com_acym/classes/mailstat.php b/deployed/acym/administrator/components/com_acym/classes/mailstat.php
new file mode 100644
index 00000000..176f4162
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/classes/mailstat.php
@@ -0,0 +1,114 @@
+ $value) {
+ if (in_array($key, $columnName)) {
+ $column[] = '`'.acym_secureDBColumn($key).'`';
+ $valueColumn[] = acym_escapeDB($value);
+ }
+ }
+
+ $query = "#__acym_mail_stat (".implode(',', $column).") VALUES (".implode(',', $valueColumn).")";
+
+ $onDuplicate = [];
+
+ if (!empty($mailStat['sent'])) {
+ $onDuplicate[] = " sent = sent + ".intval($mailStat['sent']);
+ }
+
+ if (!empty($mailStat['fail'])) {
+ $onDuplicate[] = " fail = fail + ".intval($mailStat['fail']);
+ }
+
+ if (!empty($mailStat['open_unique'])) {
+ $onDuplicate[] = "open_unique = open_unique + 1";
+ }
+
+ if (!empty($mailStat['open_total'])) {
+ $onDuplicate[] = "open_total = open_total + 1";
+ }
+
+ if (!empty($mailStat['total_subscribers'])) {
+ $onDuplicate[] = "total_subscribers = ".intval($mailStat['total_subscribers']);
+ }
+
+ if (!empty($onDuplicate)) {
+ $query .= " ON DUPLICATE KEY UPDATE ";
+ $query .= implode(',', $onDuplicate);
+ $query = "INSERT INTO ".$query;
+ } else {
+ $query = "INSERT IGNORE INTO ".$query;
+ }
+
+ acym_query($query);
+ }
+
+ public function getTotalSubscribersByMailId($mailId)
+ {
+ $result = acym_loadResult("SELECT total_subscribers FROM #__acym_mail_stat WHERE mail_id = ".intval($mailId)." LIMIT 1");
+
+ return $result === null ? 0 : $result;
+ }
+
+ function getOneByMailId($id = '')
+ {
+ $query = 'SELECT SUM(sent) as sent, SUM(fail) as fail FROM #__acym_mail_stat';
+ $query .= empty($id) ? '' : ' WHERE `mail_id` = '.intval($id);
+
+ return acym_loadObject($query);
+ }
+
+ public function getAllFromMailIds($mailsIds = [])
+ {
+ acym_arrayToInteger($mailsIds);
+ if (empty($mailsIds)) {
+ $mailsIds[] = 0;
+ }
+
+ $result = acym_loadObjectList("SELECT * FROM #__acym_mail_stat WHERE mail_id IN (".implode(",", $mailsIds).")", "mail_id");
+
+ return $result === null ? 0 : $result;
+ }
+
+ public function getOneRowByMailId($mailId)
+ {
+ $query = 'SELECT * FROM #__acym_mail_stat WHERE mail_id = '.intval($mailId);
+
+ return acym_loadObject($query);
+ }
+
+ public function getAllMailsForStats()
+ {
+ $mailClass = acym_get('class.mail');
+
+ $query = 'SELECT mail.* FROM #__acym_mail_stat AS mail_stat LEFT JOIN #__acym_mail AS mail ON mail.id = mail_stat.mail_id';
+
+ return $mailClass->decode(acym_loadObjectList($query));
+ }
+
+}
+
diff --git a/deployed/acym/administrator/components/com_acym/classes/query.php b/deployed/acym/administrator/components/com_acym/classes/query.php
new file mode 100644
index 00000000..e8948c2b
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/classes/query.php
@@ -0,0 +1,135 @@
+from)) $query .= ' FROM '.$this->from;
+ if (!empty($this->join)) $query .= ' JOIN '.implode(' JOIN ', $this->join);
+ if (!empty($this->leftjoin)) $query .= ' LEFT JOIN '.implode(' LEFT JOIN ', $this->leftjoin);
+ if (!empty($this->where)) $query .= ' WHERE ('.implode(') AND (', $this->where).')';
+ if (!empty($this->orderBy)) $query .= ' ORDER BY '.$this->orderBy;
+ if (!empty($this->limit)) $query .= ' LIMIT '.$this->limit;
+
+ return $query;
+ }
+
+ public function count()
+ {
+ return acym_loadResult($this->getQuery(['COUNT(DISTINCT user.id)']));
+ }
+
+ public function addFlag($id)
+ {
+ if (!empty($this->orderBy) || !empty($this->limit)) {
+ $flagQuery = 'UPDATE #__acym_user';
+ $flagQuery .= ' SET automation = CONCAT(automation, "a'.intval($id).'a")';
+ $flagQuery .= ' WHERE id IN (
+ SELECT id FROM (SELECT user.id FROM #__acym_user AS user';
+ if (!empty($this->join)) $flagQuery .= ' JOIN '.implode(' JOIN ', $this->join);
+ if (!empty($this->leftjoin)) $flagQuery .= ' LEFT JOIN '.implode(' LEFT JOIN ', $this->leftjoin);
+ if (!empty($this->where)) $flagQuery .= ' WHERE ('.implode(') AND (', $this->where).')';
+ if (!empty($this->orderBy)) $flagQuery .= ' ORDER BY '.$this->orderBy;
+ if (!empty($this->limit)) $flagQuery .= ' LIMIT '.$this->limit;
+ $flagQuery .= ') tmp);';
+ } else {
+ $flagQuery = 'UPDATE #__acym_user AS user ';
+ if (!empty($this->join)) $flagQuery .= ' JOIN '.implode(' JOIN ', $this->join);
+ if (!empty($this->leftjoin)) $flagQuery .= ' LEFT JOIN '.implode(' LEFT JOIN ', $this->leftjoin);
+ $flagQuery .= ' SET user.automation = CONCAT(user.automation, "a'.intval($id).'a")';
+ if (!empty($this->where)) $flagQuery .= ' WHERE ('.implode(') AND (', $this->where).')';
+ }
+ acym_query($flagQuery);
+
+ $this->join = [];
+ $this->leftjoin = [];
+ $this->where = ['user.automation LIKE "%a'.intval($id).'a%"'];
+ $this->orderBy = '';
+ $this->limit = '';
+ }
+
+ public function removeFlag($id)
+ {
+ acym_query('UPDATE #__acym_user SET automation = REPLACE(automation, "a'.intval($id).'a", "") WHERE automation LIKE "%a'.intval($id).'a%"');
+ }
+
+ function convertQuery($table, $column, $operator, $value, $type = '')
+ {
+ $operator = str_replace(['<', '>'], ['<', '>'], $operator);
+
+ if ($operator == 'CONTAINS' || ($type == 'phone' && $operator == '=')) {
+ $operator = 'LIKE';
+ $value = '%'.$value.'%';
+ } elseif ($operator == 'BEGINS') {
+ $operator = 'LIKE';
+ $value = $value.'%';
+ } elseif ($operator == 'END') {
+ $operator = 'LIKE';
+ $value = '%'.$value;
+ } elseif ($operator == 'NOTCONTAINS' || ($type == 'phone' && $operator == '!=')) {
+ $operator = 'NOT LIKE';
+ $value = '%'.$value.'%';
+ } elseif ($operator == 'REGEXP') {
+ if ($value === '') return '1 = 1';
+ } elseif ($operator == 'NOT REGEXP') {
+ if ($value === '') return '0 = 1';
+ } elseif (!in_array($operator, ['IS NULL', 'IS NOT NULL', 'NOT LIKE', 'LIKE', '=', '!=', '>', '<', '>=', '<='])) {
+ die(acym_translation_sprintf('ACYM_UNKNOWN_OPERATOR', $operator));
+ }
+
+ if (strpos($value, '[time]') !== false) {
+ $value = acym_replaceDate($value);
+ $value = strftime('%Y-%m-%d %H:%M:%S', $value);
+ }
+
+ $replace = ['{year}', '{month}', '{weekday}', '{day}'];
+ $replaceBy = [date('Y'), date('m'), date('N'), date('d')];
+ $value = str_replace($replace, $replaceBy, $value);
+
+ if (preg_match_all('#{(year|month|weekday|day)\|(add|remove):([^}]*)}#Uis', $value, $results)) {
+
+ foreach ($results[0] as $i => $oneMatch) {
+ $format = str_replace(['year', 'month', 'weekday', 'day'], ['Y', 'm', 'N', 'd'], $results[1][$i]);
+ $delay = str_replace(['add', 'remove'], ['+', '-'], $results[2][$i]).intval($results[3][$i]).' '.str_replace('weekday', 'day', $results[1][$i]);
+ $value = str_replace($oneMatch, date($format, strtotime($delay)), $value);
+ }
+ }
+
+ if (!is_numeric($value) || in_array($operator, ['REGEXP', 'NOT REGEXP', 'NOT LIKE', 'LIKE', '=', '!='])) {
+ $value = acym_escapeDB($value);
+ }
+
+ if (in_array($operator, ['IS NULL', 'IS NOT NULL'])) {
+ $value = '';
+ }
+
+ if ($type == 'datetime' && in_array($operator, ['=', '!='])) {
+ return 'DATE_FORMAT('.acym_secureDBColumn($table).'.`'.acym_secureDBColumn($column).'`, "%Y-%m-%d") '.$operator.' '.'DATE_FORMAT('.$value.', "%Y-%m-%d")';
+ }
+ if ($type == 'timestamp' && in_array($operator, ['=', '!='])) {
+ return 'FROM_UNIXTIME('.acym_secureDBColumn($table).'.`'.acym_secureDBColumn($column).'`, "%Y-%m-%d") '.$operator.' '.'FROM_UNIXTIME('.$value.', "%Y-%m-%d")';
+ }
+
+ return acym_secureDBColumn($table).'.`'.acym_secureDBColumn($column).'` '.$operator.' '.$value;
+ }
+}
+
diff --git a/deployed/acym/administrator/components/com_acym/classes/queue.php b/deployed/acym/administrator/components/com_acym/classes/queue.php
new file mode 100644
index 00000000..e0c19e9a
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/classes/queue.php
@@ -0,0 +1,388 @@
+ 'campaign.active = 1 AND queue.mail_id IS NOT NULL',
+ 'paused' => 'campaign.active = 0',
+ 'scheduled' => 'campaign.active = 1 AND queue.mail_id IS NULL',
+ 'automation' => 'mail.type = '.acym_escapeDB('automation'),
+ ];
+
+ if (empty($allowedStatus[$settings['status']])) {
+ die('Unauthorized filter: '.$settings['status']);
+ }
+
+ $filters[] = $allowedStatus[$settings['status']];
+ }
+
+ if (!empty($filters)) {
+ $query .= ' WHERE ('.implode(') AND (', $filters).')';
+ }
+
+ $queryCount = 'SELECT COUNT(DISTINCT mail.id) '.$query;
+ $query .= ' GROUP BY mail.id';
+
+ $query = 'SELECT mail.name, mail.subject, mail.id, campaign.id AS campaign, IF(campaign.sending_date IS NULL, queue.sending_date, campaign.sending_date) as sending_date, campaign.scheduled, campaign.active, COUNT(queue.mail_id) AS nbqueued '.$query.' ORDER BY queue.sending_date ASC';
+
+ $mailClass = acym_get('class.mail');
+ $results['elements'] = $mailClass->decode(acym_loadObjectList($query, '', $settings['offset'], $settings['campaignsPerPage']));
+ $results['total'] = acym_loadResult($queryCount);
+
+ foreach ($results['elements'] as $i => $oneCampaign) {
+ if (empty($oneCampaign->campaign)) {
+ $results['elements'][$i]->iscampaign = false;
+ $results['elements'][$i]->lists = acym_translation('ACYM_MAIL_FROM_AUTOMATION_SENT_TO');
+ $results['elements'][$i]->recipients = acym_loadResult('SELECT COUNT(*) FROM #__acym_queue WHERE mail_id = '.intval($oneCampaign->id));
+ } else {
+ $results['elements'][$i]->iscampaign = true;
+ $results['elements'][$i]->lists = acym_loadObjectList(
+ 'SELECT l.color, l.name , l.id
+ FROM #__acym_list AS l
+ JOIN #__acym_mail_has_list AS ml ON ml.list_id = l.id
+ WHERE ml.mail_id = '.intval($oneCampaign->id)
+ );
+ $results['elements'][$i]->recipients = intval($mailStatClass->getTotalSubscribersByMailId($oneCampaign->id));
+ }
+ }
+
+ $automationNumber = acym_loadResult('SELECT COUNT(DISTINCT mail.id) FROM #__acym_mail as mail JOIN #__acym_queue AS queue ON mail.id = queue.mail_id WHERE mail.type = '.acym_escapeDB('automation'));
+
+ $elementsPerStatus = acym_loadObjectList($queryStatus.' GROUP BY score', 'score');
+ for ($i = 0 ; $i < 4 ; $i++) {
+ $elementsPerStatus[$i] = empty($elementsPerStatus[$i]) ? 0 : $elementsPerStatus[$i]->number;
+ }
+
+ $results['status'] = [
+ 'all' => array_sum($elementsPerStatus) + $automationNumber,
+ 'sending' => $elementsPerStatus[1],
+ 'paused' => $elementsPerStatus[0] + $elementsPerStatus[2],
+ 'scheduled' => $elementsPerStatus[3],
+ 'automation' => $automationNumber,
+ ];
+
+ return $results;
+ }
+
+ public function getMatchingResults($settings)
+ {
+ $query = 'FROM #__acym_queue AS queue
+ JOIN #__acym_mail AS mail ON mail.id = queue.mail_id
+ JOIN #__acym_user AS user ON queue.user_id = user.id ';
+
+ $filters = [];
+
+ if (!empty($settings['tag'])) {
+ $query .= ' JOIN #__acym_tag AS tag ON queue.mail_id = tag.id_element AND tag.type = "mail" AND tag.name = '.acym_escapeDB($settings['tag']);
+ }
+
+ if (!empty($settings['search'])) {
+ $filters[] = 'mail.subject LIKE '.acym_escapeDB('%'.$settings['search'].'%').' OR mail.name LIKE '.acym_escapeDB('%'.$settings['search'].'%');
+ }
+
+ if (!empty($filters)) {
+ $query .= ' WHERE ('.implode(') AND (', $filters).')';
+ }
+
+ if (!empty($settings['tag'])) {
+ $query .= ' GROUP BY queue.mail_id, queue.user_id';
+ }
+
+ $queryCount = 'SELECT COUNT(queue.mail_id) '.$query;
+ $query = 'SELECT mail.id, queue.sending_date, mail.name, mail.subject, user.email, user.name AS user_name, queue.user_id, queue.try '.$query.' ORDER BY queue.sending_date ASC';
+
+ $mailClass = acym_get('class.mail');
+ $results['elements'] = $mailClass->decode(acym_loadObjectList($query, '', $settings['offset'], $settings['elementsPerPage']));
+ $results['total'] = acym_loadResult($queryCount);
+
+ return $results;
+ }
+
+ public function scheduleReady()
+ {
+ $this->messages = [];
+
+ $mailClass = acym_get('class.mail');
+ $mailReady = $mailClass->decode(
+ acym_loadObjectList(
+ 'SELECT mail.id, campaign.sending_date, mail.name
+ FROM #__acym_campaign AS campaign
+ JOIN #__acym_mail AS mail
+ ON campaign.mail_id = mail.id
+ WHERE campaign.scheduled = 1
+ AND campaign.draft = 0
+ AND campaign.sending_date <= '.acym_escapeDB(acym_date('now', 'Y-m-d H:i:s', false)).'
+ AND campaign.sent = 0',
+ 'id'
+ )
+ );
+
+
+ if (empty($mailReady)) {
+ return false;
+ }
+
+ foreach ($mailReady as $mailid => $mail) {
+ $nbQueue = $this->queue($mailid, $mail->sending_date);
+ $this->messages[] = acym_translation_sprintf('ACYM_ADDED_QUEUE_SCHEDULE', $nbQueue, ''.$mail->name.' ');
+ }
+
+ $mailIds = array_keys($mailReady);
+ acym_arrayToInteger($mailIds);
+ $campaignsIDs = acym_loadResultArray('SELECT id FROM #__acym_campaign WHERE mail_id IN ('.implode(',', $mailIds).')');
+ $campaignClass = acym_get('class.campaign');
+ foreach ($campaignsIDs as $campaignID) {
+ $campaignClass->send($campaignID, $nbQueue);
+ }
+
+ return count($mailReady);
+ }
+
+ public function delete($elements)
+ {
+ if (!is_array($elements)) {
+ $elements = [$elements];
+ }
+
+ if (empty($elements)) {
+ return 0;
+ }
+
+ acym_arrayToInteger($elements);
+
+ $query = 'DELETE FROM #__acym_queue WHERE mail_id IN ('.implode(',', $elements).')';
+ $result = acym_query($query);
+
+ acym_query('UPDATE #__acym_campaign SET draft = 1, active = 1 WHERE mail_id IN ('.implode(',', $elements).')');
+
+ if (!$result) {
+ return false;
+ }
+
+ return $result;
+ }
+
+ public function deleteOne($elements, $mailId = null)
+ {
+ if (!is_array($elements)) {
+ $elements = [$elements];
+ }
+
+ if (empty($elements)) {
+ return 0;
+ }
+
+ $nbDeleted = 0;
+ foreach ($elements as $one) {
+ if (strpos($one, '_')) {
+ list($mailId, $userId) = explode('_', $one);
+ } else {
+ $userId = $one;
+ }
+
+ $query = 'DELETE FROM #__acym_queue WHERE user_id = '.intval($userId);
+ if (!empty($mailId)) {
+ $query .= ' AND mail_id = '.intval($mailId);
+ }
+
+ $res = acym_query($query);
+ if ($res === false) {
+ $this->errors[] = acym_getDBError();
+ } else {
+ $nbDeleted += $res;
+ }
+ }
+
+ return $res;
+ }
+
+ public function getReady($limit, $mailid = 0)
+ {
+ if (empty($limit)) {
+ return [];
+ }
+
+ $config = acym_config();
+ $order = $config->get('sendorder');
+ if (empty($order)) {
+ $order = 'queue.`user_id` ASC';
+ } else {
+ if ($order == 'rand') {
+ $order = 'RAND()';
+ } else {
+ $ordering = explode(',', $order);
+ $order = 'queue.`'.acym_secureDBColumn(trim($ordering[0])).'` '.acym_secureDBColumn(trim($ordering[1]));
+ }
+ }
+
+ $query = 'SELECT queue.* FROM #__acym_queue AS queue';
+ $query .= ' JOIN #__acym_user AS user ON queue.`user_id` = user.`id` ';
+ $query .= ' JOIN #__acym_mail AS mail ON queue.`mail_id` = mail.`id` ';
+ $query .= ' LEFT JOIN #__acym_campaign AS campaign ON campaign.`mail_id` = mail.`id` ';
+ $query .= ' WHERE queue.`sending_date` <= '.acym_escapeDB(acym_date('now', 'Y-m-d H:i:s', false)).' AND (campaign.mail_id IS NULL OR (campaign.`active` = 1 AND campaign.`draft` = 0 AND user.active = 1))';
+
+ if ($config->get('require_confirmation', 1) == 1) {
+ $query .= ' AND (user.confirmed = 1 OR mail.type = "notification")';
+ }
+
+ if (!empty($this->emailtypes)) {
+ foreach ($this->emailtypes as &$oneType) {
+ $oneType = acym_escapeDB($oneType);
+ }
+ $query .= ' AND (mail.type = '.implode(' OR mail.type = ', $this->emailtypes).')';
+ }
+ if (!empty($mailid)) {
+ $query .= ' AND queue.`mail_id` = '.intval($mailid);
+ }
+ $query .= ' ORDER BY queue.`priority` ASC, queue.`sending_date` ASC, '.$order;
+ $startqueue = acym_getVar('int', 'startqueue', 0);
+ $query .= ' LIMIT '.intval($startqueue).','.intval($limit);
+ try {
+ $results = acym_loadObjectList($query);
+ } catch (Exception $e) {
+ $results = null;
+ }
+
+ if ($results === null) {
+ acym_query('REPAIR TABLE #__acym_queue, #__acym_user, #__acym_mail, #__acym_campaign');
+ }
+
+ if (empty($results)) {
+ return [];
+ }
+
+ if (!empty($results)) {
+ $firstElementQueued = reset($results);
+ acym_query('UPDATE #__acym_queue SET sending_date = DATE_ADD(sending_date, INTERVAL 1 SECOND) WHERE mail_id = '.intval($firstElementQueued->mail_id).' AND user_id = '.intval($firstElementQueued->user_id).' LIMIT 1');
+ }
+
+ $userIds = [];
+ foreach ($results as $oneRes) {
+ $userIds[$oneRes->user_id] = intval($oneRes->user_id);
+ }
+
+ $cleanQueue = false;
+ if (!empty($userIds)) {
+ $allusers = acym_loadObjectList('SELECT * FROM #__acym_user WHERE id IN ('.implode(',', $userIds).')', 'id');
+ foreach ($results as $oneId => $oneRes) {
+ if (empty($allusers[$oneRes->user_id])) {
+ $cleanQueue = true;
+ continue;
+ }
+ foreach ($allusers[$oneRes->user_id] as $oneVar => $oneVal) {
+ $results[$oneId]->$oneVar = $oneVal;
+ }
+ }
+ }
+
+ if ($cleanQueue) {
+ acym_query('DELETE queue.* FROM #__acym_queue AS queue LEFT JOIN #__acym_user AS user ON queue.user_id = user.id WHERE user.id IS NULL');
+ }
+
+ return $results;
+ }
+
+ public function delayFailed($mailId, $userIds)
+ {
+ acym_arrayToInteger($userIds);
+ if (empty($mailId) || empty($userIds)) {
+ return false;
+ }
+
+ return acym_query(
+ 'UPDATE #__acym_queue
+ SET sending_date = DATE_ADD(sending_date, INTERVAL 1 HOUR), try = try +1
+ WHERE mail_id = '.intval($mailId).'
+ AND user_id IN ('.implode(',', $userIds).')'
+ );
+ }
+
+ private function queue($mailId, $sending_date)
+ {
+ $config = acym_config();
+ $priority = $config->get('priority_newsletter', 3);
+
+
+ return acym_query(
+ 'INSERT IGNORE INTO #__acym_queue
+ SELECT '.intval($mailId).', userlist.user_id, '.acym_escapeDB($sending_date).', '.intval($priority).', 0
+ FROM #__acym_user_has_list AS userlist
+ JOIN #__acym_mail_has_list AS maillist ON userlist.list_id = maillist.list_id
+ WHERE userlist.status = 1 AND maillist.mail_id = '.intval($mailId)
+ );
+ }
+
+ public function addQueue($userId, $mailId, $sendingDate)
+ {
+ $config = acym_config();
+ $priority = $config->get('priority_newsletter', 3);
+
+ return acym_query('INSERT IGNORE INTO #__acym_queue VALUES ('.intval($mailId).', '.intval($userId).', '.intval($sendingDate).', '.intval($priority).')');
+ }
+
+ public function unpauseCampaign($campaignId, $active)
+ {
+ if (acym_query('UPDATE #__acym_campaign SET active = '.intval($active).' WHERE id = '.intval($campaignId))) {
+ acym_enqueueNotification(acym_translation($active ? 'ACYM_UNPAUSE_CAMPAIGN_SUCCESSFUL' : 'ACYM_PAUSE_CAMPAIGN_SUCCESSFUL'), "success", 10000);
+ } else {
+ acym_enqueueNotification(acym_translation($active ? 'ACYM_UNPAUSE_CAMPAIGN_FAIL' : 'ACYM_PAUSE_CAMPAIGN_FAIL'), "error", 10000);
+ }
+ }
+
+ public function removeUnconfirmedUsersEmails()
+ {
+ return acym_query(
+ 'DELETE `queue`.*
+ FROM `#__acym_queue` AS `queue`
+ JOIN `#__acym_user` AS `user` ON `queue`.`user_id` = `user`.`id`
+ WHERE `user`.`confirmed` = 0 OR `user`.`active` = 0'
+ );
+ }
+
+ public function emptyQueue()
+ {
+ return acym_query('DELETE FROM `#__acym_queue`');
+ }
+}
+
diff --git a/deployed/acym/administrator/components/com_acym/classes/rule.php b/deployed/acym/administrator/components/com_acym/classes/rule.php
new file mode 100644
index 00000000..662358e2
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/classes/rule.php
@@ -0,0 +1,63 @@
+ $rule) {
+ $rules[$i] = $this->_prepareRule($rule);
+ }
+
+ return $rules;
+ }
+
+ public function getOneById($id)
+ {
+ $rule = acym_loadObject('SELECT * FROM `#__acym_rule` WHERE `id` = '.intval($id).' LIMIT 1');
+
+ return $this->_prepareRule($rule);
+ }
+
+ private function _prepareRule($rule)
+ {
+ $columns = ['executed_on', 'action_message', 'action_user'];
+ foreach ($columns as $oneColumn) {
+ if (!empty($rule->$oneColumn)) {
+ $rule->$oneColumn = json_decode($rule->$oneColumn, true);
+ }
+ }
+
+ return $rule;
+ }
+
+ public function save($rule)
+ {
+ if (empty($rule)) {
+ return false;
+ }
+
+ return parent::save($rule);
+ }
+
+ public function delete($ids)
+ {
+ return parent::delete($ids);
+ }
+}
+
diff --git a/deployed/acym/administrator/components/com_acym/classes/step.php b/deployed/acym/administrator/components/com_acym/classes/step.php
new file mode 100644
index 00000000..fee279bd
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/classes/step.php
@@ -0,0 +1,71 @@
+ $value) {
+ if (empty($value)) continue;
+ if (is_array($value)) $value = json_encode($value);
+
+ $step->$oneAttribute = strip_tags($value);
+ }
+
+ return parent::save($step);
+ }
+
+ public function getOneStepByAutomationId($automationId)
+ {
+ return acym_loadObject('SELECT * FROM #__acym_step WHERE automation_id = '.intval($automationId));
+ }
+
+ public function getOneById($id)
+ {
+ return acym_loadObject('SELECT * FROM #__acym_step WHERE id = '.intval($id));
+ }
+
+ public function getStepsByAutomationId($automationId)
+ {
+ return acym_loadObjectList('SELECT * FROM #__acym_step WHERE automation_id = '.intval($automationId));
+ }
+
+ public function getActiveStepByTrigger($trigger)
+ {
+ return acym_loadObjectList(
+ 'SELECT step.*
+ FROM #__acym_step AS step
+ LEFT JOIN #__acym_automation AS automation ON step.automation_id = automation.id
+ WHERE step.triggers LIKE '.acym_escapeDB('%"'.$trigger.'"%').' AND automation.active = 1'
+ );
+ }
+
+ public function delete($elements)
+ {
+ if (!is_array($elements)) $elements = [$elements];
+ acym_arrayToInteger($elements);
+
+ if (empty($elements)) return 0;
+
+ $conditions = acym_loadResultArray('SELECT id FROM #__acym_condition WHERE step_id IN ('.implode(',', $elements).')');
+ $conditionClass = acym_get('class.condition');
+ $conditionsDeleted = $conditionClass->delete($conditions);
+
+ return parent::delete($elements);
+ }
+}
+
diff --git a/deployed/acym/administrator/components/com_acym/classes/tag.php b/deployed/acym/administrator/components/com_acym/classes/tag.php
new file mode 100644
index 00000000..030cb4be
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/classes/tag.php
@@ -0,0 +1,73 @@
+type = $type;
+
+ if (strpos($oneTag, "acy_new_tag_") !== false) {
+ $tagName = substr($oneTag, strlen("acy_new_tag_"));
+ if (empty($tagName)) {
+ continue;
+ }
+ $newTag->name = $tagName;
+ } else {
+ $newTag->name = $oneTag;
+ }
+ $tagsToInsertQuery[] = '('.acym_escapeDB($newTag->name).','.acym_escapeDB($newTag->type).', '.intval($elementId).')';
+ }
+ if (!empty($tagsToInsertQuery)) {
+ acym_query('INSERT INTO #__acym_tag (`name`, `type`, `id_element`) VALUES '.implode(',', $tagsToInsertQuery));
+ }
+ }
+
+ public function getAllTagsByType($type)
+ {
+ $query = 'SELECT `name` as value, `name` FROM #__acym_tag WHERE `type` = '.acym_escapeDB($type).' GROUP BY `name`';
+
+ return acym_loadObjectList($query);
+ }
+
+ public function getAllTagsByElementId($type, $id)
+ {
+ $query = 'SELECT * FROM #__acym_tag WHERE type = '.acym_escapeDB($type).' AND id_element = '.intval($id);
+ $tags = acym_loadResultArray($query);
+
+ return empty($tags) ? [] : $tags;
+ }
+
+ public function getAllTagsByTypeAndElementIds($type, $ids)
+ {
+ acym_arrayToInteger($ids);
+ if (empty($ids)) {
+ return [];
+ }
+
+ $query = 'SELECT * FROM #__acym_tag WHERE `type` = '.acym_escapeDB($type).' AND `id_element` IN ('.implode(',', $ids).')';
+
+ return acym_loadObjectList($query);
+ }
+}
+
diff --git a/deployed/acym/administrator/components/com_acym/classes/url.php b/deployed/acym/administrator/components/com_acym/classes/url.php
new file mode 100644
index 00000000..b74ff6b9
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/classes/url.php
@@ -0,0 +1,86 @@
+ $value) {
+ if (empty($value)) {
+ continue;
+ }
+
+ $url->$oneAttribute = strip_tags($value);
+ }
+
+ return parent::save($url);
+ }
+
+ public function getOneUrlById($id)
+ {
+ $query = 'SELECT * from #__acym_url WHERE id = '.intval($id);
+
+ return acym_loadObject($query);
+ }
+
+ public function get($url)
+ {
+ $column = is_numeric($url) ? 'id' : 'url';
+ $query = 'SELECT * FROM #__acym_url WHERE '.$column.' = '.acym_escapeDB($url).' LIMIT 1';
+
+ return acym_loadObject($query);
+ }
+
+ public function getAdd($url)
+ {
+ $currentUrl = $this->get($url);
+ if (empty($currentUrl->id)) {
+ $currentUrl = new stdClass();
+ $currentUrl->name = $url;
+ $currentUrl->url = $url;
+ $currentUrl->id = $this->save($currentUrl);
+
+ if (empty($currentUrl->id)) {
+ return;
+ }
+ }
+
+ return $currentUrl;
+ }
+
+ public function getUrl($url, $mailid, $userid)
+ {
+
+ if (empty($url) || empty($mailid) || empty($userid)) {
+ return;
+ }
+
+ static $allurls;
+
+ $url = str_replace('&', '&', $url);
+
+ if (empty($allurls[$url])) {
+ $currentUrl = $this->getAdd($url);
+
+ $allurls[$url] = acym_frontendLink('fronturl&action=acymailing_frontrouter&task=click&urlid='.$currentUrl->id.'&userid='.$userid.'&mailid='.$mailid);
+ }
+
+ return $allurls[$url];
+ }
+}
diff --git a/deployed/acym/administrator/components/com_acym/classes/urlclick.php b/deployed/acym/administrator/components/com_acym/classes/urlclick.php
new file mode 100644
index 00000000..dcaabcf0
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/classes/urlclick.php
@@ -0,0 +1,124 @@
+ $value) {
+ if (in_array($key, $columnName)) {
+ $column[] = '`'.acym_secureDBColumn($key).'`';
+ $valueColumn[] = acym_escapeDB($value);
+ }
+ }
+
+ $query = "#__acym_url_click (".implode(',', $column).") VALUES (".implode(',', $valueColumn).")";
+
+ $onDuplicate = [];
+
+ if (!empty($urlClick['click'])) {
+ $onDuplicate[] = "click = click + 1";
+ $automationClass = acym_get('class.automation');
+ $automationClass->trigger('user_click', ['userId' => $urlClick['user_id']]);
+ }
+
+ if (!empty($onDuplicate)) {
+ $query .= " ON DUPLICATE KEY UPDATE ";
+ $query .= implode(',', $onDuplicate);
+ $query = "INSERT INTO ".$query;
+ } else {
+ $query = "INSERT IGNORE INTO ".$query;
+ }
+
+ acym_query($query);
+ }
+
+ public function getClickRate($mailid = '')
+ {
+ $query = 'SELECT COUNT(DISTINCT user_id) as click FROM #__acym_url_click ';
+ $query .= empty($mailid) ? '' : ' WHERE `mail_id` = '.intval($mailid);
+ $query .= ' ORDER BY user_id';
+
+ return acym_loadObject($query);
+ }
+
+ public function getAllClickByMailMonth($mailid = '', $start = '', $end = '')
+ {
+ $query = 'SELECT COUNT(*) as click, DATE_FORMAT(date_click, \'%Y-%m\') as date_click FROM #__acym_url_click WHERE click > 0';
+ $query .= empty($mailid) ? '' : ' AND `mail_id` = '.intval($mailid);
+ $query .= empty($start) ? '' : ' AND date_click >= '.acym_escapeDB($start);
+ $query .= empty($end) ? '' : ' AND date_click <= '.acym_escapeDB($end);
+ $query .= ' GROUP BY MONTH(date_click), YEAR(date_click) ORDER BY date_click';
+
+ return acym_loadObjectList($query);
+ }
+
+ public function getAllClickByMailWeek($mailid = '', $start = '', $end = '')
+ {
+ $query = 'SELECT COUNT(*) as click, DATE_FORMAT(date_click, \'%Y-%m-%d\') as date_click FROM #__acym_url_click WHERE click > 0';
+ $query .= empty($mailid) ? '' : ' AND `mail_id` = '.intval($mailid);
+ $query .= empty($start) ? '' : ' AND date_click >= '.acym_escapeDB($start);
+ $query .= empty($end) ? '' : ' AND date_click <= '.acym_escapeDB($end);
+ $query .= ' GROUP BY WEEK(date_click), YEAR(date_click) ORDER BY date_click';
+
+ return acym_loadObjectList($query);
+ }
+
+ public function getAllClickByMailDay($mailid = '', $start = '', $end = '')
+ {
+ $query = 'SELECT COUNT(*) as click, DATE_FORMAT(date_click, \'%Y-%m-%d\') as date_click FROM #__acym_url_click WHERE click > 0';
+ $query .= empty($mailid) ? '' : ' AND `mail_id` = '.intval($mailid);
+ $query .= empty($start) ? '' : ' AND date_click >= '.acym_escapeDB($start);
+ $query .= empty($end) ? '' : ' AND date_click <= '.acym_escapeDB($end);
+ $query .= ' GROUP BY DAYOFYEAR(date_click), YEAR(date_click) ORDER BY date_click';
+
+ return acym_loadObjectList($query);
+ }
+
+ public function getAllClickByMailHour($mailid = '', $start = '', $end = '')
+ {
+ $query = 'SELECT COUNT(*) as click, DATE_FORMAT(date_click, \'%Y-%m-%d %H:00:00\') as date_click FROM #__acym_url_click WHERE click > 0';
+ $query .= empty($mailid) ? '' : ' AND `mail_id` = '.intval($mailid);
+ $query .= empty($start) ? '' : ' AND date_click >= '.acym_escapeDB($start);
+ $query .= empty($end) ? '' : ' AND date_click <= '.acym_escapeDB($end);
+ $query .= ' GROUP BY HOUR(date_click), DAYOFYEAR(date_click), YEAR(date_click) ORDER BY date_click';
+
+ return acym_loadObjectList($query);
+ }
+
+ public function getAllLinkFromEmail($id)
+ {
+ $queryClickUrl = 'SELECT url.name, SUM(urlclick.click) as click FROM #__acym_url_click AS urlclick
+ LEFT JOIN #__acym_url AS url ON urlclick.url_id = url.id
+ WHERE `mail_id` = '.intval($id).' GROUP BY `url_id`';
+
+ $queryCountAllClicks = 'SELECT SUM(click) FROM #__acym_url_click WHERE `mail_id` = '.intval($id);
+
+ $return = [
+ 'urls_click' => acym_loadObjectList($queryClickUrl),
+ 'allClick' => acym_loadResult($queryCountAllClicks),
+ ];
+
+ return $return;
+ }
+}
+
diff --git a/deployed/acym/administrator/components/com_acym/classes/user.php b/deployed/acym/administrator/components/com_acym/classes/user.php
new file mode 100644
index 00000000..85c44b56
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/classes/user.php
@@ -0,0 +1,812 @@
+ 'active = 1',
+ 'inactive' => 'active = 0',
+ ];
+ if (empty($allowedStatus[$settings['status']])) {
+ die('Injection denied');
+ }
+ $filters[] = 'user.'.$allowedStatus[$settings['status']];
+ }
+
+ if (!empty($settings['hiddenUsers'])) {
+ acym_arrayToInteger($settings['hiddenUsers']);
+ $filters[] = 'user.id NOT IN('.implode(',', $settings['hiddenUsers']).')';
+ }
+
+ if (!empty($settings['showOnlySelected'])) {
+ if (!empty($settings['selectedUsers'])) {
+ acym_arrayToInteger($settings['selectedUsers']);
+ $filters[] = 'user.id IN('.implode(',', $settings['selectedUsers']).')';
+ } else {
+ return ['users' => [], 'total' => 0];
+ }
+ }
+
+ if (!empty($filters)) {
+ $query .= ' WHERE ('.implode(') AND (', $filters).')';
+ $queryCount .= ' WHERE ('.implode(') AND (', $filters).')';
+ }
+
+ if (!empty($settings['ordering']) && !empty($settings['ordering_sort_order'])) {
+ $query .= ' ORDER BY user.'.acym_secureDBColumn($settings['ordering']).' '.acym_secureDBColumn(strtoupper($settings['ordering_sort_order']));
+ }
+
+ $settings['offset'] = $settings['offset'] < 0 ? 0 : $settings['offset'];
+
+ $results['users'] = acym_loadObjectList($query, '', $settings['offset'], $settings['usersPerPage']);
+ $results['total'] = acym_loadResult($queryCount);
+
+ $usersPerStatus = acym_loadObjectList($queryStatus.' GROUP BY active', 'active');
+
+ for ($i = 0 ; $i < 2 ; $i++) {
+ $usersPerStatus[$i] = empty($usersPerStatus[$i]) ? 0 : $usersPerStatus[$i]->number;
+ }
+
+ $results['status'] = [
+ 'all' => array_sum($usersPerStatus),
+ 'active' => $usersPerStatus[1],
+ 'inactive' => $usersPerStatus[0],
+ ];
+
+ return $results;
+ }
+
+ public function getAll()
+ {
+ $query = 'SELECT * FROM #__acym_user';
+
+ return acym_loadObjectList($query);
+ }
+
+ public function getOneById($id)
+ {
+ $query = 'SELECT * FROM #__acym_user WHERE id = '.intval($id).' LIMIT 1';
+
+ return acym_loadObject($query);
+ }
+
+ public function getOneByCMSId($id)
+ {
+ $query = 'SELECT * FROM #__acym_user WHERE cms_id = '.intval($id).' LIMIT 1';
+
+ return acym_loadObject($query);
+ }
+
+
+ public function getOneByEmail($email)
+ {
+ $query = "SELECT * FROM #__acym_user WHERE email = ".acym_escapeDB($email)." LIMIT 1";
+
+ return acym_loadObject($query);
+ }
+
+ public function getUserSubscriptionById($userId, $key = 'id')
+ {
+ $query = 'SELECT list.id, list.name, list.color, list.active, list.visible, userlist.status, userlist.subscription_date, userlist.unsubscribe_date
+ FROM #__acym_list AS list
+ JOIN #__acym_user_has_list AS userlist
+ ON list.id = userlist.list_id
+ WHERE userlist.user_id = '.intval($userId);
+
+ return acym_loadObjectList($query, $key);
+ }
+
+ public function getAllListsUserSubscriptionById($userId, $key = 'id')
+ {
+ $query = 'SELECT list.id, list.name, list.color, list.active, list.visible, userlist.status, userlist.subscription_date, userlist.unsubscribe_date
+ FROM #__acym_list AS list
+ LEFT JOIN #__acym_user_has_list AS userlist
+ ON list.id = userlist.list_id
+ AND userlist.user_id = '.intval($userId);
+
+ return acym_loadObjectList($query, $key);
+ }
+
+ public function getUsersSubscriptionsByIds($usersId)
+ {
+ $query = 'SELECT id, user_id, l.color, l.name
+ FROM #__acym_list AS l
+ JOIN #__acym_user_has_list AS userlist
+ ON l.id = userlist.list_id
+ WHERE user_id IN ('.implode(',', $usersId).')
+ AND userlist.status = 1';
+
+ return acym_loadObjectList($query);
+ }
+
+ public function getCountTotalUsers()
+ {
+ $query = 'SELECT COUNT(id) FROM #__acym_user';
+
+ return acym_loadResult($query);
+ }
+
+ public function getSubscriptionStatus($userId, $listids = [])
+ {
+ $query = 'SELECT status, list_id FROM #__acym_user_has_list WHERE user_id = '.intval($userId);
+ if (!empty($listids)) {
+ acym_arrayToInteger($listids);
+ $query .= ' AND list_id IN ('.implode(',', $listids).')';
+ }
+
+ return acym_loadObjectList($query, 'list_id');
+ }
+
+ public function identify($onlyValue = false)
+ {
+ $id = acym_getVar('int', "id", 0);
+ $key = acym_getVar('string', "key", '');
+
+ if (empty($id) || empty($key)) {
+ $currentUserid = acym_currentUserId();
+ if (!empty($currentUserid)) {
+ return $this->getOneByCMSId($currentUserid);
+ }
+ if (!$onlyValue) {
+ acym_enqueueNotification(acym_translation('ACYM_LOGIN'), 'error', 0);
+ }
+
+ return false;
+ }
+
+ $userIdentified = acym_loadObject('SELECT * FROM #__acym_user WHERE `id` = '.intval($id).' AND `key` = '.acym_escapeDB($key));
+
+ if (!empty($userIdentified)) {
+ return $userIdentified;
+ }
+
+ if (!$onlyValue) {
+ acym_enqueueNotification(acym_translation('INVALID_KEY'), 'error', 0);
+ }
+
+ return false;
+ }
+
+ public function subscribe($userIds, $addLists)
+ {
+ if (empty($addLists)) {
+ return false;
+ }
+
+ if (!is_array($userIds)) {
+ $userIds = [$userIds];
+ }
+
+ if (!is_array($addLists)) {
+ $addLists = [$addLists];
+ }
+
+ $config = acym_config();
+ $listClass = acym_get('class.list');
+ $subscribedToLists = false;
+ foreach ($userIds as $userId) {
+ $user = $this->getOneById($userId);
+ if (empty($user)) {
+ continue;
+ }
+ $currentSubscription = $this->getUserSubscriptionById($userId);
+
+ $currentlySubscribed = [];
+ $currentlyUnsubscribed = [];
+ foreach ($currentSubscription as $oneList) {
+ if ($oneList->status == 1) {
+ $currentlySubscribed[$oneList->id] = $oneList;
+ }
+ if ($oneList->status == 0) {
+ $currentlyUnsubscribed[$oneList->id] = $oneList;
+ }
+ }
+
+ $subscribedLists = [];
+ foreach ($addLists as $oneListId) {
+ if (empty($oneListId) || !empty($currentlySubscribed[$oneListId])) continue;
+
+ $subscription = new stdClass();
+ $subscription->user_id = $userId;
+ $subscription->list_id = $oneListId;
+ $subscription->status = 1;
+ $subscription->subscription_date = date("Y-m-d H:i:s", time());
+
+ if (empty($currentSubscription[$oneListId])) {
+ acym_insertObject('#__acym_user_has_list', $subscription);
+ } elseif (!empty($currentlyUnsubscribed[$oneListId])) {
+ acym_updateObject('#__acym_user_has_list', $subscription, ['user_id', 'list_id']);
+ }
+
+ $subscribedLists[] = $oneListId;
+ $subscribedToLists = true;
+ }
+
+ $historyClass = acym_get('class.history');
+ $historyData = acym_translation_sprintf('ACYM_LISTS_NUMBERS', implode(', ', $addLists));
+ $historyClass->insert($userId, 'subscribed', [$historyData]);
+
+ acym_trigger('onAcymAfterUserSubscribe', [&$user, &$subscribedLists]);
+
+ if ($config->get('require_confirmation', 1) == 0 || $user->confirmed == 1) {
+ $listClass->sendWelcome($userId, $subscribedLists);
+ }
+ }
+
+ return $subscribedToLists;
+ }
+
+ public function unsubscribe($userIds, $lists)
+ {
+ if (empty($lists)) {
+ return false;
+ }
+
+ if (!is_array($userIds)) {
+ $userIds = [$userIds];
+ }
+
+ if (!is_array($lists)) {
+ $lists = [$lists];
+ }
+
+ $listClass = acym_get('class.list');
+ $unsubscribedFromLists = false;
+ foreach ($userIds as $userId) {
+ $currentSubscription = $this->getUserSubscriptionById($userId);
+
+ $currentlyUnsubscribed = [];
+ foreach ($currentSubscription as $oneList) {
+ if ($oneList->status == 0) {
+ $currentlyUnsubscribed[$oneList->id] = $oneList;
+ }
+ }
+
+ $unsubscribedLists = [];
+ foreach ($lists as $oneListId) {
+ if (empty($oneListId) || !empty($currentlyUnsubscribed[$oneListId])) {
+ continue;
+ }
+
+ $subscription = new stdClass();
+ $subscription->user_id = $userId;
+ $subscription->list_id = $oneListId;
+ $subscription->status = 0;
+ $subscription->unsubscribe_date = date("Y-m-d H:i:s", time());
+
+ if (empty($currentSubscription[$oneListId])) {
+ acym_insertObject('#__acym_user_has_list', $subscription);
+ } else {
+ acym_updateObject('#__acym_user_has_list', $subscription, ['user_id', 'list_id']);
+ }
+
+ $unsubscribedLists[] = $oneListId;
+ $unsubscribedFromLists = true;
+ }
+
+ $historyClass = acym_get('class.history');
+ $historyData = acym_translation_sprintf('ACYM_LISTS_NUMBERS', implode(', ', $lists));
+ $historyClass->insert($userId, 'unsubscribed', [$historyData]);
+
+ acym_trigger('onAcymAfterUserUnsubscribe', [&$userId, &$unsubscribedLists]);
+
+ $listClass->sendUnsubscribe($userId, $unsubscribedLists);
+ }
+
+ return $unsubscribedFromLists;
+ }
+
+ public function removeSubscription($userId, $listIds = null)
+ {
+ if (!is_array($userId)) $userId = [$userId];
+ if (!is_array($listIds) || empty($listIds) || empty($userId)) return false;
+
+ acym_arrayToInteger($listIds);
+ $query = 'DELETE FROM #__acym_user_has_list WHERE user_id IN ('.implode(',', $userId).')';
+ if (!empty($listIds)) $query .= ' AND list_id IN ('.implode(',', $listIds).')';
+
+ return acym_query($query);
+ }
+
+ public function delete($elements)
+ {
+ if (!is_array($elements)) $elements = [$elements];
+ acym_arrayToInteger($elements);
+
+ if (empty($elements)) return 0;
+
+ acym_trigger('onAcymBeforeUserDelete', [&$elements]);
+
+ acym_query('DELETE FROM #__acym_user_has_list WHERE user_id IN ('.implode(',', $elements).')');
+ acym_query('DELETE FROM #__acym_queue WHERE user_id IN ('.implode(',', $elements).')');
+ acym_query('DELETE FROM #__acym_user_has_field WHERE user_id IN ('.implode(',', $elements).')');
+
+ return parent::delete($elements);
+ }
+
+ public function save($user, $customFields = null)
+ {
+ if (empty($user->email) && empty($user->id)) return false;
+
+ if (empty($user->id) && !isset($user->active)) $user->active = 1;
+
+ if (isset($user->email)) {
+ $user->email = strtolower($user->email);
+ if (!acym_isValidEmail($user->email)) {
+ $this->errors[] = acym_translation('ACYM_VALID_EMAIL');
+
+ return false;
+ }
+ }
+
+ $config = acym_config();
+
+ if (empty($user->id)) {
+ $currentUserid = acym_currentUserId();
+ $currentEmail = acym_currentUserEmail();
+ if ($this->checkVisitor && !acym_isAdmin() && intval($config->get('allow_visitor', 1)) != 1 && (empty($currentUserid) || strtolower($currentEmail) != $user->email)) {
+ $this->errors[] = acym_translation('ACYM_ONLY_LOGGED');
+
+ return false;
+ }
+ }
+
+ if (empty($user->id)) {
+ if (empty($user->name) && $config->get('generate_name', 1)) {
+ $user->name = ucwords(trim(str_replace(['.', '_', ')', ',', '(', '-', 1, 2, 3, 4, 5, 6, 7, 8, 9, 0], ' ', substr($user->email, 0, strpos($user->email, '@')))));
+ }
+
+ if (empty($user->key)) $user->key = acym_generateKey(14);
+
+ $user->creation_date = date('Y-m-d H:i:s', time());
+ } elseif (!empty($user->confirmed)) {
+ $oldUser = $this->getOneById($user->id);
+ if (!empty($oldUser) && empty($oldUser->confirmed)) {
+ $user->confirmation_date = date('Y-m-d H:i:s', time());
+ $user->confirmation_ip = acym_getIP();
+ }
+ }
+
+ foreach ($user as $oneAttribute => $value) {
+ if (empty($value)) continue;
+
+ $oneAttribute = trim(strtolower($oneAttribute));
+ if (!in_array($oneAttribute, $this->restrictedFields)) {
+ $user->$oneAttribute = strip_tags($value);
+ }
+
+ if (is_numeric($user->$oneAttribute)) continue;
+
+ if (function_exists('mb_detect_encoding')) {
+ if (mb_detect_encoding($user->$oneAttribute, 'UTF-8', true) != 'UTF-8') {
+ $user->$oneAttribute = utf8_encode($user->$oneAttribute);
+ }
+ } elseif (!preg_match('%^(?:[\x09\x0A\x0D\x20-\x7E]|[\xC2-\xDF][\x80-\xBF]|\xE0[\xA0-\xBF][\x80-\xBF]|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}|\xED[\x80-\x9F][\x80-\xBF]|\xF0[\x90-\xBF][\x80-\xBF]{2}|[\xF1-\xF3][\x80-\xBF]{3}|\xF4[\x80-\x8F][\x80-\xBF]{2})*$%xs', $user->$oneAttribute)) {
+ $user->$oneAttribute = utf8_encode($user->$oneAttribute);
+ }
+ }
+
+ if (empty($user->id)) {
+ if (empty($user->cms_id) && !empty($user->email)) {
+ $userCmsID = acym_loadResult('SELECT '.acym_secureDBColumn($this->cmsUserVars->id).' FROM '.$this->cmsUserVars->table.' WHERE '.acym_secureDBColumn($this->cmsUserVars->email).' = '.acym_escapeDB($user->email));
+ if (!empty($userCmsID)) $user->cms_id = $userCmsID;
+ }
+ acym_trigger('onAcymBeforeUserCreate', [&$user]);
+ } else {
+ acym_trigger('onAcymBeforeUserModify', [&$user]);
+ }
+
+ $userID = parent::save($user);
+
+ if (!empty($customFields)) {
+ $fieldClass = acym_get('class.field');
+ $fieldClass->store($customFields, $userID);
+ }
+
+ $historyClass = acym_get('class.history');
+ if (empty($user->id)) {
+ $user->id = $userID;
+ $historyClass->insert($user->id, 'created');
+ acym_trigger('onAcymAfterUserCreate', [&$user]);
+ } else {
+ $historyClass->insert($user->id, 'modified');
+ acym_trigger('onAcymAfterUserModify', [&$user]);
+ }
+
+ $this->sendConfirmation($userID);
+
+ return $userID;
+ }
+
+ public function saveForm()
+ {
+ $config = acym_config();
+ $allowUserModifications = (bool)($config->get('allow_modif', 'data') == 'all') || $this->allowModif;
+ $allowSubscriptionModifications = (bool)($config->get('allow_modif', 'data') != 'none') || $this->allowModif;
+
+ $user = new stdClass();
+ $user->id = acym_getCID('id');
+
+ if (!$this->allowModif && !empty($user->id)) {
+ $currentUser = $this->identify();
+ if ($currentUser->id != $user->id) {
+ $this->errors[] = acym_translation('ACYM_NOT_ALLOWED_MODIFY_USER');
+
+ return false;
+ }
+
+ $allowUserModifications = true;
+ $allowSubscriptionModifications = true;
+ }
+
+ $userData = acym_getVar('array', 'user', []);
+ if (!empty($userData)) {
+ foreach ($userData as $attribute => $value) {
+ $user->$attribute = $value;
+ }
+ }
+
+ if (empty($user->id) && empty($user->email)) {
+ $this->errors[] = acym_translation('ACYM_VALID_EMAIL');
+
+ return false;
+ }
+
+ if (!empty($user->email)) {
+ if (empty($user->id)) {
+ $user->id = 0;
+ }
+ $existUser = acym_loadObject('SELECT * FROM #__acym_user WHERE email = '.acym_escapeDB($user->email).' AND id != '.intval($user->id));
+ if (!empty($existUser->id) && !$this->allowModif) {
+ $this->errors[] = acym_translation('ACYM_ADDRESS_TAKEN');
+
+ return false;
+ }
+ }
+
+ if (!empty($user->id) && !empty($user->email)) {
+ $existUser = $this->getOneById($user->id);
+ if (trim(strtolower($user->email)) != strtolower($existUser->email)) {
+ $user->confirmed = 0;
+ }
+ }
+
+ $this->newUser = empty($user->id);
+ if (empty($user->id) || $allowUserModifications) {
+ if (isset($user->confirmed) && $user->confirmed != 1) {
+ $user->confirmed = 0;
+ }
+ if (isset($user->active) && $user->active != 1) {
+ $user->active = 0;
+ }
+ $customFieldData = acym_getVar('array', 'customField', []);
+ $id = $this->save($user, $customFieldData);
+ $allowSubscriptionModifications = true;
+ } else {
+ $id = $user->id;
+ if (isset($user->confirmed) && empty($user->confirmed)) {
+ $this->sendConfirmation($id);
+ }
+ }
+
+ if (empty($id)) {
+ return false;
+ }
+ $formData = acym_getVar('array', 'data', []);
+
+ acym_setVar('id', $id);
+
+ if (!acym_isAdmin()) {
+ $hiddenlistsString = acym_getVar('string', 'hiddenlists', '');
+ if (!empty($hiddenlistsString)) {
+ $hiddenlists = explode(',', $hiddenlistsString);
+ acym_arrayToInteger($hiddenlists);
+ foreach ($hiddenlists as $oneListId) {
+ $formData['listsub'][$oneListId] = ['status' => 1];
+ }
+ }
+ }
+
+ if (empty($formData['listsub'])) {
+ return true;
+ }
+
+ if (!$allowSubscriptionModifications) {
+ $this->requireId = true;
+ $this->errors[] = acym_translation('ACYM_NOT_ALLOWED_MODIFY_USER');
+
+ return false;
+ }
+
+ $addLists = [];
+ $unsubLists = [];
+ foreach ($formData['listsub'] as $listID => $oneList) {
+ if ($oneList['status'] == 1) {
+ $addLists[] = $listID;
+ } else {
+ $unsubLists[] = $listID;
+ }
+ }
+
+ $this->subscribe($id, $addLists);
+ if (!$this->newUser) {
+ $this->unsubscribe($id, $unsubLists);
+ }
+
+ return true;
+ }
+
+ public function sendConfirmation($userID)
+ {
+ if (!$this->forceConf && !$this->sendConf) return true;
+
+ $config = acym_config();
+ if ($config->get('require_confirmation', 1) != 1 || acym_isAdmin()) return false;
+
+ $myuser = $this->getOneById($userID);
+
+ if (!empty($myuser->confirmed)) return false;
+
+ $mailerHelper = acym_get('helper.mailer');
+
+ $mailerHelper->checkConfirmField = false;
+ $mailerHelper->checkEnabled = false;
+ $mailerHelper->report = $config->get('confirm_message', 0);
+
+ $alias = "acy_confirm";
+
+ $this->confirmationSentSuccess = $mailerHelper->sendOne($alias, $myuser);
+ $this->confirmationSentError = $mailerHelper->reportMessage;
+ }
+
+ public function deactivate($userId)
+ {
+ acym_query('UPDATE `#__acym_user` SET `active` = 0 WHERE `id` = '.intval($userId));
+ }
+
+ public function confirm($userId)
+ {
+ $confirmDate = date('Y-m-d H:i:s', time());
+ $ip = acym_getIP();
+ $query = 'UPDATE `#__acym_user`';
+ $query .= ' SET `confirmed` = 1, `confirmation_date` = '.acym_escapeDB($confirmDate).', `confirmation_ip` = '.acym_escapeDB($ip);
+ $query .= ' WHERE `id` = '.intval($userId).' LIMIT 1';
+ $res = acym_query($query);
+ if ($res === false) {
+ $msg = 'Please contact the admin of this website with the error message: '.substr(strip_tags(acym_getDBError()), 0, 200).'...';
+ acym_display($msg, 'error');
+ exit;
+ }
+
+
+ $historyClass = acym_get('class.history');
+ $historyClass->insert($userId, 'confirmed');
+
+ $listIDs = acym_loadResultArray('SELECT `list_id` FROM `#__acym_user_has_list` WHERE `status` = 1 AND `user_id` = '.intval($userId));
+
+ if (empty($listIDs)) {
+ return;
+ }
+
+ $listClass = acym_get('class.list');
+ $listClass->sendWelcome($userId, $listIDs);
+ }
+
+ public function getOneByIdWithCustomFields($id)
+ {
+ $user = $this->getOneById($id);
+ $user = get_object_vars($user);
+
+ $fieldsValue = acym_loadObjectList(
+ 'SELECT user_field.value as value, field.name as name
+ FROM #__acym_user_has_field as user_field
+ LEFT JOIN #__acym_field as field ON user_field.field_id = field.id
+ WHERE user_field.user_id = '.intval($id),
+ 'name'
+ );
+
+ foreach ($fieldsValue as $key => $value) {
+ $fieldsValue[$key] = $value->value;
+ }
+
+ return array_merge($user, $fieldsValue);
+ }
+
+ public function getAllColumnsUserAndCustomField($inAction = false)
+ {
+ $return = [];
+
+ $userFields = acym_getColumns('user');
+ foreach ($userFields as $value) {
+ $return[$value] = $value;
+ }
+
+ $customFields = acym_loadObjectList('SELECT * FROM #__acym_field WHERE id NOT IN (1, 2) '.($inAction ? 'AND type != "phone"' : ''), 'id');
+ if (!empty($customFields)) {
+ foreach ($customFields as $key => $value) {
+ $return[$key] = $value->name;
+ }
+ }
+
+ return $return;
+ }
+
+ public function getAllUserFields($user)
+ {
+ if (empty($user->id)) return $user;
+ $query = 'SELECT field.*, userfield.*
+ FROM #__acym_field AS field
+ LEFT JOIN #__acym_user_has_field AS userfield ON field.id = userfield.field_id AND userfield.user_id = '.intval($user->id).'
+ WHERE field.id NOT IN(1, 2)';
+
+ $allFields = acym_loadObjectList($query);
+
+ foreach ($allFields as $oneField) {
+ $user->{$oneField->namekey} = empty($oneField->value) ? '' : $oneField->value;
+ }
+
+ return $user;
+ }
+
+ public function synchSaveCmsUser($user, $isnew, $oldUser = null)
+ {
+ $source = acym_getVar('cmd', 'acy_source', '');
+ if (empty($source)) acym_setVar('acy_source', ACYM_CMS);
+
+ $config = acym_config();
+
+ if (!$config->get('regacy', 0)) return;
+
+ $this->checkVisitor = false;
+ $this->sendConf = false;
+
+ $cmsUser = new stdClass();
+ $cmsUser->email = trim(strip_tags($user['email']));
+ if (!acym_isValidEmail($cmsUser->email)) return;
+ if (!empty($user['name'])) $cmsUser->name = trim(strip_tags($user['name']));
+ if (!$config->get('regacy_forceconf', 0)) $cmsUser->confirmed = 1;
+ $cmsUser->active = 1 - intval($user['block']);
+ $cmsUser->cms_id = $user['id'];
+
+ if (!$isnew && !empty($oldUser['email']) && $user['email'] != $oldUser['email']) {
+ $acyUser = $this->getOneByEmail($oldUser['email']);
+ if (!empty($acyUser)) $cmsUser->id = $acyUser->id;
+ }
+
+ if (empty($cmsUser->id) && !empty($cmsUser->cms_id)) {
+ $acyUser = $this->getOneByCMSId($cmsUser->cms_id);
+ if (!empty($acyUser)) $cmsUser->id = $acyUser->id;
+ }
+
+ $acyUser = $this->getOneByEmail($cmsUser->email);
+ if (!empty($acyUser)) {
+ if (empty($cmsUser->id)) {
+ $cmsUser->id = $acyUser->id;
+ } elseif ($cmsUser->id != $acyUser->id) {
+ $this->delete($acyUser->id);
+ }
+ }
+
+ $isnew = (bool)($isnew || empty($cmsUser->id));
+
+ $id = $this->save($cmsUser);
+
+
+
+ $currentSubscription = $this->getSubscriptionStatus($id);
+
+ $autoLists = $isnew ? $config->get('regacy_autolists') : '';
+ $autoLists = explode(',', $autoLists);
+ acym_arrayToInteger($autoLists);
+
+ $listsClass = acym_get('class.list');
+ $allLists = $listsClass->getAll();
+
+ $visibleLists = acym_getVar('string', 'regacy_visible_lists');
+ $visibleLists = explode(',', $visibleLists);
+ acym_arrayToInteger($visibleLists);
+
+ $visibleListsChecked = acym_getVar('array', 'regacy_visible_lists_checked', []);
+ acym_arrayToInteger($visibleListsChecked);
+
+
+ if (!$isnew && !empty($visibleLists)) {
+ $currentlySubscribedLists = [];
+ foreach ($currentSubscription as $oneSubscription) {
+ if ($oneSubscription->status == 1) $currentlySubscribedLists[] = $oneSubscription->list_id;
+ }
+ $unsubscribeLists = array_intersect($currentlySubscribedLists, array_diff($visibleLists, $visibleListsChecked));
+ $this->unsubscribe($id, $unsubscribeLists);
+ }
+
+ $listsToSubscribe = [];
+ foreach ($allLists as $oneList) {
+ if (!$oneList->active) continue;
+ if (!empty($currentSubscription[$oneList->id]) && $currentSubscription[$oneList->id]->status == 1) continue;
+
+ if (in_array($oneList->id, $visibleListsChecked) || (in_array($oneList->id, $autoLists) && !in_array($oneList->id, $visibleLists) && empty($currentSubscription[$oneList->id]))) {
+ $listsToSubscribe[] = $oneList->id;
+ }
+ }
+
+ if (!empty($listsToSubscribe)) $this->subscribe($id, $listsToSubscribe);
+
+ $acymailingUser = $this->getOneById($id);
+ if (!$config->get('regacy_forceconf', 0) || !empty($user['block']) || !empty($acymailingUser->confirmed)) return;
+
+
+ if ($isnew || !empty($oldUser['block'])) {
+ $this->forceConf = true;
+ $this->sendConfirmation($id);
+ }
+ }
+
+ public function synchDeleteCmsUser($userEmail)
+ {
+ $acyUser = $this->getOneByEmail($userEmail);
+
+ if (empty($acyUser)) return;
+
+ $config = acym_config();
+ if ($config->get('regacy', '0') == 1 && $config->get('regacy_delete', '0') == 1) {
+ $this->delete($acyUser->id);
+ } else {
+ acym_query('UPDATE #__acym_user SET `cms_id` = 0 WHERE `id` = '.intval($acyUser->id));
+ }
+ }
+}
+
diff --git a/deployed/acym/administrator/components/com_acym/classes/userstat.php b/deployed/acym/administrator/components/com_acym/classes/userstat.php
new file mode 100644
index 00000000..4b039431
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/classes/userstat.php
@@ -0,0 +1,134 @@
+ $value) {
+ if (in_array($key, $columnName)) {
+ $column[] = '`'.acym_secureDBColumn($key).'`';
+ $valueColumn[] = acym_escapeDB($value);
+ }
+ }
+
+ $query = "INSERT INTO #__acym_user_stat (".implode(',', $column).") VALUE (".implode(',', $valueColumn).")";
+ $onDuplicate = [];
+
+ if (!empty($userStat['statusSending'])) {
+ $onDuplicate[] = $userStat['statusSending'] == 0 ? "fail = fail + 1" : "sent = sent + 1";
+ }
+
+ if (!empty($userStat['open'])) {
+ $onDuplicate[] = "open = open + 1";
+ $automationClass = acym_get('class.automation');
+ $automationClass->trigger('user_open', ['userId' => $userStat['user_id']]);
+ }
+
+ if (!empty($userStat['open_date'])) {
+ $onDuplicate[] = 'open_date = '.acym_escapeDB($userStat['open_date']);
+ }
+
+ if (!empty($onDuplicate)) {
+ $query .= " ON DUPLICATE KEY UPDATE ";
+ $query .= implode(',', $onDuplicate);
+ }
+
+ acym_query($query);
+ }
+
+ public function getOneByMailAndUserId($mail_id, $user_id)
+ {
+ $query = 'SELECT * FROM #__acym_user_stat WHERE `mail_id` = '.intval($mail_id).' AND `user_id` = '.intval($user_id);
+
+ return acym_loadObject($query);
+ }
+
+ public function getAllUserStatByUserId($idUser)
+ {
+ $query = 'SELECT * FROM #__acym_user_stat WHERE user_id = '.intval($idUser);
+
+ return acym_loadObjectList($query);
+ }
+
+
+ public function getDetailedStats($settings)
+ {
+ $mailClass = acym_get('class.mail');
+
+ $query = 'SELECT us.*, m.name, m.subject, u.email, c.id as campaign_id
+ FROM #__acym_user_stat AS us
+ LEFT JOIN #__acym_user AS u ON us.user_id = u.id
+ INNER JOIN #__acym_mail AS m ON us.mail_id = m.id
+ LEFT JOIN #__acym_campaign AS c ON m.id = c.mail_id';
+ $queryCount = 'SELECT COUNT(*) FROM #__acym_user_stat as us
+ LEFT JOIN #__acym_user AS u ON us.user_id = u.id
+ INNER JOIN #__acym_mail AS m ON us.mail_id = m.id';
+ $where = [];
+
+ if (!empty($settings['mail_id'])) {
+ $where[] = 'us.mail_id = '.intval($settings['mail_id']);
+ }
+
+ if (!empty($settings['search'])) {
+ $where[] = 'm.name LIKE '.acym_escapeDB('%'.$settings['search'].'%').' OR u.email LIKE '.acym_escapeDB('%'.$settings['search'].'%');
+ }
+
+ if (!empty($where)) {
+ $query .= ' WHERE ('.implode(') AND (', $where).')';
+ $queryCount .= ' WHERE ('.implode(') AND (', $where).')';
+ }
+
+ if (!empty($settings['ordering']) && !empty($settings['ordering_sort_order'])) {
+ if ($settings['ordering'] == 'email') {
+ $table = 'u';
+ } elseif ($settings['ordering'] == 'subject') {
+ $table = 'm';
+ } else {
+ $table = 'us';
+ }
+ $query .= ' ORDER BY '.$table.'.'.acym_secureDBColumn($settings['ordering']).' '.acym_secureDBColumn(strtoupper($settings['ordering_sort_order']));
+ }
+
+ $results['detailed_stats'] = $mailClass->decode(acym_loadObjectList($query, '', $settings['offset'], $settings['detailedStatsPerPage']));
+ $results['total'] = acym_loadResult($queryCount);
+
+ return $results;
+ }
+
+ public function getTotalFailClickOpenByMailIds($mailIds)
+ {
+ acym_arrayToInteger($mailIds);
+ if (empty($mailIds)) return [];
+
+ $query = "SELECT mail_id, SUM(fail) AS fail, SUM(sent) AS sent, SUM(open) AS open FROM #__acym_user_stat WHERE mail_id IN (".implode(',', $mailIds).") GROUP BY mail_id";
+
+ return acym_loadObjectList($query, 'mail_id');
+ }
+
+ public function getUserWithNoMailOpen()
+ {
+ $query = 'SELECT user_id FROM #__acym_user_stat GROUP BY user_id HAVING MAX(open) = 0';
+
+ return acym_loadResultArray($query);
+ }
+}
+
diff --git a/deployed/acym/administrator/components/com_acym/config.xml b/deployed/acym/administrator/components/com_acym/config.xml
new file mode 100644
index 00000000..716773b7
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/config.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/deployed/acym/administrator/components/com_acym/controllers/automation.php b/deployed/acym/administrator/components/com_acym/controllers/automation.php
new file mode 100644
index 00000000..c07ecc91
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/controllers/automation.php
@@ -0,0 +1,640 @@
+breadcrumb[acym_translation('ACYM_AUTOMATION')] = acym_completeLink('automation');
+ $this->loadScripts = [
+ 'all' => ['datepicker'],
+ ];
+ acym_setVar('edition', '1');
+ }
+
+ public function listing()
+ {
+ if (!acym_level(2)) {
+ acym_redirect(acym_completeLink('dashboard&task=upgrade&version=enterprise', false, true));
+ }
+
+ }
+
+ public function info()
+ {
+ if (!acym_level(2)) {
+ acym_redirect(acym_completeLink('dashboard&task=upgrade&version=enterprise', false, true));
+ }
+
+ }
+
+ public function condition()
+ {
+ if (!acym_level(2)) {
+ acym_redirect(acym_completeLink('dashboard&task=upgrade&version=enterprise', false, true));
+ }
+
+ }
+
+ public function filter()
+ {
+
+ if (!acym_level(2)) {
+ acym_redirect(acym_completeLink('dashboard&task=upgrade&version=enterprise', false, true));
+ }
+ }
+
+ public function switches($matches)
+ {
+ return $matches[1].'__numand__'.$matches[2].'__numand__'.$matches[3].'__numand__'.$matches[4];
+ }
+
+ public function action()
+ {
+
+ if (!acym_level(2)) {
+ acym_redirect(acym_completeLink('dashboard&task=upgrade&version=enterprise', false, true));
+ }
+ }
+
+ public function summary()
+ {
+
+ if (!acym_level(2)) {
+ acym_redirect(acym_completeLink('dashboard&task=upgrade&version=enterprise', false, true));
+ }
+ }
+
+ private function _saveInfos($isMassAction = false)
+ {
+ if ($isMassAction) {
+ acym_session();
+ }
+
+ $automationId = acym_getVar('int', 'id');
+ $automation = acym_getVar('array', 'automation');
+ $automationClass = acym_get('class.automation');
+
+ $stepAutomationId = acym_getVar('int', 'stepAutomationId');
+ $stepAutomation = acym_getVar('array', 'stepAutomation');
+ $stepClass = acym_get('class.step');
+
+ if (!empty($automationId)) {
+ $automation['id'] = $automationId;
+ }
+
+ if (!empty($stepAutomationId)) {
+ $stepAutomation['id'] = $stepAutomationId;
+ }
+
+ $typeTrigger = acym_getVar('string', 'type_trigger');
+
+ if (empty($automation['admin']) && empty($automation['name'])) {
+ return false;
+ }
+
+ if (empty($stepAutomation['triggers'][$typeTrigger])) {
+ acym_enqueueNotification(acym_translation('ACYM_PLEASE_SELECT_ONE_TRIGGER'), 'error', 5000);
+
+ $this->info();
+
+ return false;
+ }
+
+ $stepAutomation['triggers'][$typeTrigger]['type_trigger'] = $typeTrigger;
+ $stepAutomation['triggers'] = json_encode($stepAutomation['triggers'][$typeTrigger]);
+
+ $stepAutomation['automation_id'] = $automationId;
+
+ foreach ($automation as $column => $value) {
+ acym_secureDBColumn($column);
+ }
+
+ foreach ($stepAutomation as $stepColumn => $stepValue) {
+ acym_secureDBColumn($stepColumn);
+ }
+
+ $automation = (object)$automation;
+ $stepAutomation = (object)$stepAutomation;
+
+ $automation->id = $automationClass->save($automation);
+ $stepAutomation->automation_id = $automation->id;
+ $stepAutomation->id = $stepClass->save($stepAutomation);
+
+ $returnIds = [
+ "automationId" => $automation->id,
+ "stepId" => $stepAutomation->id,
+ "typeTrigger" => $typeTrigger,
+ ];
+
+ if ($isMassAction) {
+ return true;
+ } elseif (!empty($returnIds['automationId']) && !empty($returnIds['stepId'])) {
+ return $returnIds;
+ } else {
+ return false;
+ }
+ }
+
+ private function _saveConditions($isMassAction = false)
+ {
+ $automationID = acym_getVar('int', 'id');
+ $conditionId = acym_getVar('int', 'conditionId');
+ $condition = acym_getVar('array', 'acym_condition', []);
+ $conditionClass = acym_get('class.condition');
+
+ $stepAutomationId = acym_getVar('int', 'stepAutomationId');
+
+ if (!empty($stepAutomationId)) {
+ $stepAutomation['id'] = $stepAutomationId;
+ }
+
+ if (!empty($conditionId)) {
+ $condition['id'] = $conditionId;
+ }
+
+ $condition['conditions']['type_condition'] = acym_getVar('string', 'type_condition');
+
+ if ($isMassAction) {
+ acym_session();
+ $_SESSION['massAction']['conditions'] = $condition['conditions'];
+
+ return true;
+ }
+
+ $condition['conditions'] = json_encode($condition['conditions']);
+
+ $condition['step_id'] = $stepAutomationId;
+
+ foreach ($condition as $column => $value) {
+ acym_secureDBColumn($column);
+ }
+
+ $condition = (object)$condition;
+
+ $condition->id = $conditionClass->save($condition);
+
+ $returnIds = [
+ 'automationId' => $automationID,
+ 'stepId' => $stepAutomationId,
+ 'conditionId' => $condition->id,
+ ];
+
+ return $returnIds;
+ }
+
+ private function _saveFilters($isMassAction = false)
+ {
+ $automationID = acym_getVar('int', 'id');
+ $actionId = acym_getVar('int', 'actionId');
+ $action = acym_getVar('array', 'acym_action', []);
+ $actionClass = acym_get('class.action');
+ $conditionId = acym_getVar('int', 'conditionId');
+
+ $stepAutomationId = acym_getVar('int', 'stepAutomationId');
+
+ if (!empty($stepAutomationId)) {
+ $stepAutomation['id'] = $stepAutomationId;
+ }
+
+ if (!empty($conditionId)) {
+ $action['condition_id'] = $conditionId;
+ }
+
+ if (!empty($actionId)) {
+ $action['id'] = $actionId;
+ }
+
+ $action['filters']['type_filter'] = acym_getVar('string', 'type_filter');
+
+ if ($isMassAction) {
+ acym_session();
+ $_SESSION['massAction']['filters'] = $action['filters'];
+
+ return true;
+ }
+
+ $action['filters'] = json_encode($action['filters']);
+
+ $action['order'] = 1;
+
+ foreach ($action as $column => $value) {
+ acym_secureDBColumn($column);
+ }
+
+ $action = (object)$action;
+
+ $action->id = $actionClass->save($action);
+
+ $returnIds = [
+ 'automationId' => $automationID,
+ 'stepId' => $stepAutomationId,
+ 'actionId' => $action->id,
+ ];
+
+ return $returnIds;
+ }
+
+ private function _saveActions($isMassAction = false)
+ {
+ if ($isMassAction) {
+ acym_session();
+ }
+
+ $automationID = acym_getVar('int', 'id');
+ $stepID = acym_getVar('int', 'id');
+ $actionId = acym_getVar('int', 'actionId');
+ $action = acym_getVar('array', 'acym_action');
+ $actionClass = acym_get('class.action');
+ $stepAutomationId = acym_getVar('int', 'stepAutomationId');
+ $conditionId = acym_getVar('int', 'conditionId');
+
+ if (!empty($stepAutomationId)) {
+ $stepAutomation['id'] = $stepAutomationId;
+ }
+
+ if ((!empty($conditionId))) {
+ $action['condition_id'] = $conditionId;
+ }
+
+ if (!empty($actionId)) {
+ $action['id'] = $actionId;
+ }
+
+ if (empty($action['actions'])) {
+ $action['actions'] = [];
+ }
+
+ if ($isMassAction) {
+ $_SESSION['massAction']['actions'] = $action['actions'];
+
+ return true;
+ }
+
+ $action['actions'] = json_encode($action['actions']);
+
+ foreach ($action as $column => $value) {
+ acym_secureDBColumn($column);
+ }
+
+ $action = (object)$action;
+
+ $action->id = $actionClass->save($action);
+
+ $returnIds = [
+ 'automationId' => $automationID,
+ 'stepId' => $stepAutomationId,
+ 'actionId' => $action->id,
+ ];
+
+ return $returnIds;
+ }
+
+ private function _saveAutomation($from, $isMassAction = false)
+ {
+ if ($isMassAction) {
+ acym_session();
+ }
+
+ $automationId = acym_getVar('int', 'id');
+ $automation = acym_getVar('array', 'automation');
+ $automationClass = acym_get('class.automation');
+
+ $stepAutomationId = acym_getVar('int', 'stepAutomationId');
+ $stepAutomation = acym_getVar('array', 'stepAutomation');
+ $stepClass = acym_get('class.step');
+
+ if (!empty($automationId)) {
+ $automation['id'] = $automationId;
+ }
+
+ if (!empty($stepAutomationId)) {
+ $stepAutomation['id'] = $stepAutomationId;
+ }
+
+ if ($from == 'info') {
+ $typeTrigger = acym_getVar('string', 'type_trigger');
+
+ if (empty($automation['name'])) {
+ return false;
+ }
+
+ if (empty($stepAutomation['triggers'][$typeTrigger])) {
+ acym_enqueueNotification(acym_translation('ACYM_PLEASE_SELECT_ONE_TRIGGER'), 'error', 5000);
+
+ $this->info();
+
+ return false;
+ }
+
+ $stepAutomation['triggers'][$typeTrigger]['type_trigger'] = $typeTrigger;
+ $stepAutomation['triggers'] = json_encode($stepAutomation['triggers'][$typeTrigger]);
+
+ $stepAutomation['automation_id'] = $automationId;
+
+ foreach ($automation as $column => $value) {
+ acym_secureDBColumn($column);
+ }
+
+ foreach ($stepAutomation as $stepColumn => $stepValue) {
+ acym_secureDBColumn($stepColumn);
+ }
+
+ $automation = (object)$automation;
+ $stepAutomation = (object)$stepAutomation;
+
+ $saveIdStepAutomation = $stepClass->save($stepAutomation);
+ $saveIdAutomation = $automationClass->save($automation);
+
+ $returnIds = [
+ "automationId" => $saveIdAutomation,
+ "stepId" => $saveIdStepAutomation,
+ ];
+
+ if ($isMassAction) {
+ return true;
+ } elseif (!empty($returnIds['automationId']) && !empty($returnIds['stepId'])) {
+ return $returnIds;
+ } else return false;
+ } elseif ($from == 'filters') {
+ $stepAutomation['filters']['type_filter'] = acym_getVar('string', 'type_filter');
+ if ($isMassAction) {
+ $_SESSION['massAction']['filters'] = $stepAutomation['filters'];
+ }
+ $stepAutomation['filters'] = json_encode($stepAutomation['filters']);
+ } elseif ($from == 'actions') {
+ if (empty($stepAutomation['actions'])) {
+ acym_enqueueNotification(acym_translation('ACYM_PLEASE_SET_ACTIONS'), 'error', 5000);
+ if (!empty($automationId)) acym_setVar('id', $automationId);
+ $this->action();
+
+ return false;
+ }
+ if ($isMassAction) {
+ $_SESSION['massAction']['actions'] = $stepAutomation['actions'];
+ }
+ $stepAutomation['actions'] = json_encode($stepAutomation['actions']);
+ } elseif ($from == 'summary') {
+ $automation = $automationClass->getOneById($automationId);
+ $automation->active = 1;
+ }
+
+ if ($isMassAction) {
+ return true;
+ } else {
+ switch ($from) {
+ case 'info':
+ case 'summary':
+ foreach ($automation as $column => $value) {
+ acym_secureDBColumn($column);
+ }
+
+ $automation = (object)$automation;
+
+ return $automationClass->save($automation);
+ case 'filters':
+ case 'actions':
+ $stepAutomation['automation_id'] = $automationId;
+ $stepAutomation['order'] = 1;
+
+ foreach ($stepAutomation as $column => $value) {
+ acym_secureDBColumn($column);
+ }
+
+ $stepAutomation = (object)$stepAutomation;
+
+ return $stepClass->save($stepAutomation);
+ default:
+ return false;
+ }
+ }
+ }
+
+ public function saveExitInfo()
+ {
+ $ids = $this->_saveInfos();
+
+ if (empty($ids)) {
+ return;
+ }
+
+ acym_enqueueNotification(acym_translation('ACYM_SUCCESSFULLY_SAVED'), 'success', 8000);
+
+ acym_setVar('id', $ids['automationId']);
+ acym_setVar('stepId', $ids['stepId']);
+ $this->listing();
+ }
+
+ public function saveInfo()
+ {
+ $ids = $this->_saveInfos();
+
+ if (empty($ids)) {
+ return;
+ }
+
+ acym_setVar('id', $ids['automationId']);
+ acym_setVar('stepId', $ids['stepId']);
+ $this->condition();
+ }
+
+ public function saveExitConditions()
+ {
+ $ids = $this->_saveConditions();
+
+ if (empty($ids)) {
+ return;
+ }
+
+ acym_enqueueNotification(acym_translation('ACYM_SUCCESSFULLY_SAVED'), 'success', 8000);
+
+ $this->listing();
+ }
+
+ public function saveConditions()
+ {
+ $ids = $this->_saveConditions();
+
+ if (empty($ids)) {
+ return;
+ }
+
+ acym_setVar('id', $ids['automationId']);
+ acym_setVar('stepId', $ids['stepId']);
+ acym_setVar('conditionId', $ids['conditionId']);
+ $this->action();
+ }
+
+ public function saveExitFilters()
+ {
+ $ids = $this->_saveFilters();
+
+ if (empty($ids)) {
+ return;
+ }
+
+ acym_enqueueNotification(acym_translation('ACYM_SUCCESSFULLY_SAVED'), 'success', 8000);
+
+ $this->listing();
+ }
+
+ public function saveFilters()
+ {
+ $ids = $this->_saveFilters();
+
+ if (empty($ids)) {
+ return;
+ }
+
+ acym_setVar('id', $ids['automationId']);
+ acym_setVar('stepId', $ids['stepId']);
+ acym_setVar('actionId', $ids['actionId']);
+ $this->summary();
+ }
+
+ public function saveExitActions()
+ {
+ $ids = $this->_saveActions();
+
+ if (empty($ids)) {
+ return;
+ }
+
+ acym_enqueueNotification(acym_translation('ACYM_SUCCESSFULLY_SAVED'), 'success', 8000);
+
+ $this->listing();
+ }
+
+ public function saveActions()
+ {
+ $ids = $this->_saveActions();
+
+ if (empty($ids)) {
+ return;
+ }
+
+ acym_setVar('id', $ids['automationId']);
+ acym_setVar('stepId', $ids['stepId']);
+ acym_setVar('actionId', $ids['actionId']);
+ $this->filter();
+ }
+
+ public function activeAutomation()
+ {
+ $automationClass = acym_get('class.automation');
+ $automation = $automationClass->getOneById(acym_getVar('int', 'id'));
+ $automation->active = 1;
+ $saved = $automationClass->save($automation);
+ if (!empty($saved)) {
+ acym_enqueueNotification(acym_translation('ACYM_SUCCESSFULLY_SAVED'), 'success', 8000);
+ $this->listing();
+ } else {
+ acym_enqueueNotification(acym_translation('ACYM_ERROR_SAVING'), 'error', 5000);
+ $this->listing();
+ }
+ }
+
+
+ public function setFilterMassAction()
+ {
+ $this->_saveFilters(true);
+ $this->summary();
+ }
+
+ public function setActionMassAction()
+ {
+ $res = $this->_saveActions(true);
+ if (!$res) return false;
+ $this->filter();
+ }
+
+ function processMassAction()
+ {
+ acym_session();
+ $automationClass = acym_get('class.automation');
+ $massAction = empty($_SESSION['massAction']) ? '' : $_SESSION['massAction'];
+ if (!empty($massAction)) {
+ $automation = new stdClass();
+ $automation->filters = json_encode($massAction['filters']);
+ $automation->actions = json_encode($massAction['actions']);
+ $automationClass->execute($automation);
+
+ if (!empty($automationClass->report)) {
+ foreach ($automationClass->report as $oneReport) {
+ acym_enqueueNotification($oneReport, 'info', 5000);
+ }
+ }
+ }
+ $this->listing();
+ }
+
+ public function createMail()
+ {
+ $id = acym_getVar('int', 'id');
+ $idAdmin = acym_getVar('boolean', 'automation_admin');
+ $type = 'automation';
+ if ($idAdmin) $type = 'automation_admin';
+ $and = acym_getVar('string', 'and_action');
+ $this->_saveActions(empty($id));
+ $actions = acym_getVar('array', 'acym_action');
+ $mailId = $actions['actions'][$and]['acy_add_queue']['mail_id'];
+ acym_redirect(acym_completeLink('mails&task=edit&step=editEmail&type='.$type.'&from='.$mailId.'&return='.urlencode(acym_completeLink('automation&task=edit&step=action&id='.$id.'&fromMailEditor=1&mailid={mailid}&and='.$and)), false, true));
+ }
+
+
+ public function countresults()
+ {
+ $or = acym_getVar('int', 'or');
+ $and = acym_getVar('int', 'and');
+ $stepAutomation = acym_getVar('array', 'acym_action');
+
+ if (empty($stepAutomation['filters'][$or][$and])) die(acym_translation('ACYM_AUTOMATION_NOT_FOUND'));
+
+ $query = acym_get('class.query');
+ $messages = '';
+
+ foreach ($stepAutomation['filters'][$or][$and] as $filterName => $options) {
+ $messages = acym_trigger('onAcymProcessFilterCount_'.$filterName, [&$query, &$options, &$and]);
+ break;
+ }
+
+ echo implode(' | ', $messages);
+ exit;
+ }
+
+ public function countResultsOrTotal()
+ {
+ $or = acym_getVar('int', 'or');
+ $stepAutomation = acym_getVar('array', 'acym_action');
+
+ $query = acym_get('class.query');
+
+ if (!empty($stepAutomation) && !empty($stepAutomation['filters'][$or])) {
+
+ foreach ($stepAutomation['filters'][$or] as $and => $andValues) {
+ $and = intval($and);
+ foreach ($andValues as $filterName => $options) {
+ acym_trigger('onAcymProcessFilter_'.$filterName, [&$query, &$options, &$and]);
+ }
+ }
+ }
+
+ $result = $query->count();
+
+ echo acym_translation_sprintf('ACYM_SELECTED_USERS_TOTAL', $result);
+ exit;
+ }
+
+
+}
+
diff --git a/deployed/acym/administrator/components/com_acym/controllers/bounces.php b/deployed/acym/administrator/components/com_acym/controllers/bounces.php
new file mode 100644
index 00000000..fdff2448
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/controllers/bounces.php
@@ -0,0 +1,309 @@
+breadcrumb[acym_translation('ACYM_BOUNCE_HANDLING')] = acym_completeLink('bounces');
+ }
+
+ function listing()
+ {
+
+ if (!acym_level(2)) {
+ acym_redirect(acym_completeLink('dashboard&task=upgrade&version=enterprise', false, true));
+ }
+ }
+
+
+ function edit()
+ {
+ $ruleClass = acym_get('class.rule');
+ acym_setVar("layout", "edit");
+ $ruleId = acym_getVar("int", "id", 0);
+ $listsClass = acym_get('class.list');
+
+ $rule = "";
+
+ if (!empty($ruleId)) {
+ $rule = $ruleClass->getOneById($ruleId);
+ $this->breadcrumb[acym_translation($rule->name)] = acym_completeLink('bounces&task=edit&id='.$ruleId);
+ } else {
+ $this->breadcrumb[acym_translation('ACYM_NEW')] = acym_completeLink('bounces&task=edit');
+ }
+
+ $data = [
+ "id" => $ruleId,
+ "lists" => $listsClass->getAllWithIdName(),
+ "rule" => $rule,
+ ];
+
+ parent::display($data);
+ }
+
+ public function apply()
+ {
+ $this->saveRule();
+ acym_setVar("id", acym_getVar('array', 'bounce')['id']);
+ $this->edit();
+
+
+ return;
+ }
+
+ public function save()
+ {
+ $this->saveRule();
+ $this->listing();
+
+ return;
+ }
+
+ public function saveRule()
+ {
+ $rule = acym_getVar('array', 'bounce');
+
+ $ruleClass = acym_get('class.rule');
+ $bounceClass = acym_get('class.bounce');
+
+ $rule['executed_on'] = !empty($rule['executed_on']) ? json_encode($rule['executed_on']) : '[]';
+
+ if (!empty($rule['action_user'])) {
+ if (in_array('subscribe_user', $rule['action_user'])) {
+ $rule['action_user']['subscribe_user_list'] = $rule['subscribe_user_list'];
+ }
+ }
+ unset($rule['subscribe_user_list']);
+
+ if (!empty($rule['action_message']) && !in_array('forward_message', $rule['action_message'])) {
+ unset($rule['action_message']['forward_to']);
+ }
+
+ if (empty($rule['id'])) {
+ $rule['ordering'] = $bounceClass->getOrderingNumber() + 1;
+ }
+
+ $ruleObject = new stdClass();
+ $ruleObject->executed_on = '[]';
+ $ruleObject->action_message = '[]';
+ $ruleObject->action_user = '[]';
+
+ foreach ($rule as $column => $value) {
+ acym_secureDBColumn($column);
+ if (is_array($value) || is_object($value)) {
+ $ruleObject->$column = json_encode($value);
+ } else {
+ $ruleObject->$column = strip_tags($value);
+ }
+ }
+
+ $res = $ruleClass->save($ruleObject);
+
+ if (!$res) {
+ acym_enqueueNotification(acym_translation('ACYM_ERROR_SAVING'), 'error', 5000);
+ } else {
+ acym_enqueueNotification(acym_translation('ACYM_SUCCESSFULLY_SAVED'), 'success', 5000);
+ }
+ }
+
+ public function setOrdering()
+ {
+ $order = json_decode(acym_getVar('string', 'order'));
+ $i = 1;
+ $error = false;
+ foreach ($order as $rule) {
+ $query = 'UPDATE #__acym_rule SET `ordering` = '.intval($i).' WHERE `id` = '.intval($rule);
+ $error = acym_query($query) >= 0 ? false : true;
+ $i++;
+ }
+ if ($error) {
+ echo 'error';
+ } else {
+ echo 'updated';
+ }
+ exit;
+ }
+
+ function process()
+ {
+ acym_increasePerf();
+
+ $config = acym_config();
+ $bounceClass = acym_get('helper.bounce');
+ $bounceClass->report = true;
+ if (!$bounceClass->init()) {
+ return;
+ }
+ if (!$bounceClass->connect()) {
+ acym_display($bounceClass->getErrors(), 'error');
+
+ return;
+ }
+ $disp = "\n\n \n";
+ $disp .= ''.addslashes(acym_translation('ACYM_BOUNCE_PROCESS')).' '."\n";
+ $disp .= "\n\n";
+ echo $disp;
+
+ acym_display(acym_translation_sprintf('ACYM_BOUNCE_CONNECT_SUCC', $config->get('bounce_username')), 'success');
+ $nbMessages = $bounceClass->getNBMessages();
+ acym_display(acym_translation_sprintf('ACYM_NB_MAIL_MAILBOX', $nbMessages), 'info');
+
+ if (empty($nbMessages)) {
+ exit;
+ }
+
+ $bounceClass->handleMessages();
+ $bounceClass->close();
+
+ $cronHelper = acym_get('helper.cron');
+ $cronHelper->messages[] = acym_translation_sprintf('ACYM_NB_MAIL_MAILBOX', $nbMessages);
+ $cronHelper->detailMessages = $bounceClass->messages;
+ $cronHelper->saveReport();
+
+ if ($config->get('bounce_max', 0) != 0 && $nbMessages > $config->get('bounce_max', 0)) {
+ $url = acym_completeLink('bounces&task=process&continuebounce=1', true, true);
+ if (acym_getVar('int', 'continuebounce')) {
+ echo '';
+ } else {
+ echo '';
+ }
+ }
+
+ echo "";
+ while ($bounceClass->obend-- > 0) {
+ ob_start();
+ }
+ exit;
+ }
+
+ function saveconfig()
+ {
+ $this->_saveconfig();
+
+ return $this->listing();
+ }
+
+ function _saveconfig()
+ {
+ acym_checkToken();
+
+ $config = acym_config();
+ $newConfig = acym_getVar('array', 'config', [], 'POST');
+ if (!empty($newConfig['bounce_username'])) {
+ $newConfig['bounce_username'] = acym_punycode($newConfig['bounce_username']);
+ }
+
+ $newConfig['auto_bounce_next'] = min($config->get('auto_bounce_last', time()), time()) + $newConfig['auto_bounce_frequency'];
+
+ $status = $config->save($newConfig);
+
+ if ($status) {
+ acym_enqueueNotification(acym_translation('ACYM_SUCCESSFULLY_SAVED'), 'message');
+ } else {
+ acym_enqueueNotification(acym_translation('ACYM_ERROR_SAVING'), 'error');
+ }
+
+ $config->load();
+ }
+
+ function chart()
+ {
+ acym_setVar('layout', 'chart');
+
+ return parent::display();
+ }
+
+ function test()
+ {
+
+ $bounceClass = acym_get('class.bounce');
+
+ if ($bounceClass->getOrderingNumber() < 1) {
+ acym_enqueueNotification(acym_translation('ACYM_NO_RULES'), 'error', 5000);
+
+ $this->listing();
+
+ return;
+ }
+
+ acym_increasePerf();
+ $config = acym_config();
+ $bounceClass = acym_get('helper.bounce');
+ $bounceClass->report = true;
+
+ if ($bounceClass->init()) {
+ if ($bounceClass->connect()) {
+ $nbMessages = $bounceClass->getNBMessages();
+ acym_enqueueNotification(acym_translation_sprintf('ACYM_BOUNCE_CONNECT_SUCC', $config->get('bounce_username')), "success", 5000);
+ $bounceClass->close();
+ if (!empty($nbMessages)) {
+ acym_enqueueNotification(
+ [
+ acym_translation_sprintf('ACYM_NB_MAIL_MAILBOX', $nbMessages),
+ acym_modal(
+ acym_translation('ACYM_CLICK_BOUNCE'),
+ '',
+ null,
+ 'data-reveal-larger',
+ 'data-ajax="true" data-iframe="&ctrl=bounces&task=process" class="acym__color__light-blue cursor-pointer" style="margin: 0"'
+ ),
+ ]
+ );
+ }
+ } else {
+ $errors = $bounceClass->getErrors();
+ if (!empty($errors)) {
+ acym_enqueueNotification($errors, 'error');
+ $errorString = implode(' ', $errors);
+ $port = $config->get('bounce_port', '');
+ if (preg_match('#certificate#i', $errorString) && !$config->get('bounce_certif', false)) {
+ acym_enqueueNotification('You may need to turn ON the option '.acym_translation('ACYM_SELF_SIGNED_CERTIFICATE').' ', 'warning');
+ } elseif (!empty($port) && !in_array($port, ['993', '143', '110'])) {
+ acym_enqueueNotification(acym_translation('ACYM_BOUNCE_WRONG_PORT'), 'warning');
+ }
+ }
+ }
+ }
+
+ return $this->listing();
+ }
+
+ function reinstall()
+ {
+ $bounceClass = acym_get('class.bounce');
+ $bounceClass->cleanTable();
+
+ $updateHelper = acym_get('helper.update');
+ $updateHelper->installBounceRules();
+
+ return $this->listing();
+ }
+
+ public function config()
+ {
+ acym_redirect(acym_completeLink('configuration', false, true));
+ }
+
+ public function delete()
+ {
+ $rulesSelected = acym_getVar('array', 'elements_checked');
+
+ $ruleClass = acym_get('class.rule');
+ $ruleClass->delete($rulesSelected);
+
+ $this->listing();
+ }
+}
+
diff --git a/deployed/acym/administrator/components/com_acym/controllers/campaigns.php b/deployed/acym/administrator/components/com_acym/controllers/campaigns.php
new file mode 100644
index 00000000..4406515f
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/controllers/campaigns.php
@@ -0,0 +1,1347 @@
+breadcrumb[acym_translation('ACYM_CAMPAIGNS')] = acym_completeLink('campaigns');
+ $this->loadScripts = [
+ 'edit' => ['colorpicker', 'datepicker', 'thumbnail', 'foundation-email', 'parse-css'],
+ 'save' => ['colorpicker', 'datepicker', 'thumbnail', 'foundation-email', 'parse-css'],
+ ];
+ acym_setVar('edition', '1');
+ header('X-XSS-Protection:0');
+ }
+
+ public function listing()
+ {
+ acym_setVar("layout", "listing");
+ $status = acym_getVar('string', "campaigns_status", '');
+ $searchFilter = acym_getVar('string', 'campaigns_search', '');
+ $tagFilter = acym_getVar('string', 'campaigns_tag', '');
+ $ordering = acym_getVar('string', 'campaigns_ordering', 'id');
+ $orderingSortOrder = acym_getVar('string', 'campaigns_ordering_sort_order', 'desc');
+
+ $campaignsPerPage = acym_getCMSConfig('list_limit', 20);
+ $page = acym_getVar('int', 'campaigns_pagination_page', 1);
+
+ $campaignClass = acym_get('class.campaign');
+ $matchingCampaigns = $campaignClass->getMatchingCampaigns(
+ [
+ 'ordering' => $ordering,
+ 'search' => $searchFilter,
+ 'campaignsPerPage' => $campaignsPerPage,
+ 'offset' => ($page - 1) * $campaignsPerPage,
+ 'tag' => $tagFilter,
+ 'ordering_sort_order' => $orderingSortOrder,
+ 'status' => $status,
+ ]
+ );
+
+ $pagination = acym_get('helper.pagination');
+ $pagination->setStatus($matchingCampaigns['total'], $page, $campaignsPerPage);
+
+ $data = [
+ 'allCampaigns' => $matchingCampaigns['campaigns'],
+ 'allTags' => acym_get('class.tag')->getAllTagsByType('mail'),
+ 'allStatusFilter' => $this->getCountStatusFilter($matchingCampaigns['campaigns']),
+ 'pagination' => $pagination,
+ "search" => $searchFilter,
+ 'ordering' => $ordering,
+ 'status' => $status,
+ 'tag' => $tagFilter,
+ 'orderingSortOrder' => $orderingSortOrder,
+ ];
+
+ parent::display($data);
+ }
+
+ public function chooseTemplate()
+ {
+ acym_setVar('layout', 'choose_email');
+ acym_setVar('step', 'chooseTemplate');
+
+ $campaignId = acym_getVar("int", "id", 0);
+ $campaignClass = acym_get('class.campaign');
+ $searchFilter = acym_getVar('string', 'mailchoose_search', '');
+ $tagFilter = acym_getVar('string', 'mailchoose_tag', '');
+ $ordering = acym_getVar('string', 'mailchoose_ordering', 'creation_date');
+ $orderingSortOrder = acym_getVar('string', 'mailchoose_ordering_sort_order', 'DESC');
+ $type = acym_getVar('string', 'mailchoose_type', 'custom');
+ $campaign = $campaignClass->getOneByIdWithMail($campaignId);
+
+ if (!empty($campaign)) {
+ $this->breadcrumb[acym_escape($campaign->name)] = '';
+ } else {
+ $this->breadcrumb[acym_translation('ACYM_NEW_CAMPAIGN')] = '';
+ }
+
+ if (!empty($campaign->sent)) {
+ $this->summary();
+
+ return;
+ }
+
+ $mailsPerPage = 12;
+ $page = acym_getVar('int', 'mailchoose_pagination_page', 1);
+
+ $mailClass = acym_get('class.mail');
+ $matchingMails = $mailClass->getMatchingMails(
+ [
+ 'ordering' => $ordering,
+ 'ordering_sort_order' => $orderingSortOrder,
+ 'search' => $searchFilter,
+ 'mailsPerPage' => $mailsPerPage,
+ 'offset' => ($page - 1) * $mailsPerPage,
+ 'tag' => $tagFilter,
+ 'type' => $type,
+ 'onlyStandard' => true,
+ ]
+ );
+
+ $pagination = acym_get('helper.pagination');
+ $pagination->setStatus($matchingMails['total'], $page, $mailsPerPage);
+
+ foreach ($matchingMails['mails'] as $oneTemplate) {
+ if (empty($oneTemplate->thumbnail)) {
+ $oneTemplate->thumbnail = ACYM_IMAGES.'default_template_thumbnail.png';
+ }
+ }
+
+ $data = [
+ 'allMails' => $matchingMails['mails'],
+ 'allTags' => acym_get('class.tag')->getAllTagsByType('mail'),
+ 'pagination' => $pagination,
+ 'search' => $searchFilter,
+ 'tag' => $tagFilter,
+ 'ordering' => $ordering,
+ 'type' => $type,
+ 'campaignID' => $campaignId,
+ ];
+
+
+ parent::display($data);
+ }
+
+ public function editEmail()
+ {
+ acym_setVar('layout', 'edit_email');
+ acym_setVar('numberattachment', '0');
+ acym_setVar('step', 'editEmail');
+
+ $editor = acym_get('helper.editor');
+ $mailClass = acym_get('class.mail');
+ $mailId = acym_getVar("int", "from", 0);
+ $campaignId = acym_getVar("int", "id", 0);
+ $typeEditor = acym_getVar('string', 'type_editor', '');
+ $config = acym_config();
+
+ $editLink = 'campaigns&task=edit&step=editEmail';
+
+ $checkAutosave = empty($mailId);
+
+ if (empty($campaignId)) {
+ $campaign = new stdClass();
+ $campaign->id = 0;
+ $campaign->name = '';
+ $campaign->tags = [];
+ $campaign->subject = '';
+ $campaign->preheader = '';
+ $campaign->body = '';
+ $campaign->settings = null;
+ } else {
+ $campaignClass = acym_get('class.campaign');
+ $campaign = $campaignClass->getOneByIdWithMail($campaignId);
+ if (empty($mailId)) {
+ $mailId = $campaign->mail_id;
+ }
+ $editLink .= '&id='.$campaignId;
+ }
+
+ if (!empty($campaign->sent) && !empty($campaign->active)) {
+ $this->summary();
+
+ return;
+ }
+
+ if ($mailId == -1) {
+ $campaign->name = '';
+ $campaign->tags = [];
+ $campaign->subject = '';
+ $campaign->preheader = '';
+ $campaign->body = '';
+ $campaign->settings = null;
+ $campaign->attachments = [];
+ $campaign->stylesheet = '';
+ $campaign->headers = '';
+ } elseif (!empty($mailId)) {
+ $mail = $mailClass->getOneById($mailId);
+ $campaign->tags = $mail->tags;
+ $campaign->subject = $mail->subject;
+ $campaign->preheader = $mail->preheader;
+ $campaign->body = $mail->body;
+ $campaign->settings = $mail->settings;
+ $campaign->stylesheet = $mail->stylesheet;
+ $campaign->headers = $mail->headers;
+ $campaign->attachments = empty($mail->attachments) ? [] : json_decode($mail->attachments);
+
+ if (empty($campaignId)) {
+ $editLink .= '&from='.$mailId;
+ }
+ if ($checkAutosave) {
+ $campaign->autosave = $mail->autosave;
+ }
+ }
+ $this->breadcrumb[acym_escape(empty($campaign->name) ? acym_translation('ACYM_NEW_CAMPAIGN') : $campaign->name)] = acym_completeLink($editLink);
+
+ $pluginHelper = acym_get('helper.plugin');
+ $pluginHelper->cleanHtml($campaign->body);
+ $editor->content = $campaign->body;
+ $editor->autoSave = !empty($campaign->autosave) ? $campaign->autosave : '';
+ if (!empty($campaign->settings)) {
+ $editor->settings = $campaign->settings;
+ }
+
+ if (acym_bytes(ini_get('upload_max_filesize')) > acym_bytes(ini_get('post_max_size'))) {
+ $maxupload = ini_get('post_max_size');
+ } else {
+ $maxupload = ini_get('upload_max_filesize');
+ }
+
+ if (!empty($campaign->stylesheet)) {
+ $editor->stylesheet = $campaign->stylesheet;
+ }
+
+ if (empty($typeEditor) && strpos($editor->content, 'acym__wysid__template') !== false) {
+ $typeEditor = 'acyEditor';
+ }
+
+ $editor->editor = $typeEditor;
+ if ($editor->editor != 'acyEditor' || empty($editor->editor)) {
+ if (!isset($campaign->stylesheet)) $campaign->stylesheet = '';
+ $needDisplayStylesheet = ' ';
+ } else {
+ $needDisplayStylesheet = '';
+ }
+
+ $editor->mailId = empty($mailId) ? 0 : $mailId;
+
+ $data = [
+ 'campaignID' => $campaign->id,
+ 'mailInformation' => $campaign,
+ 'allTags' => acym_get('class.tag')->getAllTagsByType('mail'),
+ 'editor' => $editor,
+ 'maxupload' => $maxupload,
+ 'needDisplayStylesheet' => $needDisplayStylesheet,
+ 'social_icons' => $config->get('social_icons', '{}'),
+ ];
+
+ parent::display($data);
+ }
+
+ public function recipients()
+ {
+ acym_setVar("layout", "recipients");
+ $campaignId = acym_getVar("int", "id");
+ $campaignClass = acym_get('class.campaign');
+ $mailClass = acym_get('class.mail');
+ acym_setVar('step', 'recipients');
+
+ if (!empty($campaignId)) {
+ $currentCampaign = $campaignClass->getOneByIdWithMail($campaignId);
+ $this->breadcrumb[acym_escape($currentCampaign->name)] = acym_completeLink('campaigns&task=edit&step=recipients&id='.$campaignId);
+ } else {
+ $currentCampaign = new stdClass();
+ $this->breadcrumb[acym_translation('ACYM_NEW_CAMPAIGN')] = acym_completeLink('campaigns&task=edit&step=recipients');
+ }
+
+ if (!empty($currentCampaign->sent) && !empty($currentCampaign->active)) {
+ $this->summary();
+
+ return;
+ }
+
+ $campaign = [
+ 'campaignInformation' => $campaignId,
+ 'currentCampaign' => $currentCampaign,
+ ];
+
+ if (!empty($currentCampaign->mail_id)) {
+ $campaignLists = $mailClass->getAllListsByMailId($currentCampaign->mail_id);
+ $campaign['campaignListsId'] = array_keys($campaignLists);
+ $campaign['campaignListsSelected'] = json_encode(acym_escapeArrayValues($campaign['campaignListsId']));
+ }
+
+ parent::display($campaign);
+ }
+
+ public function sendSettings()
+ {
+ acym_setVar("layout", "send_settings");
+ acym_setVar('step', 'sendSettings');
+ $campaignId = acym_getVar("int", "id");
+ $campaignClass = acym_get('class.campaign');
+ $campaignInformation = empty($campaignId) ? null : $campaignClass->getOneById($campaignId);
+
+ if (is_null($campaignInformation)) {
+ acym_enqueueNotification(acym_translation("ACYM_CANT_GET_CAMPAIGN_INFORMATION"), 'error', 0);
+ $this->listing();
+
+ return;
+ }
+
+ $from = acym_getVar("string", "from");
+ $config = acym_config();
+
+ $campaignClass = acym_get('class.campaign');
+ $currentCampaign = $campaignClass->getOneByIdWithMail($campaignId);
+ $this->breadcrumb[acym_escape($currentCampaign->name)] = acym_completeLink('campaigns&task=edit&step=sendSettings&id='.$campaignId);
+
+ if (!empty($currentCampaign->sent) && !empty($currentCampaign->active)) {
+ $this->summary();
+
+ return;
+ } elseif (!empty($currentCampaign->sent) && empty($currentCampaign->active)) {
+ $currentCampaign->sending_date = '';
+ }
+
+
+ $lists = acym_getVar('array', 'lists');
+ if (!empty($lists)) {
+ $this->addRecipients();
+ }
+
+ $campaign = [];
+
+ $campaign['currentCampaign'] = $currentCampaign;
+ $campaign['from'] = $from;
+ $campaign['suggestedDate'] = acym_date('1534771620', 'j M Y H:i');
+ $campaign['senderInformations'] = new stdClass();
+ $campaign['config_values'] = new stdClass();
+
+ empty($currentCampaign->from_name) ? $campaign['senderInformations']->from_name = '' : $campaign['senderInformations']->from_name = $currentCampaign->from_name;
+ empty($currentCampaign->from_email) ? $campaign['senderInformations']->from_email = '' : $campaign['senderInformations']->from_email = $currentCampaign->from_email;
+ empty($currentCampaign->reply_to_name) ? $campaign['senderInformations']->reply_to_name = '' : $campaign['senderInformations']->reply_to_name = $currentCampaign->reply_to_name;
+ empty($currentCampaign->reply_to_email) ? $campaign['senderInformations']->reply_to_email = '' : $campaign['senderInformations']->reply_to_email = $currentCampaign->reply_to_email;
+
+ $campaign['config_values']->from_name = $config->get('from_name', '');
+ $campaign['config_values']->from_email = $config->get('from_email', '');
+ $campaign['config_values']->reply_to_name = $config->get('replyto_name', '');
+ $campaign['config_values']->reply_to_email = $config->get('replyto_email', '');
+
+ return parent::display($campaign);
+ }
+
+ public function saveEditEmail($ajax = false)
+ {
+ acym_checkToken();
+
+ $campaignClass = acym_get('class.campaign');
+ $mailClass = acym_get('class.mail');
+ $formData = acym_getVar('array', 'mail', []);
+ $allowedFields = acym_getColumns('mail');
+ $campaignId = acym_getVar("int", "id", 0);
+
+ if (empty($campaignId)) {
+ $mail = new stdClass();
+ $mail->creation_date = acym_date('now', 'Y-m-d H:i:s', false);
+ $mail->type = 'standard';
+ $mail->template = 0;
+ $mail->library = 0;
+
+ $campaign = new stdClass();
+ $campaign->draft = 1;
+ $campaign->active = 1;
+ $campaign->scheduled = 0;
+ $campaign->sent = 0;
+ } else {
+ $campaign = $campaignClass->getOneById($campaignId);
+ $mail = $mailClass->getOneById($campaign->mail_id);
+ }
+
+ foreach ($formData as $name => $data) {
+ if (!in_array($name, $allowedFields)) {
+ continue;
+ }
+ $mail->{acym_secureDBColumn($name)} = $data;
+ }
+
+ if (empty($mail->name)) {
+ $mail->name = $mail->subject;
+ }
+
+ $mail->body = acym_getVar('string', 'editor_content', '', 'REQUEST', ACYM_ALLOWRAW);
+ $mail->settings = acym_getVar('string', 'editor_settings', '', 'REQUEST', ACYM_ALLOWRAW);
+ $mail->stylesheet = acym_getVar('string', 'editor_stylesheet', '', 'REQUEST', ACYM_ALLOWRAW);
+ $mail->headers = acym_getVar('string', 'editor_headers', '', 'REQUEST', ACYM_ALLOWRAW);
+ $mail->drag_editor = strpos($mail->body, 'acym__wysid__template') === false ? 0 : 1;
+
+ $mail->tags = acym_getVar("array", "template_tags", []);
+
+ $newAttachments = [];
+ $attachments = acym_getVar('array', 'attachments', []);
+ $config = acym_config();
+ if (!empty($attachments)) {
+ foreach ($attachments as $id => $filepath) {
+ if (empty($filepath)) {
+ continue;
+ }
+ $attachment = new stdClass();
+ $attachment->filename = $filepath;
+ $attachment->size = filesize(ACYM_ROOT.$filepath);
+ $extension = substr($attachment->filename, strrpos($attachment->filename, '.'));
+
+ if (preg_match('#\.(php.?|.?htm.?|pl|py|jsp|asp|sh|cgi)#Ui', $attachment->filename)) {
+ acym_enqueueMessage(acym_translation_sprintf('ACYM_ACCEPTED_TYPE', substr($attachment->filename, strrpos($attachment->filename, '.') + 1), $config->get('allowed_files')), 'notice');
+ continue;
+ }
+ $attachment->filename = str_replace(['.', ' '], '_', substr($attachment->filename, 0, strpos($attachment->filename, $extension))).$extension;
+
+ $newAttachments[] = $attachment;
+ }
+ if (!empty($mail->attachments) && is_array(json_decode($mail->attachments))) {
+ $newAttachments = array_merge(json_decode($mail->attachments), $newAttachments);
+ }
+ $mail->attachments = $newAttachments;
+ }
+
+ if (empty($mail->attachments)) {
+ unset($mail->attachments);
+ }
+ if (!empty($mail->attachments) && !is_string($mail->attachments)) {
+ $mail->attachments = json_encode($mail->attachments);
+ }
+
+ if ($mailID = $mailClass->save($mail)) {
+ if (acym_getVar('string', 'nextstep', '') == 'listing') {
+ acym_enqueueNotification(acym_translation('ACYM_SUCCESSFULLY_SAVED'), 'success', 8000);
+ }
+ } else {
+ acym_enqueueNotification(acym_translation('ACYM_ERROR_SAVING'), 'error', 0);
+ if (!empty($mailClass->errors)) {
+ acym_enqueueNotification($mailClass->errors, 'error', 0);
+ }
+
+ if (!$ajax) {
+ $this->listing();
+
+ return;
+ } else {
+ return false;
+ }
+ }
+
+ $campaign->mail_id = $mailID;
+ $campaign->id = $campaignClass->save($campaign);
+
+ if ($ajax) {
+ return $campaign->id;
+ }
+
+ acym_setVar("id", $campaign->id);
+
+ $this->edit();
+ }
+
+ public function saveRecipients()
+ {
+ $allLists = json_decode(acym_getVar("string", "lists_selected"));
+ $campaignId = acym_getVar("int", "id");
+
+ $campaignClass = acym_get('class.campaign');
+ $currentCampaign = $campaignClass->getOneByIdWithMail($campaignId);
+
+
+ if ($currentCampaign->sent && !$currentCampaign->active) {
+ $mailStatClass = acym_get('class.mailstat');
+ $listClass = acym_get('class.list');
+ $mailStat = $mailStatClass->getOneRowByMailId($currentCampaign->mail_id);
+ $mailStat->total_subscribers = $listClass->getTotalSubCount($allLists);
+ $mailStatClass->save($mailStat);
+ } elseif (!empty($currentCampaign->mail_id)) {
+ $campaignClass->manageListsToCampaign($allLists, $currentCampaign->mail_id);
+ if (acym_getVar('string', 'nextstep', '') == 'listing') {
+ acym_enqueueNotification(acym_translation_sprintf("ACYM_LIST_IS_SAVED", $currentCampaign->name), 'success', 8000);
+ }
+ }
+
+ $this->edit();
+ }
+
+ public function saveSendSettings()
+ {
+ $campaignClass = acym_get('class.campaign');
+ $mailClass = acym_get('class.mail');
+ $campaignId = acym_getVar('int', 'id');
+ $senderInformation = acym_getVar('', 'senderInformation');
+ $isScheduled = acym_getVar('string', 'isScheduled');
+ $sendingDate = acym_getVar('string', 'sendingDate');
+
+ $campaignInformation = $campaignClass->getOneById($campaignId);
+
+ if (is_null($campaignInformation)) {
+ acym_enqueueNotification(acym_translation("ACYM_CAMPAIGN_DOESNT_EXISTS"), 'error', 0);
+
+ $this->listing();
+
+ return;
+ }
+ $currentCampaign = $campaignClass->getOneById($campaignId);
+ empty($currentCampaign->mail_id) ? : $currentMail = $mailClass->getOneById($currentCampaign->mail_id);
+
+ if (empty($currentMail) || empty($senderInformation)) {
+ $this->listing();
+
+ return;
+ }
+
+ $currentMail->from_name = $senderInformation['from_name'];
+ $currentMail->from_email = $senderInformation['from_email'];
+ $currentMail->reply_to_name = $senderInformation['reply_to_name'];
+ $currentMail->reply_to_email = $senderInformation['reply_to_email'];
+ $currentMail->bcc = $senderInformation['bcc'];
+
+
+ $mailClass->save($currentMail);
+
+ if (!empty($isScheduled) && empty($currentCampaign->sent)) {
+ if ($isScheduled == 'true') {
+ $currentCampaign->scheduled = 1;
+ if (!empty($sendingDate) && empty($currentCampaign->sent)) $currentCampaign->sending_date = acym_date(acym_getTime($sendingDate), 'Y-m-d H:i:s', false);
+ } else {
+ $currentCampaign->scheduled = 0;
+ $currentCampaign->sending_date = null;
+ }
+ } elseif (empty($isScheduled)) {
+ $this->listing();
+
+ return;
+ }
+
+ if ($campaignClass->save($currentCampaign)) {
+ if (acym_getVar('string', 'nextstep', '') == 'listing') {
+ acym_enqueueNotification(acym_translation('ACYM_SUCCESSFULLY_SAVED'), 'success', 8000);
+ }
+ } else {
+ acym_enqueueNotification(acym_translation('ACYM_ERROR_SAVING'), 'error', 0);
+ if (!empty($campaignClass->errors)) {
+ acym_enqueueNotification($campaignClass->errors, 'error', 0);
+ }
+
+ $this->listing();
+
+ return;
+ }
+
+ $this->edit();
+ }
+
+ public function duplicate()
+ {
+ $campaignsSelected = acym_getVar('int', 'elements_checked');
+
+ $campaignClass = acym_get('class.campaign');
+ $mailClass = acym_get('class.mail');
+ $campaignId = 0;
+
+ foreach ($campaignsSelected as $campaignSelected) {
+
+ $campaign = $campaignClass->getOneById($campaignSelected);
+
+ unset($campaign->id);
+ unset($campaign->sending_date);
+ $campaign->draft = 1;
+ $campaign->sent = 0;
+
+ $mail = $mailClass->getOneById($campaign->mail_id);
+ $oldMailId = $mail->id;
+ unset($mail->id);
+ $mail->creation_date = acym_date('now', 'Y-m-d H:i:s', false);
+ $mail->name .= '_copy';
+ $idNewMail = $mailClass->save($mail);
+
+ $campaign->mail_id = $idNewMail;
+ $campaignId = $campaignClass->save($campaign);
+
+ $allLists = $campaignClass->getListsForCampaign($oldMailId);
+
+ $campaignClass->manageListsToCampaign($allLists, $idNewMail);
+ }
+
+ acym_enqueueNotification(acym_translation('ACYM_CAMPAIGN_DUPLICATED_SUCCESS'), 'success', '10000');
+
+ if (count($campaignsSelected) == 1 && acym_getVar('string', 'step', '') == 'summary') {
+ acym_setVar('id', $campaignId);
+ $this->editEmail();
+ } else {
+ $this->listing();
+ }
+
+ return;
+ }
+
+ public function saveSummary()
+ {
+ $this->edit();
+ }
+
+ public function summary()
+ {
+ acym_setVar('step', 'summary');
+ acym_setVar('layout', 'summary');
+ $campaignId = acym_getVar('int', 'id');
+ $campaignClass = acym_get('class.campaign');
+
+ $campaign = empty($campaignId) ? null : $campaignClass->getOneByIdWithMail($campaignId);
+
+ if (is_null($campaign)) {
+ acym_enqueueNotification(acym_translation('ACYM_CANT_GET_CAMPAIGN_INFORMATION'), 'error', 0);
+ $this->listing();
+
+ return;
+ }
+
+ $userClass = acym_get('class.user');
+ $mailClass = acym_get('class.mail');
+ $config = acym_config();
+ $nbSubscribers = 0;
+
+ $campaignLists = $mailClass->getAllListsWithCountSubscribersByMailIds([$campaign->mail_id]);
+ $mailData = $mailClass->getOneById($campaign->mail_id);
+
+ if (!empty($campaignLists)) {
+ $listsIds = [];
+ foreach ($campaignLists as $oneList) {
+ $listsIds[] = $oneList->list_id;
+ }
+ $listClass = acym_get('class.list');
+ $nbSubscribers = $listClass->getSubscribersCount($listsIds);
+ }
+
+ $mailData->from_name = empty($mailData->from_name) ? $config->get('from_name') : $mailData->from_name;
+ $mailData->from_email = empty($mailData->from_email) ? $config->get('from_email') : $mailData->from_email;
+
+
+ $useFromInReply = $config->get('from_as_replyto');
+ $replytoName = $config->get('replyto_name');
+ $replytoEmail = $config->get('replyto_email');
+
+ if (!empty($mailData->reply_to_name)) {
+ $replytoName = $mailData->reply_to_name;
+ } elseif ($useFromInReply != 0 || empty($replytoName)) {
+ $replytoName = $config->get('from_name');
+ }
+
+ if (!empty($mailData->reply_to_email)) {
+ $replytoEmail = $mailData->reply_to_email;
+ } elseif ($useFromInReply != 0 || empty($replytoEmail)) {
+ $replytoEmail = $config->get('from_email');
+ }
+
+ $mailData->reply_to_name = $replytoName;
+ $mailData->reply_to_email = $replytoEmail;
+
+ $campaignType = empty($campaign->scheduled) ? 'now' : 'scheduled';
+
+ acym_trigger('replaceContent', [&$mailData, false]);
+ $receiver = $userClass->getOneByEmail(acym_currentUserEmail());
+ if (empty($receiver)) {
+ $receiver = new stdClass();
+ $receiver->email = acym_currentUserEmail();
+ $newID = $userClass->save($receiver);
+ $receiver = $userClass->getOneById($newID);
+ }
+ acym_trigger('replaceUserInformation', [&$mailData, &$receiver, false]);
+
+ $data = [
+ 'config' => $config,
+ 'campaignInformation' => $campaign,
+ 'mailInformation' => $mailData,
+ 'listsReceiver' => $campaignLists,
+ 'nbSubscribers' => $nbSubscribers,
+ 'campaignType' => $campaignType,
+ ];
+
+ $this->breadcrumb[acym_escape($campaign->name)] = acym_completeLink('campaigns&task=edit&step=summary&id='.$campaign->id);
+ parent::display($data);
+ }
+
+ function unpause_campaign()
+ {
+ $id = acym_getVar('int', 'id', 0);
+ if (empty($id)) {
+ acym_enqueueNotification(acym_translation('ACYM_CAMPAIGN_NOT_FOUND'), 'error', 10000);
+ $this->listing();
+
+ return;
+ }
+
+ acym_redirect(acym_completeLink('queue').'&task=playPauseSending&acym__queue__play_pause__active__new_value=1&acym__queue__play_pause__campaign_id='.$id);
+
+ return;
+ }
+
+ public function stopSending()
+ {
+ acym_checkToken();
+
+ $campaignID = acym_getVar('int', 'stopSendingCampaignId');
+ $campaignClass = acym_get('class.campaign');
+
+ if (!empty($campaignID)) {
+ $campaign = new stdClass();
+ $campaign->id = $campaignID;
+ $campaign->active = 0;
+ $campaign->draft = 1;
+
+ $campaignId = $campaignClass->save($campaign);
+ if (empty($campaignId)) {
+ acym_enqueueNotification(acym_translation('ACYM_CAMPAIGN_CANT_BE_SAVED'), 'error', 0);
+ } else {
+ acym_enqueueNotification(acym_translation('ACYM_SUCCESSFULLY_SAVED'), 'success', 8000);
+ }
+ } else {
+ acym_enqueueNotification(acym_translation('ACYM_CAMPAIGN_CANT_BE_SAVED'), 'error', 0);
+ }
+ $this->listing();
+ }
+
+ public function stopScheduled()
+ {
+ acym_checkToken();
+
+ $campaignID = acym_getVar('int', 'stopScheduledCampaignId');
+ $campaignClass = acym_get('class.campaign');
+
+ if (!empty($campaignID)) {
+ $campaign = new stdClass();
+ $campaign->id = $campaignID;
+ $campaign->active = 0;
+ $campaign->draft = 1;
+
+ $campaignId = $campaignClass->save($campaign);
+ if (empty($campaignId)) {
+ acym_enqueueNotification(acym_translation('ACYM_CAMPAIGN_CANT_BE_SAVED'), 'error', 0);
+ } else {
+ acym_enqueueNotification(acym_translation('ACYM_SUCCESSFULLY_SAVED'), 'success', 8000);
+ }
+ } else {
+ acym_enqueueNotification(acym_translation('ACYM_CAMPAIGN_CANT_BE_SAVED'), 'error', 0);
+ }
+ $this->listing();
+ }
+
+ public function confirmCampaign()
+ {
+ $campaignId = acym_getVar('int', 'id');
+ $campaignSendingDate = acym_getVar('string', 'sending_date');
+
+ $campaignClass = acym_get('class.campaign');
+
+ $campaign = new stdClass();
+ $campaign->id = $campaignId;
+ $campaign->draft = 0;
+ $campaign->active = 1;
+
+ $resultSave = $campaignClass->save($campaign);
+
+ if ($resultSave) {
+ acym_enqueueNotification(acym_translation_sprintf('ACYM_CONFIRMED_CAMPAIGN', acym_date($campaignSendingDate, 'j F Y H:i')), 'success', 8000);
+ } else {
+ acym_enqueueNotification(acym_translation('ACYM_CANT_CONFIRM_CAMPAIGN').' : '.end($campaignClass->errors), 'error', 0);
+ }
+
+ $this->listing();
+ }
+
+ public function saveAsDraftCampaign()
+ {
+ $campaignId = acym_getVar('int', 'id');
+ $campaignClass = acym_get('class.campaign');
+
+ $campaign = new stdClass();
+ $campaign->id = $campaignId;
+ $campaign->draft = 1;
+ $campaign->active = 0;
+
+ $resultSave = $campaignClass->save($campaign);
+
+ if ($resultSave) {
+ acym_enqueueNotification(acym_translation('ACYM_CAMPAIGN_SUCCESSFULLY_SAVE_AS_DRAFT'), 'success', 8000);
+ } else {
+ acym_enqueueNotification(acym_translation('ACYM_CAMPAIGN_CANT_BE_SAVED').' : '.end($campaignClass->errors), 'error', 0);
+ }
+
+ $this->listing();
+ }
+
+ public function getAll()
+ {
+ $campaignClass = acym_get('class.campaign');
+ $listClass = acym_get('class.list');
+
+ $allCampaigns = $campaignClass->getAll();
+
+ foreach ($allCampaigns as $campaign) {
+ $campaign->tags = $campaignClass->getAllTagsByCampaignId($campaign->id);
+ $lists = $campaignClass->getAllListsByCampaignId($campaign->id)[0]->name;
+ if (!empty($lists)) {
+ $campaign->lists = $campaignClass->getAllListsByCampaignId($campaign->id);
+ $campaign->subscribers = 0;
+ foreach ($campaign->lists as $list) {
+ $campaign->subscribers += $listClass->getSubscribersCountByListId($list->id);
+ }
+ }
+
+ $campaign->trigger = $campaignClass->getAllTriggerByCampaignId($campaign->id);
+ if (empty($campaign->trigger->automation_id)) {
+ $campaign->trigger = null;
+ }
+
+ $campaign->sending = 0;
+ }
+
+ return $allCampaigns;
+ }
+
+ public function getCountStatusFilter($allCampaigns)
+ {
+ $allCountStatus = new stdClass();
+ $allCountStatus->sending = 0;
+ $allCountStatus->scheduled = 0;
+ $allCountStatus->sent = 0;
+ $allCountStatus->draft = 0;
+
+ foreach ($allCampaigns as $campaign) {
+ $allCountStatus->scheduled += $campaign->scheduled;
+ $allCountStatus->sent += $campaign->sent;
+ $allCountStatus->draft += $campaign->draft;
+ }
+
+ return $allCountStatus;
+ }
+
+ public function cancelDashboardAndGetCampaignsAjax()
+ {
+ $campaignId = acym_getVar('int', 'id');
+ $campaignClass = acym_get('class.campaign');
+
+ if (!empty($campaignId)) {
+ $campaign = new stdClass();
+ $campaign->id = $campaignId;
+ $campaign->active = 0;
+ $campaign->draft = 1;
+
+ $campaignId = $campaignClass->save($campaign);
+ if (empty($campaignId)) {
+ echo 'error';
+ exit;
+ }
+
+ $campaigns = $campaignClass->getCampaignForDashboard();
+
+ if (empty($campaigns)) {
+ echo ''.acym_translation('ACYM_NONE_OF_YOUR_CAMPAIGN_SCHEDULED_GO_SCHEDULE_ONE').' ';
+ exit;
+ }
+
+ $echo = '';
+
+ foreach ($campaigns as $campaign) {
+ $echo .= '
+
'.$campaign->name.'
+
'.acym_translation('ACYM_SCHEDULED').' : '.acym_getDate($campaign->sending_date, 'M. j, Y').'
+
'.acym_translation('ACYM_CANCEL_SCHEDULING').'
+
+ ';
+ }
+ echo $echo;
+ exit;
+ } else {
+ echo 'error';
+ exit;
+ }
+ }
+
+ public function addQueue()
+ {
+ acym_checkToken();
+
+ $campaignID = acym_getVar('int', 'id', 0);
+
+ if (empty($campaignID)) {
+ acym_enqueueNotification(acym_translation('ACYM_CAMPAIGN_NOT_FOUND'), 'error', 10000);
+ } else {
+ $campaignClass = acym_get('class.campaign');
+ $campaign = $campaignClass->getOneByIdWithMail($campaignID);
+
+ if ($campaign->sent) {
+ acym_enqueueNotification(acym_translation_sprintf('ACYM_CAMPAIGN_ALREADY_SENT', $campaign->name), 'error', 10000);
+
+ $this->_redirectAfterQueued();
+
+ return;
+ }
+
+ $status = $campaignClass->send($campaignID);
+
+ if ($status) {
+ acym_enqueueNotification(acym_translation_sprintf('ACYM_CAMPAIGN_ADDED_TO_QUEUE', $campaign->name), 'info', 5000);
+ } else {
+ if (empty($campaignClass->errors)) {
+ acym_enqueueNotification(acym_translation_sprintf('ACYM_ERROR_QUEUE_CAMPAIGN', $campaign->name), 'error', 10000);
+ } else {
+ acym_enqueueNotification($campaignClass->errors, 'error', 6000);
+ }
+ }
+ }
+
+ $this->_redirectAfterQueued();
+ }
+
+ private function _redirectAfterQueued()
+ {
+ $config = acym_config();
+ if (!acym_level(1) || $config->get('cron_last', 0) < (time() - 43200)) {
+ acym_redirect(acym_completeLink('queue&task=campaigns', false, true));
+ } else {
+ $this->listing();
+ }
+ }
+
+ public function countNumberOfRecipients()
+ {
+ $listsSelected = acym_getVar("array", "listsSelected", []);
+ if (empty($listsSelected)) {
+ echo 0;
+ exit;
+ }
+
+ $listClass = acym_get('class.list');
+ echo $listClass->getTotalSubCount($listsSelected);
+ exit;
+ }
+
+ public function deleteAttach()
+ {
+ $mailid = acym_getVar('int', 'mail', 0);
+ $attachid = acym_getVar('int', 'id', 0);
+
+ if (!empty($mailid) && $attachid >= 0) {
+ $mailClass = acym_get('class.mail');
+
+ return $mailClass->deleteOneAttachment($mailid, $attachid);
+ } else {
+ echo 'error';
+ }
+ }
+
+ public function test()
+ {
+ $result = new stdClass();
+ $result->type = 'info';
+ $result->timer = 5000;
+ $result->message = '';
+
+ $campaignId = acym_getVar('int', 'id', 0);
+
+ $campaignClass = acym_get('class.campaign');
+ $campaign = $campaignClass->getOneById($campaignId);
+
+ if (empty($campaign)) {
+ $result->type = 'error';
+ $result->timer = '';
+ $result->message = acym_translation('ACYM_CAMPAIGN_NOT_FOUND');
+ exit;
+ }
+
+ $mailerHelper = acym_get('helper.mailer');
+ $mailerHelper->autoAddUser = true;
+ $mailerHelper->checkConfirmField = false;
+ $mailerHelper->report = false;
+
+
+ $report = [];
+
+ $testEmails = explode(',', acym_getVar('string', 'test_emails'));
+ foreach ($testEmails as $oneAddress) {
+ if (!$mailerHelper->sendOne($campaign->mail_id, $oneAddress, true)) {
+ $result->type = 'error';
+ $result->timer = '';
+ }
+
+ if (!empty($mailerHelper->reportMessage)) {
+ $report[] = $mailerHelper->reportMessage;
+ }
+ }
+
+ $result->message = implode(' ', $report);
+ echo json_encode($result);
+ exit;
+ }
+
+ public function tests()
+ {
+ $campaignClass = acym_get('class.campaign');
+ acym_setVar('step', 'tests');
+ acym_setVar('layout', 'tests');
+ $campaignId = acym_getVar('int', 'id', 0);
+
+ $campaign = $campaignClass->getOneByIdWithMail($campaignId);
+
+ if (empty($campaign->id)) {
+ acym_enqueueNotification(acym_translation("ACYM_CANT_GET_CAMPAIGN_INFORMATION"), 'error', 0);
+ $this->listing();
+
+ return;
+ }
+
+ $testEmails = acym_getVar('array', 'test_emails', [acym_currentUserEmail()]);
+ foreach ($testEmails as $oneEmail) {
+ $defaultEmails[$oneEmail] = $oneEmail;
+ }
+
+ $data = [
+ 'id' => $campaign->id,
+ 'test_emails' => $defaultEmails,
+ 'upgrade' => !acym_level(2) ? true : false,
+ 'version' => 'enterprise',
+ ];
+
+ $this->breadcrumb[acym_escape($campaign->name)] = acym_completeLink('campaigns&task=edit&step=tests&id='.$campaign->id);
+ parent::display($data);
+ }
+
+ public function saveTests()
+ {
+ $this->edit();
+ }
+
+ public function checkContent()
+ {
+ $campaignId = acym_getVar('int', 'id', 0);
+ $campaignClass = acym_get('class.campaign');
+ $campaign = $campaignClass->getOneByIdWithMail($campaignId);
+
+ $spamWords = [
+ '4U',
+ 'you are a winner',
+ 'For instant access',
+ 'Accept credit cards',
+ 'Claims you registered with',
+ 'For just $',
+ 'Act now!',
+ 'Don’t hesitate!',
+ 'Click below',
+ 'Free',
+ 'income',
+ 'Click here',
+ 'Click to remove',
+ 'All natural',
+ 'Amazing',
+ 'Compare rates',
+ 'Apply Online',
+ 'your business',
+ 'As seen on',
+ 'all orders',
+ 'Auto email removal',
+ 'bankruptcy',
+ 'debt',
+ 'Be amazed',
+ 'Copy accurately',
+ 'Be your own boss',
+ 'Being a member',
+ 'Big bucks',
+ 'Credit card',
+ 'Bill',
+ 'Cures baldness',
+ 'Billing address',
+ 'Billion dollars',
+ 'Dear friend',
+ 'Brand new pager',
+ 'Bulk email',
+ 'Different reply to',
+ 'Buy direct',
+ 'Dig up dirt',
+ 'Full refund',
+ 'Buying judgments',
+ 'Direct email',
+ 'Get It Now',
+ 'Cable converter',
+ 'Direct marketing',
+ 'Get paid',
+ 'Get started now',
+ 'Call now',
+ 'Do it today',
+ 'Gift certificate',
+ 'Calling creditors',
+ 'Don’t delete',
+ 'Great offer',
+ 'Can’t live without',
+ 'Drastically reduced',
+ 'Guarantee',
+ 'Cancel at any time',
+ 'Earn per week',
+ 'Have you been turned down?',
+ 'Easy terms',
+ 'Hidden assets',
+ 'Eliminate bad credit',
+ 'Home employment',
+ 'Cash',
+ 'Email harvest',
+ 'Human growth hormone',
+ 'Casino',
+ 'Email marketing',
+ 'Expect to earn',
+ 'In accordance with laws',
+ 'Fantastic deal',
+ 'Increase sales',
+ 'Viagra',
+ 'Increase traffic',
+ 'Insurance',
+ 'Find out anything',
+ 'Investment decision',
+ 'it\'s legal',
+ 'It\'s effective',
+ 'Join millions of',
+ 'No questions asked',
+ 'Reverses aging',
+ 'No selling',
+ 'Risk',
+ 'Limited time only',
+ 'No strings attached',
+ 'Round the world',
+ 'Not intended',
+ 'Lose weight',
+ 'Off shore',
+ 'Safeguard notice',
+ 'Lower interest rates',
+ 'Offer expires',
+ 'Satisfaction guaranteed',
+ 'Lower monthly payment',
+ 'coupon',
+ 'Save $',
+ 'Lowest price',
+ 'Luxury car',
+ 'Save up to',
+ 'Once in a lifetime',
+ 'Score with babes',
+ 'Marketing solutions',
+ 'Mass email',
+ 'guaranteed',
+ 'See for yourself',
+ 'Meet singles',
+ 'One time mailing',
+ 'Sent in compliance',
+ 'Member stuff',
+ 'opportunity',
+ 'Online pharmacy',
+ 'Serious only',
+ 'MLM',
+ 'Only $',
+ 'Shopping spree',
+ 'Social security number',
+ 'trial offer',
+ 'Special promotion',
+ 'More Internet traffic',
+ 'Stock alert',
+ 'Outstanding values',
+ 'Pennies a day',
+ 'Stock pick',
+ 'New customers only',
+ 'money',
+ 'Stop snoring',
+ 'New domain extensions',
+ 'Please read',
+ 'Strong buy',
+ 'Potential earnings',
+ 'Stuff on sale',
+ 'No age restrictions',
+ 'Subject to credit',
+ 'No catch',
+ 'Supplies are limited',
+ 'No claim forms',
+ 'Produced and sent out',
+ 'Take action now',
+ 'No cost',
+ 'Profits',
+ 'hidden charges',
+ 'No credit check',
+ 'Promise you',
+ 'No disappointment',
+ 'Pure profit',
+ 'Real thing',
+ 'No fees',
+ 'Refinance home',
+ 'The best rates',
+ 'No gimmick',
+ 'The following form',
+ 'No inventory',
+ 'No investment',
+ 'giving it away',
+ 'No medical exams',
+ 'Removes wrinkles',
+ 'This isn’t junk',
+ 'No middleman',
+ 'This isn’t spam',
+ 'No obligation',
+ 'initial investment',
+ 'University diplomas',
+ 'No purchase necessary',
+ 'Reserves the right',
+ 'Unlimited',
+ 'We honor all',
+ 'Will not believe your eyes',
+ 'Urgent',
+ 'Winner',
+ 'US dollars',
+ 'What are you waiting for?',
+ 'Winning',
+ 'While supplies last',
+ 'Work at home',
+ 'drugs',
+ 'While you sleep',
+ 'You have been selected',
+ 'We hate spam',
+ 'Why pay more?',
+ ];
+
+ $errors = [];
+ foreach ($spamWords as $oneWord) {
+ if ((bool)preg_match('#'.preg_quote($oneWord, '#').'#Uis', $campaign->subject.$campaign->body)) {
+ $errors[] = $oneWord;
+ }
+ }
+
+ if (count($errors) > 2) {
+ echo acym_translation('ACYM_TESTS_CONTENT_DESC');
+ echo '';
+ }
+ exit;
+ }
+
+ public function checkLinks()
+ {
+ $campaignId = acym_getVar('int', 'id', 0);
+ $campaignClass = acym_get('class.campaign');
+ $mailClass = acym_get('class.mail');
+ $campaign = $campaignClass->getOneById($campaignId);
+ $mail = $mailClass->getOneById($campaign->mail_id);
+
+ acym_trigger('replaceContent', [&$mail, false]);
+ $userClass = acym_get('class.user');
+ $receiver = $userClass->getOneByEmail(acym_currentUserEmail());
+ if (empty($receiver)) {
+ $receiver = new stdClass();
+ $receiver->email = acym_currentUserEmail();
+ $newID = $userClass->save($receiver);
+ $receiver = $userClass->getOneById($newID);
+ }
+ acym_trigger('replaceUserInformation', [&$mail, &$receiver, false]);
+
+ preg_match_all('# (href|src)="([^"]+)"#Uis', acym_absoluteURL($mail->body), $URLs);
+
+ $errors = [];
+ $processed = [];
+ foreach ($URLs[2] as $oneURL) {
+ if (in_array($oneURL, $processed)) continue;
+ if (0 === strpos($oneURL, 'mailto:')) continue;
+ if (strlen($oneURL) > 1 && 0 === strpos($oneURL, '#')) continue;
+
+ $processed[] = $oneURL;
+
+ $headers = @get_headers($oneURL);
+ $headers = is_array($headers) ? implode("\n ", $headers) : $headers;
+
+ if (empty($headers) || preg_match('#^HTTP/.*\s+[(200|301|302)]+\s#i', $headers) !== 1) {
+ $errors[] = ''.(strlen($oneURL) > 50 ? substr($oneURL, 0, 25).'...'.substr($oneURL, strlen($oneURL) - 20) : $oneURL).' ';
+ }
+ }
+
+ if (!empty($errors)) {
+ echo '';
+ }
+
+ exit;
+ }
+
+ public function checkSPAM()
+ {
+ $result = new stdClass();
+ $result->type = 'error';
+ $result->message = '';
+
+ $campaignId = acym_getVar('int', 'id', 0);
+ $campaignClass = acym_get('class.campaign');
+ $campaign = $campaignClass->getOneByIdWithMail($campaignId);
+
+ if (empty($campaign->mail_id)) {
+ $result->message = acym_translation('ACYM_CAMPAIGN_NOT_FOUND');
+ } else {
+ $config = acym_config();
+ ob_start();
+ $urlSite = trim(base64_encode(preg_replace('#https?://(www\.)?#i', '', ACYM_LIVE)), '=/');
+ $url = ACYM_SPAMURL.'spamTestSystem&component=acymailing&level='.strtolower($config->get('level', 'starter')).'&urlsite='.$urlSite;
+ $spamtestSystem = acym_fileGetContent($url, 30);
+ $warnings = ob_get_clean();
+
+ if (empty($spamtestSystem) || !empty($warnings)) {
+ $result->message = acym_translation('ACYM_ERROR_LOAD_FROM_ACYBA').(!empty($warnings) && acym_isDebug() ? $warnings : '');
+ } else {
+ $decodedInformation = json_decode($spamtestSystem, true);
+ if (!empty($decodedInformation['messages']) || !empty($decodedInformation['error'])) {
+ $msgError = empty($decodedInformation['messages']) ? '' : $decodedInformation['messages'].' ';
+ $msgError .= empty($decodedInformation['error']) ? '' : $decodedInformation['error'];
+ $result->message = $msgError;
+ } else {
+ if (empty($decodedInformation['email'])) {
+ $result->message = acym_translation('ACYM_SPAMTEST_MISSING_EMAIL');
+ } else {
+ $mailerHelper = acym_get('helper.mailer');
+ $mailerHelper->checkConfirmField = false;
+ $mailerHelper->checkEnabled = false;
+ $mailerHelper->loadedToSend = true;
+ $mailerHelper->report = false;
+
+ $receiver = new stdClass();
+ $receiver->id = 0;
+ $receiver->email = $decodedInformation['email'];
+ $receiver->name = $decodedInformation['name'];
+ $receiver->confirmed = 1;
+ $receiver->enabled = 1;
+
+ if ($mailerHelper->sendOne($campaign->mail_id, $receiver)) {
+ $result->type = 'success';
+ $result->message = 'https://mailtester.acyba.com/'.(substr($decodedInformation['email'], 0, strpos($decodedInformation['email'], '@')));
+ $result->lang = acym_getLanguageTag();
+ } else {
+ $result->message = $mailerHelper->reportMessage;
+ }
+ }
+ }
+ }
+ }
+
+ echo json_encode($result);
+ exit;
+ }
+
+ public function saveAjax()
+ {
+ $return = $this->saveEditEmail(true);
+ echo json_encode(['error' => !$return ? acym_translation('ACYM_ERROR_SAVING') : '', 'data' => $return]);
+ exit;
+ }
+}
+
diff --git a/deployed/acym/administrator/components/com_acym/controllers/configuration.php b/deployed/acym/administrator/components/com_acym/controllers/configuration.php
new file mode 100644
index 00000000..a943abb9
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/controllers/configuration.php
@@ -0,0 +1,437 @@
+breadcrumb[acym_translation('ACYM_CONFIGURATION')] = acym_completeLink('configuration');
+ }
+
+ public function listing()
+ {
+ acym_setVar('layout', 'listing');
+
+ $config = acym_config();
+ $tabHelper = acym_get('helper.tab');
+
+ $langs = acym_getLanguages();
+ $languages = [];
+
+ foreach ($langs as $lang => $obj) {
+ if (strlen($lang) != 5 || $lang == "xx-XX") {
+ continue;
+ }
+
+ $oneLanguage = new stdClass();
+ $oneLanguage->language = $lang;
+ $oneLanguage->name = $obj->name;
+
+ $linkEdit = acym_completeLink('language&task=displayLanguage&code='.$lang, true);
+ $icon = $obj->exists ? 'edit' : 'add';
+ $idModalLanguage = 'acym_modal_language_'.$lang;
+ $oneLanguage->edit = acym_modal(
+ ' ',
+ '', //
+ $idModalLanguage,
+ 'data-reveal-larger',
+ '',
+ false
+ );
+
+ $languages[] = $oneLanguage;
+ }
+
+ $listClass = acym_get('class.list');
+ $lists = $listClass->getAll();
+ foreach ($lists as $i => $oneList) {
+ if ($oneList->active == 0) {
+ unset($lists[$i]);
+ }
+ }
+
+ $data = [
+ 'config' => $config,
+ 'tab' => $tabHelper,
+ 'languages' => $languages,
+ 'lists' => $lists,
+ ];
+
+ parent::display($data);
+ }
+
+ function checkDB()
+ {
+ $messages = [];
+
+ $queries = file_get_contents(ACYM_BACK.'tables.sql');
+ $tables = explode("CREATE TABLE IF NOT EXISTS ", $queries);
+ $structure = [];
+ $createTable = [];
+ $indexes = [];
+
+ foreach ($tables as $oneTable) {
+ if (strpos($oneTable, '`#__') !== 0) {
+ continue;
+ }
+
+ $tableName = substr($oneTable, 1, strpos($oneTable, '`', 1) - 1);
+
+ $fields = explode("\n", $oneTable);
+ foreach ($fields as $oneField) {
+ if (strpos($oneField, '#__') === 1) {
+ continue;
+ }
+ $oneField = rtrim(trim($oneField), ',');
+
+ if (substr($oneField, 0, 1) == '`') {
+ $columnName = substr($oneField, 1, strpos($oneField, '`', 1) - 1);
+ $structure[$tableName][$columnName] = trim($oneField, ",");
+ continue;
+ }
+
+ if (strpos($oneField, 'PRIMARY KEY') === 0) {
+ $indexes[$tableName]['PRIMARY'] = $oneField;
+ } elseif (strpos($oneField, 'INDEX') === 0) {
+ $firstBackquotePos = strpos($oneField, '`');
+ $indexName = substr($oneField, $firstBackquotePos + 1, strpos($oneField, '`', $firstBackquotePos + 1) - $firstBackquotePos - 1);
+
+ $indexes[$tableName][$indexName] = $oneField;
+ }
+ }
+ $createTable[$tableName] = "CREATE TABLE IF NOT EXISTS ".$oneTable;
+ }
+
+
+ $columnNames = [];
+ $tableNames = array_keys($structure);
+
+ foreach ($tableNames as $oneTableName) {
+ try {
+ $columns = acym_loadObjectList("SHOW COLUMNS FROM ".$oneTableName);
+ } catch (Exception $e) {
+ $columns = null;
+ }
+
+ if (!empty($columns)) {
+ foreach ($columns as $oneField) {
+ $columnNames[$oneTableName][$oneField->Field] = $oneField->Field;
+ }
+ continue;
+ }
+
+
+ $errorMessage = (isset($e) ? $e->getMessage() : substr(strip_tags(acym_getDBError()), 0, 200));
+ $messages[] = "Could not load columns from the table ".$oneTableName." : ".$errorMessage." ";
+
+ if (strpos($errorMessage, 'marked as crashed')) {
+ $repairQuery = 'REPAIR TABLE '.$oneTableName;
+
+ try {
+ $isError = acym_query($repairQuery);
+ } catch (Exception $e) {
+ $isError = null;
+ }
+
+ if ($isError === null) {
+ $errorMessage = (isset($e) ? $e->getMessage() : substr(strip_tags(acym_getDBError()), 0, 200));
+ $messages[] = "[ERROR]Could not repair the table ".$oneTableName." : ".$errorMessage." ";
+ } else {
+ $messages[] = "[OK]Problem solved : Table ".$oneTableName." repaired ";
+ }
+ continue;
+ }
+
+ try {
+ $isError = acym_query($createTable[$oneTableName]);
+ } catch (Exception $e) {
+ $isError = null;
+ }
+
+ if ($isError === null) {
+ $errorMessage = (isset($e) ? $e->getMessage() : substr(strip_tags(acym_getDBError()), 0, 200));
+ $messages[] = "[ERROR]Could not create the table ".$oneTableName." : ".$errorMessage." ";
+ } else {
+ $messages[] = "[OK]Problem solved : Table ".$oneTableName." created ";
+ }
+ }
+
+ foreach ($tableNames as $oneTableName) {
+ if (empty($columnNames[$oneTableName])) {
+ continue;
+ }
+
+ $idealColumnNames = array_keys($structure[$oneTableName]);
+ $missingColumns = array_diff($idealColumnNames, $columnNames[$oneTableName]);
+
+ if (!empty($missingColumns)) {
+ foreach ($missingColumns as $oneColumn) {
+ $messages[] = "Column ".$oneColumn." missing in ".$oneTableName." ";
+ try {
+ $isError = acym_query('ALTER TABLE '.$oneTableName.' ADD '.$structure[$oneTableName][$oneColumn]);
+ } catch (Exception $e) {
+ $isError = null;
+ }
+ if ($isError === null) {
+ $errorMessage = (isset($e) ? $e->getMessage() : substr(strip_tags(acym_getDBError()), 0, 200));
+ $messages[] = '[ERROR]Could not add the column '.$oneColumn.' on the table '.$oneTableName.' : '.$errorMessage.' ';
+ } else {
+ $messages[] = '[OK]Problem solved : Added '.$oneColumn.' in '.$oneTableName.' ';
+ }
+ }
+ }
+
+
+
+
+ $results = acym_loadObjectList('SHOW INDEX FROM '.$oneTableName, 'Key_name');
+ if (empty($results)) {
+ $results = [];
+ }
+
+ foreach ($indexes[$oneTableName] as $name => $query) {
+ $name = acym_prepareQuery($name);
+ if (in_array($name, array_keys($results))) {
+ continue;
+ }
+
+
+ $keyName = $name == 'PRIMARY' ? 'primary key' : 'index '.$name;
+
+ $messages[] = "".$keyName." missing in ".$oneTableName." ";
+ try {
+ $isError = acym_query('ALTER TABLE '.$oneTableName.' ADD '.$query);
+ } catch (Exception $e) {
+ $isError = null;
+ }
+
+ if ($isError === null) {
+ $errorMessage = (isset($e) ? $e->getMessage() : substr(strip_tags(acym_getDBError()), 0, 200));
+ $messages[] = "[ERROR]Could not add the ".$keyName." on the table ".$oneTableName." : ".$errorMessage." ";
+ } else {
+ $messages[] = "[OK]Problem solved : Added ".$keyName." to ".$oneTableName." ";
+ }
+ }
+ }
+
+ if (empty($messages)) {
+ echo ' ';
+ } else {
+ echo implode(' ', $messages);
+ }
+
+ exit;
+ }
+
+ function store()
+ {
+ acym_checkToken();
+
+ $formData = acym_getVar('array', 'config', []);
+ if (empty($formData)) {
+ return false;
+ }
+
+ if ($formData['from_as_replyto'] == 1) {
+ $formData['replyto_name'] = $formData['from_name'];
+ $formData['replyto_email'] = $formData['from_email'];
+ }
+
+
+ $config = acym_config();
+ $status = $config->save($formData);
+
+ if ($status) {
+ acym_enqueueNotification(acym_translation('ACYM_SUCCESSFULLY_SAVED'), 'success', 8000);
+ } else {
+ acym_enqueueNotification(acym_translation('ACYM_ERROR_SAVING'), 'error', 0);
+ }
+
+ $config->load();
+ }
+
+ public function test()
+ {
+ $this->store();
+
+ $config = acym_config();
+ $mailerHelper = acym_get('helper.mailer');
+ $addedName = $config->get('add_names', true) ? $mailerHelper->cleanText(acym_currentUserName()) : '';
+
+ $mailerHelper->AddAddress(acym_currentUserEmail(), $addedName);
+ $mailerHelper->Subject = 'Test e-mail from '.ACYM_LIVE;
+ $mailerHelper->Body = acym_translation('ACYM_TEST_EMAIL');
+ $mailerHelper->SMTPDebug = 1;
+ if (acym_isDebug()) {
+ $mailerHelper->SMTPDebug = 2;
+ }
+
+ $mailerHelper->isHTML(false);
+ $result = $mailerHelper->send();
+
+ if (!$result) {
+ $sendingMethod = $config->get('mailer_method');
+
+ if ($sendingMethod == 'smtp') {
+ if ($config->get('smtp_secured') == 'ssl' && !function_exists('openssl_sign')) {
+ acym_enqueueNotification(acym_translation('ACYM_OPENSSL'), 'notice');
+ }
+
+ if (!$config->get('smtp_auth') && strlen($config->get('smtp_password')) > 1) {
+ acym_enqueueNotification(acym_translation('ACYM_ADVICE_SMTP_AUTH'), 'notice');
+ }
+
+ if ($config->get('smtp_port') && !in_array($config->get('smtp_port'), [25, 2525, 465, 587])) {
+ acym_enqueueNotification(acym_translation_sprintf('ACYM_ADVICE_PORT', $config->get('smtp_port')), 'notice');
+ }
+ }
+
+ if (acym_isLocalWebsite() && in_array($sendingMethod, ['sendmail', 'qmail', 'mail'])) {
+ acym_enqueueNotification(acym_translation('ACYM_ADVICE_LOCALHOST'), 'notice');
+ }
+
+ $bounce = $config->get('bounce_email');
+ if (!empty($bounce) && !in_array($sendingMethod, ['smtp', 'elasticemail'])) {
+ acym_enqueueNotification(acym_translation_sprintf('ACYM_ADVICE_BOUNCE', ''.$bounce.' '), 'notice');
+ }
+ }
+
+ $this->listing();
+ }
+
+ public function ports()
+ {
+ if (!function_exists('fsockopen')) {
+ echo ''.acym_translation('ACYM_FSOCKOPEN').' ';
+ exit;
+ }
+
+ $tests = [25 => 'smtp.sendgrid.com', 2525 => 'smtp.sendgrid.com', 587 => 'smtp.sendgrid.com', 465 => 'ssl://smtp.sendgrid.com'];
+ $total = 0;
+ foreach ($tests as $port => $server) {
+ $fp = @fsockopen($server, $port, $errno, $errstr, 5);
+ if ($fp) {
+ echo ''.acym_translation_sprintf('ACYM_SMTP_AVAILABLE_PORT', $port).' ';
+ fclose($fp);
+ $total++;
+ } else {
+ echo ''.acym_translation_sprintf('ACYM_SMTP_NOT_AVAILABLE_PORT', $port, $errno.' - '.utf8_encode($errstr)).' ';
+ }
+ }
+
+ exit;
+ }
+
+ public function detecttimeout()
+ {
+ acym_query('REPLACE INTO `#__acym_configuration` (`name`,`value`) VALUES ("max_execution_time","5"), ("last_maxexec_check","'.time().'")');
+ @ini_set('max_execution_time', 600);
+ @ignore_user_abort(true);
+ $i = 0;
+ while ($i < 480) {
+ sleep(8);
+ $i += 10;
+ acym_query('UPDATE `#__acym_configuration` SET `value` = "'.intval($i).'" WHERE `name` = "max_execution_time"');
+ acym_query('UPDATE `#__acym_configuration` SET `value` = "'.intval(time()).'" WHERE `name` = "last_maxexec_check"');
+ sleep(2);
+ }
+ exit;
+ }
+
+ public function deletereport()
+ {
+ $config = acym_config();
+ $path = trim(html_entity_decode($config->get('cron_savepath')));
+ if (!preg_match('#^[a-z0-9/_\-{}]*\.log$#i', $path)) {
+ acym_enqueueNotification(acym_translation('ACYM_WRONG_LOG_NAME'), 'error', 6000);
+
+ return;
+ }
+
+ $path = str_replace(['{year}', '{month}'], [date('Y'), date('m')], $config->get('cron_savepath'));
+ $reportPath = acym_cleanPath(ACYM_ROOT.$path);
+
+ if (is_file($reportPath)) {
+ $result = acym_deleteFile($reportPath);
+ if ($result) {
+ acym_enqueueNotification(acym_translation('ACYM_SUCC_DELETE_LOG'), 'success', 4000);
+ } else {
+ acym_enqueueNotification(acym_translation('ACYM_ERROR_DELETE_LOG'), 'error', 4000);
+ }
+ } else {
+ acym_enqueueNotification(acym_translation('ACYM_EXIST_LOG'), 'info', 4000);
+ }
+
+ return $this->listing();
+ }
+
+ public function seereport()
+ {
+ acym_noCache();
+
+ $config = acym_config();
+
+ $path = trim(html_entity_decode($config->get('cron_savepath')));
+ if (!preg_match('#^[a-z0-9/_\-{}]*\.log$#i', $path)) {
+ acym_display(acym_translation('ACYM_WRONG_LOG_NAME'), 'error');
+ }
+
+ $path = str_replace(['{year}', '{month}'], [date('Y'), date('m')], $path);
+ $reportPath = acym_cleanPath(ACYM_ROOT.$path);
+
+ if (file_exists($reportPath) && !is_dir($reportPath)) {
+ try {
+ $lines = 5000;
+ $f = fopen($reportPath, "rb");
+ fseek($f, -1, SEEK_END);
+ if (fread($f, 1) != "\n") {
+ $lines -= 1;
+ }
+
+ $report = '';
+ while (ftell($f) > 0 && $lines >= 0) {
+ $seek = min(ftell($f), 4096); // Figure out how far back we should jump
+ fseek($f, -$seek, SEEK_CUR);
+ $report = ($chunk = fread($f, $seek)).$report; // Get the line
+ fseek($f, -mb_strlen($chunk, '8bit'), SEEK_CUR);
+ $lines -= substr_count($chunk, "\n"); // Move to previous line
+ }
+
+ while ($lines++ < 0) {
+ $report = substr($report, strpos($report, "\n") + 1);
+ }
+ fclose($f);
+ } catch (Exception $e) {
+ $report = '';
+ }
+ }
+
+ if (empty($report)) {
+ $report = acym_translation('ACYM_EMPTY_LOG');
+ }
+
+ echo nl2br($report);
+ exit;
+ }
+
+ public function redomigration()
+ {
+ $config = acym_config();
+ $newConfig = new stdClass();
+ $newConfig->migration = 0;
+ $config->save($newConfig);
+
+ acym_redirect(acym_completeLink('dashboard', false, true));
+ }
+}
+
diff --git a/deployed/acym/administrator/components/com_acym/controllers/dashboard.php b/deployed/acym/administrator/components/com_acym/controllers/dashboard.php
new file mode 100644
index 00000000..d1ed2db0
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/controllers/dashboard.php
@@ -0,0 +1,845 @@
+loadScripts = [
+ 'all' => ['colorpicker', 'datepicker', 'thumbnail', 'foundation-email', 'parse-css'],
+ ];
+ }
+
+ public function listing()
+ {
+ acym_setVar('layout', 'listing');
+ $config = acym_config();
+
+ if ($config->get('migration') == 0 && acym_existsAcyMailing59()) {
+
+ acym_setVar("layout", "migrate");
+
+ parent::display();
+
+ return;
+ }
+
+ if (ACYM_CMS === 'wordpress') {
+ $installDate = $config->get('install_date', time());
+ $remindme = json_decode($config->get('remindme', '[]'));
+
+ if ($installDate < time() - 1814400 && !in_array('reviews', $remindme)) {
+ $this->feedback();
+
+ return true;
+ }
+ }
+
+ $newConfig = new stdClass();
+
+ $newConfig->migration = '1';
+ $config->save($newConfig);
+
+ if ($config->get('walk_through') == 1) {
+ $walkthroughParams = json_decode($config->get('walkthrough_params', '[]'), true);
+ if (!empty($walkthroughParams['step'])) {
+ $this->{$walkthroughParams['step']}();
+ } else {
+ $this->stepSubscribe();
+ }
+
+ return;
+ }
+
+ $data = [];
+ $campaignClass = acym_get('class.campaign');
+ $mailStatsClass = acym_get('class.mailstat');
+ $urlClickClass = acym_get('class.urlclick');
+ $mails = $mailStatsClass->getAllMailsForStats();
+ $data['campaignsScheduled'] = $campaignClass->getCampaignForDashboard();
+ $data['dashboard_stats'] = true;
+
+ if (empty($mails)) {
+ $data['emptyGlobal'] = 'campaigns';
+ parent::display($data);
+
+ return;
+ }
+
+ $data['mails'] = [];
+
+ foreach ($mails as $mail) {
+ if (empty($mail->name) || (empty($mail->id) && $mail->sent != 1)) continue;
+
+ $newMail = new stdClass();
+ $newMail->name = $mail->name;
+ $newMail->value = $mail->id;
+ $data['mails'][] = $newMail;
+ }
+
+ $data['selectedMailid'] = empty($selectedMail) ? '' : $selectedMail;
+
+ $statsMailSelected = $mailStatsClass->getOneByMailId($data['selectedMailid']);
+
+ if (empty($statsMailSelected)) {
+ $data['emptyGlobal'] = empty($data['selectedMailid']) ? 'campaigns' : 'stats';
+ }
+
+ if (empty($statsMailSelected->sent)) {
+ $data['emptyGlobal'] = 'stats';
+ }
+
+ $statsMailSelected->totalMail = $statsMailSelected->sent + $statsMailSelected->fail;
+ $statsMailSelected->pourcentageSent = empty($statsMailSelected->totalMail) ? 0 : intval(($statsMailSelected->sent * 100) / $statsMailSelected->totalMail);
+ $statsMailSelected->allSent = empty($statsMailSelected->totalMail) ? acym_translation_sprintf('ACYM_X_MAIL_SUCCESSFULLY_SENT_OF_X', 0, 0) : acym_translation_sprintf('ACYM_X_MAIL_SUCCESSFULLY_SENT_OF_X', $statsMailSelected->sent, $statsMailSelected->totalMail);
+
+ $openRateCampaign = empty($data['selectedMailid']) ? $campaignClass->getOpenRateAllCampaign() : $campaignClass->getOpenRateOneCampaign($data['selectedMailid']);
+ $statsMailSelected->pourcentageOpen = empty($openRateCampaign->sent) ? 0 : intval(($openRateCampaign->open_unique * 100) / $openRateCampaign->sent);
+ $statsMailSelected->allOpen = empty($openRateCampaign->sent) ? acym_translation_sprintf('ACYM_X_MAIL_OPENED_OF_X', 0, 0) : acym_translation_sprintf('ACYM_X_MAIL_OPENED_OF_X', $openRateCampaign->open_unique, $openRateCampaign->sent);
+
+ $clickRateCampaign = $urlClickClass->getClickRate($data['selectedMailid']);
+ $statsMailSelected->pourcentageClick = empty($statsMailSelected->sent) ? 0 : intval(($clickRateCampaign->click * 100) / $statsMailSelected->sent);
+ $statsMailSelected->allClick = empty($statsMailSelected->sent) ? acym_translation_sprintf('ACYM_X_MAIL_CLICKED_OF_X', 0, 0) : acym_translation_sprintf('ACYM_X_MAIL_CLICKED_OF_X', $clickRateCampaign->click, $statsMailSelected->sent);
+
+ $bounceRateCampaign = empty($data['selectedMailid']) ? $campaignClass->getBounceRateAllCampaign() : $campaignClass->getBounceRateOneCampaign($data['selectedMailid']);
+ $statsMailSelected->pourcentageBounce = empty($statsMailSelected->sent) ? 0 : intval(($bounceRateCampaign->bounce_unique * 100) / $statsMailSelected->sent);
+ $statsMailSelected->allBounce = empty($statsMailSelected->sent) ? acym_translation_sprintf('ACYM_X_BOUNCE_OF_X', 0, 0) : acym_translation_sprintf('ACYM_X_BOUNCE_OF_X', $bounceRateCampaign->bounce_unique, $statsMailSelected->sent);
+
+
+ $campaignOpenByMonth = $campaignClass->getOpenByMonth($data['selectedMailid']);
+ $campaignOpenByDay = $campaignClass->getOpenByDay($data['selectedMailid']);
+ $campaignOpenByHour = $campaignClass->getOpenByHour($data['selectedMailid']);
+
+ $campaignClickByMonth = $urlClickClass->getAllClickByMailMonth($data['selectedMailid']);
+ $campaignClickByDay = $urlClickClass->getAllClickByMailDay($data['selectedMailid']);
+ $campaignClickByHour = $urlClickClass->getAllClickByMailHour($data['selectedMailid']);
+
+ if (empty($campaignOpenByMonth) || empty($campaignOpenByDay) || empty($campaignOpenByHour)) {
+ $statsMailSelected->empty = true;
+ $data['stats_mail_1'] = $statsMailSelected;
+
+ parent::display($data);
+
+ return;
+ }
+
+ #To get all the month between the first open date and the last
+ $begin = new DateTime(empty($campaignClickByMonth) ? $campaignOpenByMonth[0]->open_date : min([$campaignOpenByMonth[0]->open_date, $campaignClickByMonth[0]->date_click]));
+ $end = new DateTime(empty($campaignClickByMonth) ? end($campaignOpenByMonth)->open_date : max([end($campaignOpenByMonth)->open_date, end($campaignClickByMonth)->date_click]));
+
+ $end->modify('+1 day');
+
+ $interval = new DateInterval('P1M');
+ $daterange = new DatePeriod($begin, $interval, $end);
+
+ $rangeMonth = [];
+
+ foreach ($daterange as $date) {
+ $rangeMonth[] = acym_getTime($date->format('Y-m-d H:i:s'));
+ }
+
+ #To get all the day between the first open date and the last
+ $begin = new DateTime(empty($campaignClickByDay) ? $campaignOpenByDay[0]->open_date : min([$campaignOpenByDay[0]->open_date, $campaignClickByDay[0]->date_click]));
+ $end = new DateTime(empty($campaignClickByDay) ? end($campaignOpenByDay)->open_date : max([end($campaignOpenByDay)->open_date, end($campaignClickByDay)->date_click]));
+
+ $end->modify('+1 hour');
+
+ $interval = new DateInterval('P1D');
+ $daterange = new DatePeriod($begin, $interval, $end);
+
+ $rangeDay = [];
+
+ foreach ($daterange as $date) {
+ $rangeDay[] = acym_getTime($date->format('Y-m-d H:i:s'));
+ }
+
+
+ #To get all the hour between the first open date and the last
+ $begin = new DateTime(empty($campaignClickByHour) ? $campaignOpenByHour[0]->open_date : min([$campaignOpenByHour[0]->open_date, $campaignClickByHour[0]->date_click]));
+ $end = new DateTime(empty($campaignClickByHour) ? end($campaignOpenByHour)->open_date : max([end($campaignOpenByHour)->open_date, end($campaignClickByHour)->date_click]));
+
+ $end->modify('+1 min');
+
+ $interval = new DateInterval('PT1H');
+ $daterange = new DatePeriod($begin, $interval, $end);
+
+ $rangeHour = [];
+
+ foreach ($daterange as $date) {
+ $rangeHour[] = acym_getTime($date->format('Y-m-d H:i:s'));
+ }
+
+ $openMonthArray = [];
+ $openDayArray = [];
+ $openHourArray = [];
+
+ foreach ($campaignOpenByMonth as $one) {
+ $openMonthArray[acym_date(acym_getTime($one->open_date), 'M Y')] = $one->open;
+ }
+
+ foreach ($campaignOpenByDay as $one) {
+ $openDayArray[acym_date(acym_getTime($one->open_date), 'd M Y')] = $one->open;
+ }
+
+ foreach ($campaignOpenByHour as $one) {
+ $openHourArray[acym_date(acym_getTime($one->open_date), 'd M Y H')] = $one->open;
+ }
+
+ $clickMonthArray = [];
+ $clickDayArray = [];
+ $clickHourArray = [];
+
+ foreach ($campaignClickByMonth as $one) {
+ $clickMonthArray[acym_date(acym_getTime($one->date_click), 'M Y')] = $one->click;
+ }
+
+ foreach ($campaignClickByDay as $one) {
+ $clickDayArray[acym_date(acym_getTime($one->date_click), 'd M Y')] = $one->click;
+ }
+
+ foreach ($campaignClickByHour as $one) {
+ $clickHourArray[acym_date(acym_getTime($one->date_click), 'd M Y H')] = $one->click;
+ }
+
+ $statsMailSelected->month = [];
+ foreach ($rangeMonth as $one) {
+ $one = acym_date($one, 'M Y');
+ $currentMonth = [];
+ $currentMonth['open'] = empty($openMonthArray[$one]) ? 0 : $openMonthArray[$one];
+ $currentMonth['click'] = empty($clickMonthArray[$one]) ? 0 : $clickMonthArray[$one];
+ $statsMailSelected->month[$one] = $currentMonth;
+ }
+
+ $statsMailSelected->day = [];
+ foreach ($rangeDay as $one) {
+ $one = acym_date($one, 'd M Y');
+ $currentDay = [];
+ $currentDay['open'] = empty($openDayArray[$one]) ? 0 : $openDayArray[$one];
+ $currentDay['click'] = empty($clickDayArray[$one]) ? 0 : $clickDayArray[$one];
+ $statsMailSelected->day[$one] = $currentDay;
+ }
+
+ $statsMailSelected->hour = [];
+ foreach ($rangeHour as $one) {
+ $one = acym_date($one, 'd M Y H');
+ $currentHour = [];
+ $currentHour['open'] = empty($openHourArray[$one]) ? 0 : $openHourArray[$one];
+ $currentHour['click'] = empty($clickHourArray[$one]) ? 0 : $clickHourArray[$one];
+ $statsMailSelected->hour[$one.':00'] = $currentHour;
+ }
+ $data['stats_mail_1'] = $statsMailSelected;
+
+ parent::display($data);
+ }
+
+ public function stepSubscribe()
+ {
+ acym_setVar('layout', 'walk_through');
+
+ $data = [
+ 'step' => 'subscribe',
+ 'email' => acym_currentUserEmail(),
+ ];
+
+ parent::display($data);
+ }
+
+ public function saveStepSubscribe()
+ {
+ $this->_saveWalkthrough(['step' => 'stepEmail']);
+ $this->stepEmail();
+ }
+
+ public function stepEmail()
+ {
+ acym_setVar('layout', 'walk_through');
+
+ $config = acym_config();
+
+ $walkthroughParams = json_decode($config->get('walkthrough_params', '[]'), true);
+
+ $mailClass = acym_get('class.mail');
+ $updateHelper = acym_get('helper.update');
+
+ $mail = empty($walkthroughParams['mail_id']) ? $mailClass->getOneByName(acym_translation($updateHelper::FIRST_EMAIL_NAME_KEY)) : $mailClass->getOneById($walkthroughParams['mail_id']);
+
+ if (empty($mail)) {
+ $updateHelper = acym_get('helper.update');
+ if (!$updateHelper->installNotifications()) {
+ $this->stepSubscribe();
+
+ return;
+ }
+ $mail = $mailClass->getOneByName(acym_translation($updateHelper::FIRST_EMAIL_NAME_KEY));
+ }
+
+ $editor = acym_get('helper.editor');
+ $editor->content = $mail->body;
+ $editor->autoSave = '';
+ $editor->settings = $mail->settings;
+ $editor->stylesheet = $mail->stylesheet;
+ $editor->editor = 'acyEditor';
+ $editor->mailId = $mail->id;
+ $editor->walkThrough = true;
+
+ $data = [
+ 'step' => 'email',
+ 'editor' => $editor,
+ 'social_icons' => $config->get('social_icons', '{}'),
+ 'mail' => $mail,
+ ];
+
+ parent::display($data);
+ }
+
+ public function saveAjax()
+ {
+ $mailController = acym_get('controller.mails');
+
+ $isWellSaved = $mailController->store(true);
+ echo json_encode(['error' => $isWellSaved ? '' : acym_translation('ACYM_ERROR_SAVING'), 'data' => $isWellSaved]);
+ exit;
+ }
+
+ public function saveStepEmail()
+ {
+ $mailController = acym_get('controller.mails');
+
+ $mailId = $mailController->store();
+
+ if (empty($mailId)) {
+ acym_enqueueNotification(acym_translation('ACYM_ERROR_SAVING'), 'error', 10000);
+ $this->passWalkThrough();
+ } else {
+ $this->_saveWalkthrough(['step' => 'stepList', 'mail_id' => $mailId]);
+ $this->stepList();
+ }
+ }
+
+ public function stepList()
+ {
+ acym_setVar('layout', 'walk_through');
+ $listClass = acym_get('class.list');
+ $config = acym_config();
+ $walkthroughParams = json_decode($config->get('walkthrough_params', '[]'), true);
+
+ $users = empty($walkthroughParams['list_id']) ? [] : $listClass->getSubscribersByListId($walkthroughParams['list_id']);
+ $usersReturn = [];
+ if (!empty($users)) {
+ foreach ($users as $user) {
+ $usersReturn[] = $user->email;
+ }
+ }
+
+ if (empty($usersReturn)) $usersReturn[] = acym_currentUserEmail();
+
+ $data = [
+ 'step' => 'list',
+ 'users' => $usersReturn,
+ ];
+
+ parent::display($data);
+ }
+
+ public function saveStepList()
+ {
+ $config = acym_config();
+ $walkthroughParams = json_decode($config->get('walkthrough_params', '[]'), true);
+ if (empty($walkthroughParams['list_id'])) {
+ $testingList = new stdClass();
+ $testingList->name = acym_translation('ACYM_TESTING_LIST');
+ $testingList->visible = 0;
+ $testingList->active = 1;
+ $testingList->color = '#94d4a6';
+
+ $listClass = acym_get('class.list');
+ $listId = $listClass->save($testingList);
+ } else {
+ $listId = $walkthroughParams['list_id'];
+ }
+
+ if (empty($listId)) {
+ acym_enqueueNotification(acym_translation('ACYM_ERROR_SAVE_LIST'), 'error', 5000);
+ $this->passWalkThrough();
+
+ return;
+ }
+
+ $userClass = acym_get('class.user');
+
+ $addresses = acym_getVar('array', 'addresses', []);
+ $addresses = array_unique($addresses);
+ $wrongAddresses = [];
+ foreach ($addresses as $oneAddress) {
+ if (!acym_isValidEmail($oneAddress)) {
+ $wrongAddresses[] = $oneAddress;
+ continue;
+ }
+
+ $existing = $userClass->getOneByEmail($oneAddress);
+ if (empty($existing)) {
+ $newUser = new stdClass();
+ $newUser->email = $oneAddress;
+ $newUser->confirmed = 1;
+
+ $userId = $userClass->save($newUser);
+ } else {
+ $userId = $existing->id;
+ }
+
+ $userClass->subscribe($userId, $listId);
+ }
+
+ if (!empty($wrongAddresses)) acym_enqueueNotification(acym_translation_sprintf('ACYM_WRONG_ADDRESSES', implode(', ', $wrongAddresses)), 'warning', 5000);
+
+ $nextStep = acym_isLocalWebsite() ? 'stepGmail' : 'stepPhpmail';
+
+ $this->_saveWalkthrough(['step' => $nextStep, 'list_id' => $listId]);
+ $this->$nextStep();
+ }
+
+ public function stepPhpmail()
+ {
+ acym_setVar('layout', 'walk_through');
+
+ $data = [
+ 'step' => 'phpmail',
+ 'userEmail' => acym_currentUserEmail(),
+ ];
+
+ parent::display($data);
+ }
+
+ public function saveStepPhpmail()
+ {
+ $config = acym_config();
+
+
+ if (!$this->_saveFrom()) {
+ $this->stepPhpmail();
+
+ return;
+ }
+
+ $mailerMethod = ['mailer_method' => 'phpmail'];
+ if (false === $config->save($mailerMethod)) {
+ acym_enqueueMessage(acym_translation('ACYM_ERROR_SAVING', 'error'));
+ $this->stepPhpmail();
+
+ return;
+ }
+
+ if (false === $this->_sendFirstEmail()) {
+ $this->stepPhpmail();
+
+ return;
+ }
+
+ $this->_saveWalkthrough(['step' => 'stepResult']);
+ $this->stepResult();
+ }
+
+ public function stepGmail()
+ {
+ acym_setVar('layout', 'walk_through');
+
+ $data = [
+ 'step' => 'gmail',
+ 'userEmail' => acym_currentUserEmail(),
+ ];
+
+ parent::display($data);
+ }
+
+ public function saveStepGmail()
+ {
+ $config = acym_config();
+
+ if (!$this->_saveFrom() || !$this->_saveGmailInformation()) {
+ $this->stepGmail();
+
+ return;
+ }
+
+ $this->_sendFirstEmail();
+
+ $this->_saveWalkthrough(['step' => 'stepResult']);
+ $this->stepResult();
+ }
+
+ public function stepResult()
+ {
+ acym_setVar('layout', 'walk_through');
+
+ $data = [
+ 'step' => 'result',
+ ];
+
+ parent::display($data);
+ }
+
+ public function saveStepResult()
+ {
+ $config = acym_config();
+ $result = acym_getVar('boolean', 'result');
+
+ $walkthroughParams = json_decode($config->get('walkthrough_params', '[]'), true);
+
+ $stepFail = acym_isLocalWebsite() || !empty($walkthroughParams['step_fail']) ? 'stepFaillocal' : 'stepFail';
+
+ $nextStep = $result ? 'stepSuccess' : $stepFail;
+ $this->_saveWalkthrough(['step' => $nextStep]);
+
+ $this->$nextStep();
+ }
+
+ public function stepSuccess()
+ {
+ acym_setVar('layout', 'walk_through');
+
+ $data = [
+ 'step' => 'success',
+ ];
+
+ parent::display($data);
+ }
+
+ public function saveStepSuccess()
+ {
+ $this->passWalkThrough();
+ }
+
+ public function stepFaillocal()
+ {
+ acym_setVar('layout', 'walk_through');
+ $data = [
+ 'step' => 'faillocal',
+ 'email' => acym_currentUserEmail(),
+ ];
+ parent::display($data);
+ }
+
+ public function saveStepFaillocal()
+ {
+ $this->_handleContactMe('stepFaillocal');
+ }
+
+ public function stepFail()
+ {
+ acym_setVar('layout', 'walk_through');
+
+ $data = [
+ 'step' => 'fail',
+ 'email' => acym_currentUserEmail(),
+ ];
+
+ parent::display($data);
+ }
+
+ public function saveStepFail()
+ {
+ $choice = acym_getVar('cmd', 'choice', 'gmail');
+ if ('gmail' === $choice) {
+ $this->_saveGmailInformation();
+ $this->_sendFirstEmail();
+ $this->_saveWalkthrough(['step' => 'stepResult', 'step_fail' => true]);
+ $this->stepResult();
+ } else {
+ $this->_handleContactMe('stepFail');
+ }
+ }
+
+ private function _handleContactMe($fromFunction)
+ {
+ $email = acym_getVar('string', 'email');
+ if (empty($email) || !acym_isValidEmail($email)) {
+ acym_enqueueNotification(acym_translation('ACYM_PLEASE_ADD_YOUR_EMAIL'), 'error', 10000);
+ $this->$fromFunction();
+
+ return;
+ }
+
+ $config = acym_config();
+
+ $handle = curl_init();
+ $url = ACYM_UPDATEMEURL.'contact&task=contactme&email='.urlencode($email).'&version='.$config->get('version', '6').'&cms='.ACYM_CMS;
+ curl_setopt($handle, CURLOPT_URL, $url);
+ curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
+ $output = curl_exec($handle);
+ curl_close($handle);
+ $output = json_decode($output, true);
+ if (!empty($output['error'])) {
+ acym_enqueueMessage(acym_translation('ACYM_SOMETHING_WENT_WRONG_CONTACT_ON_ACYBA'), 'error');
+ $this->passWalkThrough();
+ } else {
+ $this->_saveWalkthrough(['step' => 'stepSupport']);
+ $this->stepSupport();
+ }
+ }
+
+ public function stepSupport()
+ {
+ acym_setVar('layout', 'walk_through');
+
+ $data = [
+ 'step' => 'support',
+ ];
+
+ parent::display($data);
+ }
+
+ public function saveStepSupport()
+ {
+ $this->passWalkThrough();
+ }
+
+ public function passWalkThrough()
+ {
+ $config = acym_config();
+ $newConfig = new stdClass();
+ $newConfig->walk_through = 0;
+
+ if ($config->get('templates_installed') == 0) {
+ $updateHelper = acym_get('helper.update');
+ $updateHelper->installTemplate();
+ $newConfig->templates_installed = 1;
+ }
+ $config->save($newConfig);
+
+ acym_redirect(acym_completeLink('users&task=import', false, true));
+
+ return;
+ }
+
+ public function preMigration()
+ {
+ $elementToMigrate = acym_getVar("string", "element");
+ $helperMigration = acym_get('helper.migration');
+
+ $result = $helperMigration->preMigration($elementToMigrate);
+
+ if (!empty($result["isOk"])) {
+ echo $result["count"];
+ } else {
+ echo "ERROR : ";
+ if (!empty($result["errorInsert"])) {
+ echo strtoupper(acym_translation("ACYM_INSERT_ERROR"));
+ }
+ if (!empty($result["errorClean"])) {
+ echo strtoupper(acym_translation("ACYM_CLEAN_ERROR"));
+ }
+
+ if (!empty($result["errors"])) {
+ echo " ";
+
+ foreach ($result["errors"] as $key => $oneError) {
+ echo " ".$key." : ".$oneError;
+ }
+ }
+ }
+ exit;
+ }
+
+ public function migrate()
+ {
+ $elementToMigrate = acym_getVar("string", "element");
+ $helperMigration = acym_get('helper.migration');
+ $functionName = "do".ucfirst($elementToMigrate)."Migration";
+
+ $result = $helperMigration->$functionName($elementToMigrate);
+
+ if (!empty($result["isOk"])) {
+ echo json_encode($result);
+ } else {
+ echo "ERROR : ";
+ if (!empty($result["errorInsert"])) {
+ echo strtoupper(acym_translation("ACYM_INSERT_ERROR"));
+ }
+ if (!empty($result["errorClean"])) {
+ echo strtoupper(acym_translation("ACYM_CLEAN_ERROR"));
+ }
+
+ if (!empty($result["errors"])) {
+ echo " ";
+
+ foreach ($result["errors"] as $key => $oneError) {
+ echo " ".$key." : ".$oneError;
+ }
+ }
+ }
+ exit;
+ }
+
+ public function migrationDone()
+ {
+ $config = acym_config();
+
+ $newConfig = new stdClass();
+ $newConfig->migration = "1";
+ $config->save($newConfig);
+
+ $updateHelper = acym_get('helper.update');
+ $updateHelper->installNotifications();
+
+ $this->listing();
+ }
+
+ private function acym_existsAcyMailing59()
+ {
+ $allTables = acym_getTables();
+
+ if (in_array(acym_getPrefix().'acymailing_config', $allTables)) {
+ $queryVersion = 'SELECT `value` FROM #__acymailing_config WHERE `namekey` LIKE "version"';
+
+ $version = acym_loadResult($queryVersion);
+
+ if (version_compare($version, '5.9.0') >= 0) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public function upgrade()
+ {
+ acym_setVar('layout', 'upgrade');
+
+ $version = acym_getVar('string', 'version', 'enterprise');
+
+ $data = ['version' => $version];
+
+ parent::display($data);
+ }
+
+ public function feedback()
+ {
+ acym_setVar('layout', 'feedback');
+
+ parent::display();
+
+ return;
+ }
+
+ private function _saveFrom()
+ {
+ $fromName = acym_getVar('string', 'from_name', 'Test');
+ $fromAddress = acym_getVar('string', 'from_address', 'test@test.com');
+
+ $mailClass = acym_get('class.mail');
+ $updateHelper = acym_get('helper.update');
+
+ $firstMail = $mailClass->getOneByName(acym_translation($updateHelper::FIRST_EMAIL_NAME_KEY));
+
+ if (empty($firstMail)) {
+ acym_enqueueNotification(acym_translation('ACYM_PLEASE_REINSTALL_ACYMAILING'), 'error');
+
+ return false;
+ }
+
+ $firstMail->from_name = $fromName;
+ $firstMail->from_email = $fromAddress;
+
+ $statusSaveMail = $mailClass->save($firstMail);
+
+ if (empty($statusSaveMail)) {
+ acym_enqueueNotification(acym_translation('ACYM_ERROR_SAVING'), 'error');
+
+ return false;
+ }
+
+ return true;
+ }
+
+ private function _saveGmailInformation()
+ {
+ $gmailAddress = acym_getVar('string', 'gmail_address', '');
+ $gmailPassword = acym_getVar('string', 'gmail_password', '');
+
+ $config = acym_config();
+
+ if (empty($gmailAddress) || empty($gmailPassword)) {
+ acym_enqueueMessage(acym_translation('ACYM_EMPTY_ADDRESS_OR_PASSWORD'), 'error');
+
+ return false;
+ }
+
+ $newSmtpConfiguration = [
+ 'smtp_auth' => '1',
+ 'smtp_host' => 'smtp.gmail.com',
+ 'smtp_keepalive' => '1',
+ 'smtp_port' => '465',
+ 'smtp_secured' => 'ssl',
+ 'smtp_username' => $gmailAddress,
+ 'smtp_password' => $gmailPassword,
+ 'mailer_method' => 'smtp',
+ ];
+
+ if (false === $config->save($newSmtpConfiguration)) {
+ acym_enqueueMessage(acym_translation('ACYM_ERROR_SAVING', 'error'));
+
+ return false;
+ }
+
+ return true;
+ }
+
+ private function _sendFirstEmail()
+ {
+ $config = acym_config();
+ $walkthroughParams = json_decode($config->get('walkthrough_params', '[]'), true);
+ $listClass = acym_get('class.list');
+ $mailClass = acym_get('class.mail');
+ $updateHelper = acym_get('helper.update');
+ $mailerHelper = acym_get('helper.mailer');
+
+ $testingList = empty($walkthroughParams['list_id']) ? $listClass->getOneByName(acym_translation('ACYM_TESTING_LIST')) : $listClass->getOneById($walkthroughParams['list_id']);
+ $firstMail = empty($walkthroughParams['mail_id']) ? $mailClass->getOneByName(acym_translation($updateHelper::FIRST_EMAIL_NAME_KEY)) : $mailClass->getOneById($walkthroughParams['mail_id']);
+
+ if (empty($testingList)) {
+ acym_enqueueNotification(acym_translation('ACYM_CANT_RETRIEVE_TESTING_LIST'), 'error');
+
+ return false;
+ }
+
+ if (empty($firstMail)) {
+ acym_enqueueNotification(acym_translation('ACYM_CANT_RETRIEVE_TEST_EMAIL'), 'error');
+ }
+
+ $subscribersTestingListIds = $listClass->getSubscribersIdsById($testingList->id);
+
+ $nbSent = 0;
+ foreach ($subscribersTestingListIds as $subscriberId) {
+ if ($mailerHelper->sendOne($firstMail->id, $subscriberId, true)) $nbSent++;
+ }
+
+ if ($nbSent === 0) {
+ return false;
+ }
+
+ return true;
+ }
+
+ private function _saveWalkthrough($params)
+ {
+ $config = acym_config();
+
+ $newParams = json_decode($config->get('walkthrough_params', '[]'), true);
+ foreach ($params as $key => $value) {
+ $newParams[$key] = $value;
+ }
+ $config->save(['walkthrough_params' => json_encode($newParams)]);
+ }
+}
+
diff --git a/deployed/acym/administrator/components/com_acym/controllers/dynamics.php b/deployed/acym/administrator/components/com_acym/controllers/dynamics.php
new file mode 100644
index 00000000..a6499479
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/controllers/dynamics.php
@@ -0,0 +1,119 @@
+setDefaultTask('popup');
+ }
+
+ public function popup()
+ {
+ $plugins = acym_trigger('dynamicText');
+ $isAutomation = acym_getVar('string', 'automation');
+
+ $js = 'function setTag(tagvalue, element){
+ var $allRows = jQuery(".acym__listing__row__popup");
+ $allRows.removeClass("selected_row");
+ element.addClass("selected_row");
+ window.document.getElementById(\'dtextcode\').value = tagvalue;
+ }';
+ $js .= 'try{window.parent.previousSelection = window.parent.getPreviousSelection(); }catch(err){window.parent.previousSelection=false; }';
+
+ acym_addScript(true, $js);
+
+ $tab = acym_get('helper.tab');
+
+ $data = [
+ "type" => acym_getVar('string', 'type', 'news'),
+ "plugins" => $plugins,
+ "tab" => $tab,
+ "automation" => $isAutomation,
+ ];
+
+ parent::display($data);
+ }
+
+ public function replaceDummy()
+ {
+ $mailId = acym_getVar('int', 'mailId', 0);
+ if (!empty($mailId)) {
+ $mailClass = acym_get('class.mail');
+ $email = $mailClass->getOneById($mailId);
+ }
+
+ if (empty($email)) {
+ $email = new stdClass();
+ $email->id = 0;
+ $email->name = '';
+ $email->subject = '';
+ $email->from_name = '';
+ $email->from_email = '';
+ $email->reply_to_name = '';
+ $email->reply_to_email = '';
+ $email->bcc = '';
+ }
+
+ $email->creation_date = acym_date('now', 'Y-m-d H:i:s', false);
+ $email->creator_id = acym_currentUserId();
+ $email->thumbnail = '';
+ $email->drag_editor = '1';
+ $email->library = '0';
+ $email->type = 'standard';
+ $email->template = '0';
+ $email->settings = '';
+ $email->stylesheet = '';
+ $email->attachments = '';
+
+ $email->body = acym_getVar('string', 'code', '');
+
+
+ acym_trigger('replaceContent', [&$email]);
+
+ $userClass = acym_get('class.user');
+ $userEmail = acym_currentUserEmail();
+ $user = $userClass->getOneByEmail($userEmail);
+
+ if (empty($user)) {
+ $user = new stdClass();
+ $user->email = acym_currentUserEmail();
+ $user->name = acym_currentUserName();
+ $user->cms_id = acym_currentUserId();
+ $user->confirmed = 0;
+ $user->source = ACYM_CMS;
+
+ $userClass->checkVisitor = false;
+ $user->id = $userClass->save($user);
+ }
+
+ acym_trigger('replaceUserInformation', [&$email, &$user, false]);
+
+ echo $email->body;
+ exit;
+ }
+
+ function trigger()
+ {
+ $plugin = acym_getVar('cmd', 'plugin', '');
+ $trigger = acym_getVar('cmd', 'trigger', '');
+ if (empty($plugin) || empty($trigger)) {
+ exit;
+ }
+
+ acym_trigger($trigger, [], $plugin);
+
+ exit;
+ }
+}
+
diff --git a/deployed/acym/administrator/components/com_acym/controllers/fields.php b/deployed/acym/administrator/components/com_acym/controllers/fields.php
new file mode 100644
index 00000000..98df009a
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/controllers/fields.php
@@ -0,0 +1,260 @@
+breadcrumb[acym_translation('ACYM_CUSTOM_FIELDS')] = acym_completeLink('fields');
+ }
+
+ public function listing()
+ {
+
+ if (!acym_level(2)) {
+ acym_redirect(acym_completeLink('dashboard&task=upgrade&version=enterprise', false, true));
+ }
+ }
+
+ public function edit()
+ {
+ acym_setVar('layout', 'edit');
+ $id = acym_getVar('int', 'id');
+ $fieldClass = acym_get('class.field');
+
+ if (empty($id)) {
+ $field = new stdClass();
+ $field->id = 0;
+ $field->name = '';
+ $field->active = 1;
+ $field->type = 'text';
+ $field->value = '';
+ $field->option = '';
+ $field->default_value = '';
+ $field->required = 0;
+ $field->backend_profile = 1;
+ $field->backend_listing = 0;
+ $field->backend_filter = 1;
+ $field->frontend_form = 1;
+ $field->frontend_profile = 1;
+ $field->frontend_filter = 1;
+ $field->access = 1;
+ $field->fieldDB = new stdClass();
+ } else {
+ $field = $fieldClass->getOneFieldByID($id);
+ $field->option = json_decode($field->option);
+ $field->value = json_decode($field->value);
+ $field->fieldDB = empty($field->option->fieldDB) ? new stdClass() : json_decode($field->option->fieldDB);
+ if (!in_array($id, [1, 2]) && !empty($field->fieldDB->table)) {
+ $tables = acym_loadResultArray('SHOW TABLES FROM `'.acym_secureDBColumn($field->fieldDB->database).'`');
+ $field->fieldDB->tables = [];
+ foreach ($tables as $one) {
+ $field->fieldDB->tables[$one] = $one;
+ }
+ $columns = empty($field->fieldDB->table) ? [] : acym_loadResultArray('SHOW COLUMNS FROM '.acym_secureDBColumn($field->fieldDB->table).' FROM '.acym_secureDBColumn($field->fieldDB->database));
+ $field->fieldDB->columns = [];
+ foreach ($columns as $one) {
+ $field->fieldDB->columns[$one] = $one;
+ }
+ array_unshift($field->fieldDB->columns, acym_translation('ACYM_CHOOSE_COLUMN'));
+ }
+ }
+
+ if (!empty($id)) {
+ $this->breadcrumb[acym_escape(acym_translation($field->name))] = acym_completeLink('fields&task=edit&id='.$id);
+ } else {
+ $this->breadcrumb[acym_translation('ACYM_NEW_CUSTOM_FIELD')] = acym_completeLink('fields&task=edit');
+ }
+
+ $allDatabases = acym_loadResultArray('SHOW DATABASES');
+ $databases = [];
+ foreach ($allDatabases as $database) {
+ $databases[$database] = $database;
+ }
+
+ $allFields = $fieldClass->getAllfields();
+
+ $allFieldsName = [];
+ foreach ($allFields as $one) {
+ $allFieldsName[$one->id] = $one->name;
+ }
+
+ $data = [
+ 'field' => $field,
+ 'database' => $databases,
+ 'allFields' => $allFieldsName,
+ ];
+
+ $data['fieldType'] = [
+ 'text' => acym_translation('ACYM_TEXT'),
+ 'textarea' => acym_translation('ACYM_TEXTAREA'),
+ 'radio' => acym_translation('ACYM_RADIO'),
+ 'checkbox' => acym_translation('ACYM_CHECKBOX'),
+ 'single_dropdown' => acym_translation('ACYM_SINGLE_DROPDOWN'),
+ 'multiple_dropdown' => acym_translation('ACYM_MULTIPLE_DROPDOWN'),
+ 'date' => acym_translation('ACYM_DATE'),
+ 'file' => acym_translation('ACYM_FILE'),
+ 'phone' => acym_translation('ACYM_PHONE'),
+ 'custom_text' => acym_translation('ACYM_CUSTOM_TEXT'),
+ ];
+
+ return parent::display($data);
+ }
+
+ public function getTables()
+ {
+ $database = acym_getVar('string', 'database');
+ $allTables = acym_loadResultArray('SHOW TABLES FROM '.$database);
+ echo json_encode($allTables);
+ exit;
+ }
+
+ public function setColumns()
+ {
+ $table = acym_getVar('string', 'table');
+ $database = acym_getVar('string', 'database');
+ $query = 'SHOW COLUMNS FROM '.$table.' FROM '.$database;
+ $columns = acym_loadResultArray($query);
+ array_unshift($columns, 'ACYM_CHOOSE_COLUMN');
+ echo json_encode($columns);
+ exit;
+ }
+
+ public function apply()
+ {
+ $fieldClass = acym_get('class.field');
+ $newField = $this->setFieldToSave();
+ $id = $fieldClass->save($newField);
+ if (!empty($id)) {
+ acym_setVar('id', $id);
+ acym_enqueueNotification(acym_translation('ACYM_SUCCESSFULLY_SAVED'), 'success', 5000);
+ } else {
+ acym_enqueueNotification(acym_translation('ACYM_ERROR_SAVING'), 'error', 5000);
+ }
+
+ $this->edit();
+ }
+
+ public function save()
+ {
+ $fieldClass = acym_get('class.field');
+ $newField = $this->setFieldToSave();
+ $id = $fieldClass->save($newField);
+ if (!empty($id)) {
+ acym_setVar('id', $id);
+ acym_enqueueNotification(acym_translation('ACYM_SUCCESSFULLY_SAVED'), 'success', 5000);
+ } else {
+ acym_enqueueNotification(acym_translation('ACYM_ERROR_SAVING'), 'error', 5000);
+ }
+ $this->listing();
+ }
+
+ private function setFieldToSave()
+ {
+ $fieldClass = acym_get('class.field');
+ $field = acym_getVar('array', 'field');
+ $fieldDB = json_encode(acym_getVar('array', 'fieldDB'));
+ $id = acym_getVar('int', 'id');
+ if ($id == 2) {
+ $field['required'] = 1;
+ }
+ if (empty($field['name'])) {
+ return false;
+ }
+
+
+ $value = [];
+
+ $fieldValues = $field['value'];
+ $field['type'] = in_array($id, [1, 2]) ? 'text' : $field['type'];
+
+ $i = 0;
+ foreach ($fieldValues['value'] as $one) {
+ if (empty($one) && $one != '0' && ($i != 0 || !in_array($field['type'], ['single_dropdown', 'multiple_dropdown']))) {
+ $i++;
+ continue;
+ } else {
+ $value[$i] = [
+ 'value' => $one,
+ 'title' => $fieldValues['title'][$i],
+ 'disabled' => $fieldValues['disabled'][$i],
+ ];
+ $i++;
+ }
+ }
+
+ $field['namekey'] = empty($field['namekey']) ? $fieldClass->generateNamekey($field['name']) : $field['namekey'];
+ $field['option']['format'] = ($field['type'] == 'date' && empty($field['option']['format'])) ? '%d%m%y' : strtolower($field['option']['format']);
+ $field['option']['rows'] = ($field['type'] == 'textarea' && empty($field['option']['rows'])) ? '5' : $field['option']['rows'];
+ $field['option']['columns'] = ($field['type'] == 'textarea' && empty($field['option']['columns'])) ? '30' : $field['option']['columns'];
+
+ $field['value'] = json_encode($value);
+ $field['option']['fieldDB'] = $fieldDB;
+ $field['option']['format'] = !empty($field['option']['format']) ? preg_replace('/[^a-zA-Z\%]/', '', $field['option']['format']) : $field['option']['format'];
+ $newField = new stdClass();
+ $newField->name = $field['name'];
+ $newField->active = $field['active'];
+ $newField->namekey = $field['namekey'];
+ $newField->type = in_array($id, [1, 2]) ? 'text' : $field['type'];
+ $newField->required = $field['required'];
+ $newField->option = json_encode($field['option']);
+ $newField->value = $field['value'];
+ $newField->default_value = $field['default_value'];
+ $newField->frontend_form = $field['frontend_form'];
+ $newField->frontend_profile = $field['frontend_profile'];
+ $newField->backend_profile = $field['backend_profile'];
+ $newField->backend_listing = $field['backend_listing'];
+ $newField->backend_filter = 1;
+ $newField->frontend_filter = 1;
+ $newField->access = 'all';
+ if (empty($id)) {
+ $newField->ordering = $fieldClass->getOrdering()->ordering_number + 1;
+ } else {
+ $newField->id = $id;
+ }
+
+ return $newField;
+ }
+
+ public function setOrdering()
+ {
+ $order = json_decode(acym_getVar('string', 'order'));
+ $i = 1;
+ $error = false;
+ foreach ($order as $field) {
+ $query = 'UPDATE #__acym_field SET `ordering` = '.intval($i).' WHERE `id` = '.intval($field);
+ $error = acym_query($query) >= 0 ? false : true;
+ $i++;
+ }
+ if ($error) {
+ echo 'error';
+ } else {
+ echo 'updated';
+ }
+ exit;
+ }
+
+ public function delete()
+ {
+ $ids = acym_getVar('cmd', 'elements_checked');
+ if (in_array('1', $ids) || in_array('2', $ids)) {
+ acym_enqueueNotification(acym_translation('ACYM_CANT_DELETE'), 'error', 5000);
+ $this->listing();
+
+ return;
+ } else {
+ return parent::delete();
+ }
+ }
+}
+
diff --git a/deployed/acym/administrator/components/com_acym/controllers/file.php b/deployed/acym/administrator/components/com_acym/controllers/file.php
new file mode 100644
index 00000000..94a20196
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/controllers/file.php
@@ -0,0 +1,64 @@
+setDefaultTask('select');
+ }
+
+ public function select()
+ {
+ $config = acym_config();
+ $uploadFolders = $config->get('uploadfolder', ACYM_UPLOAD_FOLDER);
+ $uploadFolder = acym_getVar('string', 'currentFolder', $uploadFolders);
+ $uploadPath = acym_cleanPath(ACYM_ROOT.trim(str_replace('/', DS, trim($uploadFolder)), DS));
+ $map = acym_getVar('string', 'id');
+ acym_setVar('layout', 'select');
+
+ $folders = acym_generateArborescence([$uploadFolders]);
+
+
+ $uploadedFile = acym_getVar('array', 'uploadedFile', [], 'files');
+ if (!empty($uploadedFile) && !empty($uploadedFile['name'])) {
+ $uploaded = acym_importFile($uploadedFile, $uploadPath, false);
+ if ($uploaded) {
+ }
+ }
+
+
+
+ $allowedExtensions = explode(',', $config->get('allowed_files'));
+ $imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'ico', 'bmp', 'svg'];
+ $displayType = acym_getVar('string', 'displayType', 'icons');
+
+ $files = [];
+ if (file_exists($uploadPath)) {
+ $files = acym_getFiles($uploadPath);
+ }
+
+ $data = [
+ 'files' => $files,
+ 'uploadFolder' => $uploadFolder,
+ 'map' => $map,
+ 'displayType' => $displayType,
+ 'imageExtensions' => $imageExtensions,
+ 'allowedExtensions' => $allowedExtensions,
+ 'folders' => $folders,
+ ];
+
+ parent::display($data);
+ }
+}
+
diff --git a/deployed/acym/administrator/components/com_acym/controllers/index.html b/deployed/acym/administrator/components/com_acym/controllers/index.html
new file mode 100644
index 00000000..fa6d84e8
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/controllers/index.html
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/deployed/acym/administrator/components/com_acym/controllers/language.php b/deployed/acym/administrator/components/com_acym/controllers/language.php
new file mode 100644
index 00000000..7e53c6f2
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/controllers/language.php
@@ -0,0 +1,219 @@
+', '', $content);
+
+ if (empty($code) || empty($content)) {
+ return $this->displayLanguage();
+ }
+
+ $customcontent = acym_getVar('string', 'customcontent', '', '', ACYM_ALLOWHTML);
+ $customcontent = str_replace('', '', $customcontent);
+
+ $path = acym_getLanguagePath(ACYM_ROOT, $code).DS.$code.'.com_acym.ini';
+ $result = acym_writeFile($path, $content);
+ if ($result) {
+ acym_enqueueNotification(acym_translation('ACYM_SUCCESSFULLY_SAVED'), 'success');
+ acym_addScript(true, "window.top.document.getElementById('image$code').innerHTML = 'edit'");
+
+ $updateHelper = acym_get('helper.update');
+ $updateHelper->installBackLanguages($code);
+ } else {
+ acym_enqueueNotification(acym_translation_sprintf('ACYM_FAIL_SAVE', $path), 'error');
+ }
+
+ $custompath = acym_getLanguagePath(ACYM_ROOT, $code).DS.$code.'.com_acym_custom.ini';
+ $customresult = acym_writeFile($custompath, $customcontent);
+ if (!$customresult) {
+ acym_enqueueNotification(acym_translation_sprintf('ACYM_FAIL_SAVE', $custompath), 'error');
+ }
+
+ if ($code == acym_getLanguageTag()) {
+ acym_loadLanguage();
+ }
+
+ $updateHelper = acym_get('helper.update');
+ $updateHelper->installBackLanguages();
+
+ if ($fromShare) {
+ return $result;
+ } else {
+ return $this->displayLanguage();
+ }
+ }
+
+ public function latest()
+ {
+ $this->displayLanguage();
+ }
+
+ public function share()
+ {
+ acym_checkToken();
+
+ if ($this->saveLanguage(true)) {
+ acym_setVar('layout', 'share');
+
+ $file = new stdClass();
+ $file->name = acym_getVar('cmd', 'code');
+
+ return parent::display(['file' => $file]);
+ } else {
+ return $this->displayLanguage();
+ }
+ }
+
+ public function send()
+ {
+ acym_checkToken();
+
+ $bodyEmail = acym_getVar('string', 'mailbody');
+ $code = acym_getVar('cmd', 'code');
+ acym_setVar('code', $code);
+
+ if (empty($code)) {
+ return;
+ }
+
+ $config = acym_config();
+ $mailer = acym_get('helper.mailer');
+ $mailer->Subject = '[ACYMAILING LANGUAGE FILE] '.$code;
+ $mailer->Body = 'The website '.ACYM_LIVE.' using AcyMailing '.$config->get('level').' '.$config->get('version').' sent a language file : '.$code;
+ $mailer->Body .= "\n\n\n".$bodyEmail;
+
+ $file = acym_getLanguagePath(ACYM_ROOT, $code).DS.$code.'.com_acym.ini';
+ if (!file_exists($file)) {
+ return;
+ }
+
+ $translation = acym_fileGetContent($file);
+
+ $customFile = acym_getLanguagePath(ACYM_ROOT, $code).DS.$code.'.com_acym_custom.ini';
+
+ if (file_exists($customFile)) {
+ $customTranslation = acym_fileGetContent($customFile);
+
+ if (!empty($customTranslation)) {
+ $newKeys = [];
+ $customKeys = [];
+ preg_match_all('#([0-9A-Z_]+)="((?:[^"]|"_QQ_")+)"#is', $customTranslation, $customKeys);
+
+ if (!empty($customKeys)) {
+ $mainKeys = [];
+ preg_match_all('#([0-9A-Z_]+)="((?:[^"]|"_QQ_")+)"#is', $translation, $mainKeys);
+
+ foreach ($customKeys[1] as $index => $oneKey) {
+ $position = array_search($oneKey, $mainKeys[1]);
+ if ($position !== false) {
+ $translation = str_replace($mainKeys[0][$position], $customKeys[0][$index], $translation);
+ } else {
+ $newKeys[] = $customKeys[0][$index];
+ }
+ }
+
+ if (!empty($newKeys)) {
+ $mailer->Body .= "\n\n\nCustom content:\n".implode("\n", $newKeys);
+ }
+ }
+ }
+ }
+
+ $mailer->addStringAttachment($translation, $code.'.com_acym.ini');
+
+ $mailer->AddAddress(acym_currentUserEmail(), acym_currentUserName());
+ $mailer->AddAddress('translate@acyba.com', 'Acyba Translation Team');
+ $mailer->report = false;
+
+ $result = $mailer->Send();
+
+ if ($result) {
+ acym_enqueueNotification(acym_translation('ACYM_THANK_YOU_SHARING').' '.acym_translation('ACYM_MESSAGE_SENT'), 'success');
+ } else {
+ acym_enqueueNotification($mailer->reportMessage, 'error');
+ }
+
+ $this->displayLanguage();
+ }
+
+ public function displayLanguage()
+ {
+ acym_setVar("layout", "default");
+
+ $code = acym_getVar('string', 'code');
+ if (empty($code)) {
+ acym_display('Code not specified', 'error');
+
+ return;
+ }
+
+ $file = new stdClass();
+ $file->name = $code;
+ $path = acym_getLanguagePath(ACYM_ROOT, $code).DS.$code.'.com_acym.ini';
+ $file->path = $path;
+ $file->content = '';
+ $file->customcontent = '';
+
+
+ $showLatest = true;
+ $loadLatest = false;
+
+ if (file_exists($path)) {
+ $file->content = acym_fileGetContent($path);
+ if (empty($file->content)) {
+ acym_display('File not found : '.$path, 'error');
+ }
+ } else {
+ $loadLatest = true;
+ acym_enqueueMessage(acym_translation('ACYM_LOAD_ENGLISH_1').' '.acym_translation('ACYM_LOAD_ENGLISH_2').' '.acym_translation('ACYM_LOAD_ENGLISH_3'), 'info');
+ $file->content = acym_fileGetContent(acym_getLanguagePath(ACYM_ROOT, ACYM_DEFAULT_LANGUAGE).DS.ACYM_DEFAULT_LANGUAGE.'.com_acym.ini');
+ }
+
+ $custompath = acym_getLanguagePath(ACYM_ROOT, $code).DS.$code.'.com_acym_custom.ini';
+ if (file_exists($custompath)) {
+ $file->customcontent = acym_fileGetContent($custompath);
+ }
+
+ if ($loadLatest || acym_getVar('cmd', 'task') == 'latest') {
+ if (file_exists(acym_getLanguagePath(ACYM_ROOT, $code))) {
+ acym_addScript(false, ACYM_UPDATEMEURL.'update&component=acym&task=languageload&code='.acym_getVar('cmd', 'code'));
+ } else {
+ acym_enqueueMessage('The specified language "'.acym_escape($code).'" is not installed on your site', 'warning');
+ }
+ $showLatest = false;
+ } elseif (acym_getVar('cmd', 'task') == 'save') {
+ $showLatest = false;
+ }
+
+ $data = [
+ 'showLatest' => $showLatest,
+ 'file' => $file,
+ ];
+
+ return parent::display($data);
+ }
+}
+
diff --git a/deployed/acym/administrator/components/com_acym/controllers/lists.php b/deployed/acym/administrator/components/com_acym/controllers/lists.php
new file mode 100644
index 00000000..0726eae6
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/controllers/lists.php
@@ -0,0 +1,550 @@
+breadcrumb[acym_translation('ACYM_LISTS')] = acym_completeLink('lists');
+ $this->edition = acym_getVar('int', 'edition', 0);
+ $this->listClass = acym_get('class.list');
+ $this->loadScripts = [
+ 'edit' => ['colorpicker'],
+ 'save' => ['colorpicker'],
+ ];
+ }
+
+ public function listing()
+ {
+ acym_setVar("layout", "listing");
+
+ $searchFilter = acym_getVar('string', 'lists_search', '');
+ $tagFilter = acym_getVar('string', 'lists_tag', '');
+ $ordering = acym_getVar('string', 'lists_ordering', 'id');
+ $status = acym_getVar('string', 'lists_status', '');
+ $format = acym_getVar('string', 'global_listingformat', 'list');
+ $orderingSortOrder = acym_getVar('string', 'lists_ordering_sort_order', 'desc');
+
+ $listsPerPage = acym_getCMSConfig('list_limit', 20);
+ $page = acym_getVar('int', 'lists_pagination_page', 1);
+
+ $listClass = acym_get('class.list');
+ $matchingLists = $listClass->getMatchingLists(
+ [
+ 'ordering' => $ordering,
+ 'search' => $searchFilter,
+ 'listsPerPage' => $listsPerPage,
+ 'offset' => ($page - 1) * $listsPerPage,
+ 'tag' => $tagFilter,
+ 'status' => $status,
+ 'ordering_sort_order' => $orderingSortOrder,
+ ]
+ );
+
+ $pagination = acym_get('helper.pagination');
+ $pagination->setStatus($matchingLists['total'], $page, $listsPerPage);
+
+ $data = [
+ "lists" => $matchingLists['lists'],
+ "tags" => acym_get('class.tag')->getAllTagsByType('list'),
+ "pagination" => $pagination,
+ "search" => $searchFilter,
+ "tag" => $tagFilter,
+ "ordering" => $ordering,
+ "listNumberPerStatus" => $matchingLists["status"],
+ "status" => $status,
+ "format" => $format,
+ "orderingSortOrder" => $orderingSortOrder,
+ ];
+
+ parent::display($data);
+ }
+
+ public function subscribers()
+ {
+ acym_setVar("layout", "subscribers");
+ $listId = acym_getVar("int", "id", 0);
+
+ if (!$listId) {
+ $this->listing();
+
+ return;
+ }
+
+ $searchFilter = acym_getVar('string', 'subscribers_search', '');
+ $status = acym_getVar('string', 'subscribers_status', '');
+
+ $usersPerPage = acym_getCMSConfig('list_limit', 20);
+ $page = acym_getVar('int', 'subscribers_pagination_page', 1);
+
+ $listData = [];
+ $listData['listInformation'] = $this->listClass->getOneById($listId);
+
+ $link = $this->edition ? acym_completeLink('lists&task=edit&step=subscribers&edition=1&id=').$listId : '';
+ $this->breadcrumb[acym_escape($listData['listInformation']->name)] = $link;
+
+ if (is_null($listData['listInformation'])) {
+ acym_enqueueNotification(acym_translation("ACYM_LIST_DOESNT_EXIST"), 'error', 0);
+ $this->listing();
+
+ return;
+ }
+
+ $matchingUsers = $this->listClass->getMatchingSubscribersByListId(
+ [
+ 'search' => $searchFilter,
+ 'usersPerPage' => $usersPerPage,
+ 'offset' => ($page - 1) * $usersPerPage,
+ 'status' => $status,
+ ],
+ $listId
+ );
+
+ $allSubscribedUsersId = $this->listClass->getSubscribersIdsById($listId);
+
+ $pagination = acym_get('helper.pagination');
+ $pagination->setStatus($matchingUsers['total'], $page, $usersPerPage);
+
+ $listData['listSubscribers'] = $matchingUsers['users'];
+ $listData['pagination'] = $pagination;
+ $listData['search'] = $searchFilter;
+ $listData['userNumberPerStatus'] = $matchingUsers['status'];
+ $listData['status'] = $status;
+ $listData['subscribedUsersId'] = json_encode($allSubscribedUsersId);
+
+ parent::display($listData);
+ }
+
+ public function unsubscribeUser()
+ {
+ acym_checkToken();
+ $listId = acym_getVar("int", "id", 0);
+ $userId = acym_getVar("int", "userid", 0);
+
+ if (!empty($listId) && !empty($userId)) {
+ $userClass = acym_get('class.user');
+ if ($userClass->unsubscribe($userId, $listId)) {
+ acym_enqueueNotification(acym_translation("ACYM_THE_USER_HAS_BEEN_UNSUBSCRIBED"), 'success', 8000);
+ } else {
+ acym_enqueueNotification(acym_translation("ACYM_THE_USER_CANT_BE_UNSUBSCRIBED"), 'error', 0);
+ }
+ } else {
+ acym_enqueueNotification(acym_translation("ACYM_THE_USER_CANT_BE_UNSUBSCRIBED"), 'error', 0);
+ }
+ $this->subscribers();
+ }
+
+ public function unsubscribeUsers()
+ {
+ acym_checkToken();
+ $ids = acym_getVar('array', 'elements_checked', []);
+ $userClass = acym_get('class.user');
+ foreach ($ids as $id) {
+ if (!empty($id)) {
+ $userClass->unsubscribe($id, acym_getVar('int', 'id', 0));
+ }
+ }
+
+ $this->edit();
+ }
+
+ public function unsubscribeSelected()
+ {
+ acym_checkToken();
+ $listId = acym_getVar("int", "id", 0);
+ $selectedUsers = acym_getVar("array", "elements_checked", []);
+
+
+ if (!empty($selectedUsers) && !empty($listId)) {
+ $userClass = acym_get('class.user');
+ if ($userClass->unsubscribe($selectedUsers, $listId)) {
+ acym_enqueueNotification(acym_translation("ACYM_SUCCESSFULLY_UNSUBSCRIBED"), 'success', 8000);
+ } else {
+ acym_enqueueNotification(acym_translation("ACYM_ERROR_DURING_UNSUBSCRIBE"), 'error', 0);
+ }
+ } else {
+ acym_enqueueNotification(acym_translation("ACYM_THE_USER_CANT_BE_UNSUBSCRIBED"), 'error', 0);
+ }
+
+ acym_setVar('search', acym_getVar('string', 'subscribers_search', ''));
+ acym_setVar('status', acym_getVar('string', 'subscribers_status', ''));
+ acym_setVar('list_limit', acym_getCMSConfig('list_limit', 20));
+ acym_setVar('pagination_page', acym_getVar('int', 'subscribers_pagination_page', ''));
+
+ $this->subscribers();
+ }
+
+ public function settings()
+ {
+ acym_setVar("layout", "settings");
+ $listId = acym_getVar("int", "id", 0);
+ $listTagsName = [];
+
+ $randColor = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
+
+ if (!$listId) {
+ $listInformation = new stdClass();
+ $listInformation->id = "";
+ $listInformation->name = "";
+ $listInformation->active = 1;
+ $listInformation->from_name = "";
+ $listInformation->from_email = "";
+ $listInformation->reply_to_name = "";
+ $listInformation->reply_to_email = "";
+ $listInformation->color = '#'.$randColor[rand(0, 15)].$randColor[rand(0, 15)].$randColor[rand(0, 15)].$randColor[rand(0, 15)].$randColor[rand(0, 15)].$randColor[rand(0, 15)];
+
+ $this->breadcrumb[acym_translation('ACYM_NEW_LIST')] = acym_completeLink('lists&task=edit&step=settings');
+ } else {
+
+ $listsTags = acym_get('class.tag')->getAllTagsByElementId('list', $listId);
+
+ foreach ($listsTags as $oneTag) {
+ $listTagsName[] = $oneTag;
+ }
+
+ $listInformation = $this->listClass->getOneById($listId);
+ if (is_null($listInformation)) {
+ acym_enqueueNotification(acym_translation("ACYM_LIST_DOESNT_EXIST"), 'error', 0);
+ $this->listing();
+
+ return;
+ }
+
+ $this->breadcrumb[acym_escape($listInformation->name)] = acym_completeLink('lists&task=edit&step=settings&id=').$listId;
+ acym_setVar('edition', '1');
+ }
+
+ $listData = [
+ "listInformation" => $listInformation,
+ "allTags" => acym_get('class.tag')->getAllTagsByType('list'),
+ "listTagsName" => $listTagsName,
+ ];
+
+ parent::display($listData);
+ }
+
+ private function selectEmail($type)
+ {
+ acym_setVar("layout", $type);
+ $listId = acym_getVar("int", "id");
+ if (empty($listId)) {
+ return $this->listing();
+ }
+
+ $searchFilter = acym_getVar('string', $type.'_search', '');
+
+ $mailsPerPage = 12;
+ $page = acym_getVar('int', $type.'_pagination_page', 1);
+
+ $mailClass = acym_get('class.mail');
+ $mails = $mailClass->getMailsByType(
+ $type,
+ [
+ 'mailsPerPage' => $mailsPerPage,
+ 'offset' => ($page - 1) * $mailsPerPage,
+ 'search' => $searchFilter,
+ ]
+ );
+
+ $currentList = $this->listClass->getOneById($listId);
+ $columnId = $type.'_id';
+ $selectedTemplate = !empty($currentList->$columnId) ? $currentList->$columnId : '';
+ $this->breadcrumb[acym_escape($currentList->name)] = acym_completeLink('lists&task=edit&step='.$type.'&id=').$listId.($this->edition ? '&edition=1' : '');
+
+ $pagination = acym_get('helper.pagination');
+ $pagination->setStatus($mails['total'], $page, $mailsPerPage);
+
+ foreach ($mails['mails'] as $oneMail) {
+ if (empty($oneMail->thumbnail)) {
+ $oneMail->thumbnail = ACYM_IMAGES.'default_template_thumbnail.png';
+ }
+ }
+
+ $data = [
+ $type.'Mails' => $mails['mails'],
+ 'pagination' => $pagination,
+ 'search' => $searchFilter,
+ 'selected'.ucfirst($type) => $selectedTemplate,
+ 'listId' => $listId,
+ ];
+
+ parent::display($data);
+ }
+
+ public function welcome()
+ {
+ $listId = acym_getVar("int", "id", 0);
+ $listInformation = $this->listClass->getOneById($listId);
+
+ if (is_null($listInformation)) {
+ acym_enqueueNotification(acym_translation("ACYM_LIST_DOESNT_EXIST"), 'error', 0);
+ $this->listing();
+
+ return;
+ }
+
+ $this->selectEmail('welcome');
+ }
+
+ public function unsubscribe()
+ {
+ $listId = acym_getVar("int", "id", 0);
+ $listInformation = $this->listClass->getOneById($listId);
+
+ if (is_null($listInformation)) {
+ acym_enqueueNotification(acym_translation("ACYM_LIST_DOESNT_EXIST"), 'error', 0);
+ $this->listing();
+
+ return;
+ }
+
+ $this->selectEmail('unsubscribe');
+ }
+
+ public function addSubscribers()
+ {
+ acym_checkToken();
+ $idsNewSubscribers = json_decode(acym_getVar('string', 'users_selected', ""));
+ $listId = acym_getVar('int', 'id', 0);
+
+ if (!empty($idsNewSubscribers) && is_array($idsNewSubscribers) && !empty($listId)) {
+ $userClass = acym_get('class.user');
+ $userClass->subscribe($idsNewSubscribers, $listId);
+ acym_enqueueNotification(acym_translation('ACYM_USERS_SUBSCRIBED'), "success", "5000");
+ } else {
+ acym_enqueueNotification(acym_translation('ACYM_NO_USERS_HAVE_BEEN_SUBSCRIBED'), "notice", "5000");
+ }
+
+ $this->subscribers();
+ }
+
+ public function saveSettings()
+ {
+ acym_checkToken();
+
+ $listUseSameReplyTo = acym_getVar("boolean", "list_use_same_reply-to");
+ $formData = (object)acym_getVar("array", "list", []);
+
+ $listId = acym_getVar('int', 'id', 0);
+ if (!empty($listId)) {
+ $formData->id = $listId;
+ }
+
+ $allowedFields = acym_getColumns('list');
+ $listInformation = new stdClass();
+ foreach ($formData as $name => $data) {
+ if (!in_array($name, $allowedFields)) {
+ continue;
+ }
+ $listInformation->{$name} = $data;
+ }
+
+ $listInformation->tags = acym_getVar("array", "list_tags", []);
+
+ if ($listUseSameReplyTo) {
+ $listInformation->reply_to_name = $listInformation->from_name;
+ $listInformation->reply_to_email = $listInformation->from_email;
+ }
+
+ $listId = $this->listClass->save($listInformation);
+
+ if (!empty($listId)) {
+ acym_setVar('id', $listId);
+ acym_enqueueNotification(acym_translation_sprintf("ACYM_LIST_IS_SAVED", $listInformation->name), 'success', 8000);
+ } else {
+ acym_enqueueNotification(acym_translation("ACYM_ERROR_SAVING"), 'error', 0);
+ if (!empty($this->listClass->errors)) {
+ acym_enqueueNotification($this->listClass->errors, 'error', 0);
+ }
+ acym_setVar('nextstep', 'listing');
+ }
+
+ return $this->edit();
+ }
+
+ public function saveSubscribers()
+ {
+ acym_checkToken();
+ $listId = acym_getVar("int", "id", 0);
+ acym_setVar('id', $listId);
+
+ $this->edit();
+ }
+
+ public function saveWelcome()
+ {
+ $this->saveMail();
+ }
+
+ public function saveUnsubscribe()
+ {
+ $this->saveMail();
+ }
+
+ private function saveMail()
+ {
+ acym_checkToken();
+
+ $listId = acym_getVar('int', "id");
+ $mail = acym_getVar('int', 'mailSelected') == 0 ? null : acym_getVar('int', 'mailSelected');
+ $typeMail = acym_getVar('string', 'typeMail');
+
+ $listData = new stdClass();
+ $listData->id = $listId;
+
+ if ($typeMail == 'welcome') {
+ $listData->welcome_id = $mail;
+ } else {
+ $listData->unsubscribe_id = $mail;
+ }
+
+ $listId = $this->listClass->save($listData);
+
+ if (empty($listId)) {
+ acym_enqueueNotification(acym_translation('ACYM_ERROR_SAVING_LIST_TEMPLATE'), 'error', 0);
+ if (!empty($this->listClass->errors)) {
+ acym_enqueueNotification($this->listClass->errors, 'error', 0);
+ }
+ acym_setVar('nextstep', 'listing');
+ } else {
+ acym_enqueueNotification(acym_translation("ACYM_SUCCESSFULLY_SAVED"), 'success', 8000);
+ }
+
+ return $this->edit();
+ }
+
+ public function setVisible()
+ {
+ acym_checkToken();
+ $ids = acym_getVar('array', 'elements_checked', []);
+
+ if (!empty($ids)) {
+ $this->listClass->setVisible($ids, 1);
+ }
+
+ $this->listing();
+ }
+
+ public function setInvisible()
+ {
+ acym_checkToken();
+ $ids = acym_getVar('array', 'elements_checked', []);
+
+ if (!empty($ids)) {
+ $this->listClass->setVisible($ids, 0);
+ }
+
+ $this->listing();
+ }
+
+ public function setAjaxListing()
+ {
+ $showSelected = acym_getVar('string', 'show_selected');
+ $matchingListsData = new stdClass();
+ $matchingListsData->ordering = 'name';
+ $matchingListsData->searchFilter = acym_getVar('string', 'search_lists');
+ $matchingListsData->listsPerPage = acym_getVar('string', 'listsPerPage');
+ $matchingListsData->idsSelected = json_decode(acym_getVar('string', 'selectedLists'));
+ $matchingListsData->idsAlready = json_decode(acym_getVar('string', 'alreadyLists'));
+ $matchingListsData->page = acym_getVar('int', 'pagination_page_ajax');
+ $matchingListsData->needDisplaySub = acym_getVar('int', 'needDisplaySub');
+ $matchingListsData->displayNonActive = acym_getVar('int', 'nonActive');
+ if (empty($matchingListsData->page)) {
+ $matchingListsData->page = 1;
+ }
+
+
+ $params = [
+ 'ordering' => $matchingListsData->ordering,
+ 'search' => $matchingListsData->searchFilter,
+ 'listsPerPage' => $matchingListsData->listsPerPage,
+ 'offset' => ($matchingListsData->page - 1) * $matchingListsData->listsPerPage,
+ 'already' => $matchingListsData->idsAlready,
+ ];
+
+ if ($showSelected == 'true') {
+ $params['ids'] = $matchingListsData->idsSelected;
+ }
+
+ $lists = $this->listClass->getListsWithIdNameCount($params);
+
+ $return = '';
+
+ if (empty($lists['lists'])) {
+ $return .= ''.acym_translation('ACYM_NO_RESULTS_FOUND').' ';
+ }
+
+ foreach ($lists['lists'] as $list) {
+ if (!empty($matchingListsData->displayNonActive) && $list->active == 0) {
+ continue;
+ }
+ $return .= '';
+ }
+
+ $pagination = acym_get('helper.pagination');
+ $pagination->setStatus($lists['total'], $matchingListsData->page, $matchingListsData->listsPerPage);
+
+ $return .= $pagination->displayAjax();
+
+ echo $return;
+ exit;
+ }
+
+ public function ajaxGetLists()
+ {
+ $subscribedListsIds = acym_getVar('string', 'ids');
+ $echo = '';
+
+ $subscribedListsIds = explode(',', $subscribedListsIds);
+
+ $allLists = $this->listClass->getListsByIds($subscribedListsIds);
+
+ foreach ($allLists as $list) {
+ $echo .= '
+
+
+
'.$list->name.'
+
+
+
+
+
+ '.acym_translation('ACYM_REMOVE').'
+
+
';
+ }
+ $return = [];
+ $return['html'] = $echo;
+ $return['notif'] = acym_translation_sprintf('ACYM_X_CONFIRMATION_SUBSCRIPTION_ADDED_AND_CLICK_TO_SAVE', count($allLists));
+ $return = json_encode($return);
+ echo $return;
+ exit;
+ }
+}
+
diff --git a/deployed/acym/administrator/components/com_acym/controllers/mails.php b/deployed/acym/administrator/components/com_acym/controllers/mails.php
new file mode 100644
index 00000000..68cda57b
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/controllers/mails.php
@@ -0,0 +1,620 @@
+breadcrumb[acym_translation('automation' != $type ? 'ACYM_TEMPLATES' : 'ACYM_AUTOMATION')] = acym_completeLink('automation' != $type ? 'mails' : 'automation');
+ $this->loadScripts = [
+ 'edit' => ['colorpicker', 'datepicker', 'editor', 'thumbnail', 'foundation-email', 'parse-css'],
+ 'apply' => ['colorpicker', 'datepicker', 'editor', 'thumbnail', 'foundation-email', 'parse-css'],
+ 'test' => ['colorpicker', 'datepicker', 'editor', 'thumbnail', 'foundation-email', 'parse-css'],
+ ];
+ header('X-XSS-Protection:0');
+ }
+
+ public function listing()
+ {
+ acym_setVar('layout', 'listing');
+
+ $searchFilter = acym_getVar('string', 'mails_search', '');
+ $tagFilter = acym_getVar('string', 'mails_tag', '');
+ $ordering = acym_getVar('string', 'mails_ordering', 'id');
+ $status = acym_getVar('string', 'mails_status', 'standard');
+ $orderingSortOrder = acym_getVar('string', 'mails_ordering_sort_order', 'desc');
+
+ $mailsPerPage = 12;
+ $page = acym_getVar('int', 'mails_pagination_page', 1);
+
+ $mailClass = acym_get('class.mail');
+ $matchingMails = $mailClass->getMatchingMails(
+ [
+ 'ordering' => $ordering,
+ 'search' => $searchFilter,
+ 'mailsPerPage' => $mailsPerPage,
+ 'offset' => ($page - 1) * $mailsPerPage,
+ 'tag' => $tagFilter,
+ 'status' => $status,
+ 'ordering_sort_order' => $orderingSortOrder,
+ ]
+ );
+
+ $matchingMailsNb = count($matchingMails['mails']);
+
+ if (empty($matchingMailsNb)) {
+ if ($page > 1) {
+ acym_setVar('mails_pagination_page', 1);
+ $this->listing();
+
+ return;
+ } elseif (!empty($status)) {
+ acym_setVar('mails_status', '');
+ $this->listing();
+
+ return;
+ }
+ }
+
+ $pagination = acym_get('helper.pagination');
+ $pagination->setStatus($matchingMails['total'], $page, $mailsPerPage);
+
+ foreach ($matchingMails['mails'] as $oneTemplate) {
+ if (empty($oneTemplate->thumbnail)) {
+ $oneTemplate->thumbnail = ACYM_IMAGES.'default_template_thumbnail.png';
+ }
+ }
+
+ $mailsData = [
+ 'allMails' => $matchingMails['mails'],
+ 'allTags' => acym_get('class.tag')->getAllTagsByType('mail'),
+ 'pagination' => $pagination,
+ 'search' => $searchFilter,
+ 'tag' => $tagFilter,
+ 'ordering' => $ordering,
+ 'status' => $status,
+ 'mailNumberPerStatus' => $matchingMails['status'],
+ 'orderingSortOrder' => $orderingSortOrder,
+ ];
+ parent::display($mailsData);
+
+ return;
+ }
+
+ public function choose()
+ {
+ acym_setVar("layout", "choose");
+
+ $this->breadcrumb[acym_translation('ACYM_CREATE')] = "";
+
+ $searchFilter = acym_getVar('string', 'mailchoose_search', '');
+ $tagFilter = acym_getVar('string', 'mailchoose_tag', 0);
+ $ordering = acym_getVar('string', 'mailchoose_ordering', 'creation_date');
+ $orderingSortOrder = acym_getVar('string', 'mailchoose_ordering_sort_order', 'DESC');
+ $type = acym_getVar('string', 'mailchoose_type', 'custom');
+
+ $mailsPerPage = 12;
+ $page = acym_getVar('int', 'mailchoose_pagination_page', 1);
+
+ $mailClass = acym_get('class.mail');
+ $matchingMails = $mailClass->getMatchingMails(
+ [
+ 'ordering' => $ordering,
+ 'ordering_sort_order' => $orderingSortOrder,
+ 'search' => $searchFilter,
+ 'mailsPerPage' => $mailsPerPage,
+ 'offset' => ($page - 1) * $mailsPerPage,
+ 'tag' => $tagFilter,
+ 'type' => $type,
+ ]
+ );
+
+ $pagination = acym_get('helper.pagination');
+ $pagination->setStatus($matchingMails['total'], $page, $mailsPerPage);
+
+ foreach ($matchingMails['mails'] as $oneTemplate) {
+ if (empty($oneTemplate->thumbnail)) {
+ $oneTemplate->thumbnail = ACYM_IMAGES.'default_template_thumbnail.png';
+ }
+ }
+
+ $mailsData = [
+ 'allMails' => $matchingMails['mails'],
+ 'allTags' => acym_get('class.tag')->getAllTagsByType('mail'),
+ 'pagination' => $pagination,
+ 'search' => $searchFilter,
+ 'tag' => $tagFilter,
+ 'ordering' => $ordering,
+ 'type' => $type,
+ ];
+
+
+ parent::display($mailsData);
+ }
+
+ public function edit()
+ {
+ $tempId = acym_getVar("int", "id");
+ $mailClass = acym_get('class.mail');
+ $typeEditor = acym_getVar('string', 'type_editor');
+ $notification = acym_getVar("cmd", "notification");
+ $return = acym_getVar('string', 'return', '');
+ $return = empty($return) ? '' : urldecode($return);
+ $type = acym_getVar('string', 'type');
+
+ if (!empty($notification)) {
+ $mail = $mailClass->getOneByName($notification);
+ if (!empty($mail->id)) {
+ $tempId = $mail->id;
+ }
+ }
+
+ $isAutomationAdmin = false;
+
+ if (strpos($type, 'automation') !== false || empty($tempId)) {
+ $fromId = acym_getVar("int", "from");
+ if ($type == 'automation_admin') {
+ $type = 'automation';
+ $isAutomationAdmin = true;
+ }
+
+ if (empty($fromId)) {
+ $mail = new stdClass();
+ $mail->name = '';
+ $mail->subject = '';
+ $mail->preheader = '';
+ $mail->tags = [];
+ $mail->type = '';
+ $mail->body = '';
+ $mail->editor = 'automation' == $type ? 'acyEditor' : $typeEditor;
+ $mail->headers = '';
+ $mail->thumbnail = null;
+ } else {
+ $mail = $mailClass->getOneById($fromId);
+ if (0 == $mail->drag_editor) {
+ $mail->editor = 'html';
+ } else {
+ $mail->editor = !empty($typeEditor) ? $typeEditor : 'acyEditor';
+ }
+ }
+
+ if (!empty($type)) $mail->type = $type;
+
+ if ('automation' != $type || empty($fromId)) $mail->id = 0;
+ $this->breadcrumb[acym_translation('automation' != $type ? 'ACYM_CREATE_TEMPLATE' : 'ACYM_NEW_EMAIL')] = acym_completeLink('mails&task=edit&type_editor='.$typeEditor.(!empty($fromId) ? '&from='.$fromId : '').'&type='.$type.(!empty($return) ? '&return='.urlencode($return) : ''));
+ } else {
+ $mail = $mailClass->getOneById($tempId);
+ $mail->editor = $mail->drag_editor == 0 ? 'html' : 'acyEditor';
+ if (!empty($typeEditor)) $mail->editor = $typeEditor;
+
+ if (empty($notification)) {
+ $this->breadcrumb[acym_escape($mail->name)] = acym_completeLink('mails&task=edit&id='.$mail->id);
+ } else {
+ if (empty($return)) {
+ $return = empty($_SERVER['HTTP_REFERER']) ? '' : $_SERVER['HTTP_REFERER'];
+ }
+
+ $notifName = acym_translation('ACYM_NOTIFICATIION_'.strtoupper(substr($mail->name, 4)));
+ if (strpos($notifName, 'ACYM_NOTIFICATIION_') !== false) {
+ $notifName = $mail->name;
+ }
+ $this->breadcrumb[acym_escape($notifName)] = acym_completeLink('mails&task=edit¬ification='.$mail->name.'&return='.urlencode($return));
+ }
+
+
+ if (strpos($mail->stylesheet, '[class="') !== false) {
+ acym_enqueueMessage(acym_translation('ACYM_WARNING_STYLESHEET_NOT_CORRECT'), 'warning');
+ }
+ }
+
+ $config = acym_config();
+
+ $data = [
+ "mail" => $mail,
+ 'allTags' => acym_get('class.tag')->getAllTagsByType('mail'),
+ 'config' => acym_config(),
+ 'isAutomationAdmin' => $isAutomationAdmin,
+ 'social_icons' => $config->get('social_icons', '{}'),
+ ];
+
+ if (!empty($return)) $data['return'] = $return;
+
+ acym_setVar("layout", "edit");
+ parent::display($data);
+ }
+
+ public function editor_wysid()
+ {
+ acym_setVar("layout", "editor_wysid");
+
+ parent::display();
+ }
+
+ public function store($ajax = false)
+ {
+ acym_checkToken();
+
+ $mailClass = acym_get('class.mail');
+ $formData = acym_getVar('array', 'mail', []);
+ $mail = new stdClass();
+ $allowedFields = acym_getColumns('mail');
+ $return = acym_getVar('string', 'return');
+ $fromAutomation = false;
+ if (!empty($return) && strpos($return, 'automation') !== false) $fromAutomation = true;
+ foreach ($formData as $name => $data) {
+ if (!in_array($name, $allowedFields)) {
+ continue;
+ }
+ $mail->{$name} = $data;
+ }
+
+ if ($fromAutomation) {
+ acym_setVar('from', $mail->id);
+ acym_setVar('type', 'automation');
+ acym_setVar('type_editor', 'acyEditor');
+ }
+
+ if (empty($mail->subject) && !empty($mail->type) && $mail->type != 'standard') {
+ return false;
+ }
+
+ $mail->tags = acym_getVar("array", "template_tags", []);
+ $mail->body = acym_getVar('string', 'editor_content', '', 'REQUEST', ACYM_ALLOWRAW);
+ $mail->settings = acym_getVar('string', 'editor_settings', '', 'REQUEST', ACYM_ALLOWRAW);
+ $mail->stylesheet = acym_getVar('string', 'editor_stylesheet', '', 'REQUEST', ACYM_ALLOWRAW);
+ $mail->headers = acym_getVar('string', 'editor_headers', '', 'REQUEST', ACYM_ALLOWRAW);
+ $mail->thumbnail = $fromAutomation ? '' : acym_getVar('string', 'editor_thumbnail', '', 'REQUEST', ACYM_ALLOWRAW);
+ $mail->template = $fromAutomation ? 2 : 1;
+ $mail->library = 0;
+ $mail->drag_editor = strpos($mail->body, 'acym__wysid__template') === false ? 0 : 1;
+ if ($fromAutomation) $mail->type = 'automation';
+ if (empty($mail->id)) {
+ $mail->creation_date = acym_date('now', 'Y-m-d H:i:s', false);
+ }
+ $mailID = $mailClass->save($mail);
+ if (!empty($mailID)) {
+ if (!$ajax) acym_enqueueNotification(acym_translation('ACYM_SUCCESSFULLY_SAVED'), 'success', 8000);
+ if ($fromAutomation) {
+ acym_setVar('from', $mailID);
+ acym_setVar('type', 'automation');
+ acym_setVar('type_editor', 'acyEditor');
+ } else {
+ acym_setVar('mailID', $mailID);
+ }
+
+ return $mailID;
+ } else {
+ if (!$ajax) acym_enqueueNotification(acym_translation('ACYM_ERROR_SAVING'), 'error', 0);
+ if (!empty($mailClass->errors)) {
+ if (!$ajax) acym_enqueueNotification($mailClass->errors, 'error', 0);
+ }
+
+ return false;
+ }
+ }
+
+ public function apply()
+ {
+ $this->store();
+ $mailId = acym_getVar('int', 'mailID', 0);
+ acym_setVar('id', $mailId);
+ $this->edit();
+ }
+
+ public function save()
+ {
+ $mailid = $this->store();
+
+ $return = str_replace('{mailid}', empty($mailid) ? '' : $mailid, acym_getVar('string', 'return'));
+ if (empty($return)) {
+ $this->listing();
+ } else {
+ acym_redirect($return);
+ }
+ }
+
+ public function autoSave()
+ {
+ $mailClass = acym_get('class.mail');
+ $mail = new stdClass();
+
+ $mail->id = acym_getVar('int', 'mailId', 0);
+ $mail->autosave = acym_getVar('string', 'autoSave', '', 'REQUEST', ACYM_ALLOWRAW);
+
+ if (empty($mail->id) || !$mailClass->autoSave($mail)) {
+ echo 'error';
+ } else {
+ echo 'saved';
+ }
+
+ exit;
+ }
+
+ public function getTemplateAjax()
+ {
+ $searchFilter = acym_getVar('string', 'search', '');
+ $tagFilter = acym_getVar('string', 'tag', 0);
+ $ordering = 'creation_date';
+ $orderingSortOrder = 'DESC';
+ $type = acym_getVar('string', 'type', 'custom');
+ $editor = acym_getVar('string', 'editor');
+ $automation = acym_getVar('string', 'automation');
+
+ $mailsPerPage = 12;
+ $page = acym_getVar('int', 'pagination_page_ajax', 1);
+ $page != 'undefined' ? : $page = '1';
+
+ $mailClass = acym_get('class.mail');
+ $matchingMails = $mailClass->getMatchingMails(
+ [
+ 'ordering' => $ordering,
+ 'ordering_sort_order' => $orderingSortOrder,
+ 'search' => $searchFilter,
+ 'mailsPerPage' => $mailsPerPage,
+ 'offset' => ($page - 1) * $mailsPerPage,
+ 'tag' => $tagFilter,
+ 'type' => $type,
+ 'editor' => $editor,
+ 'automation' => $automation,
+ ]
+ );
+
+ $return = '';
+
+ foreach ($matchingMails['mails'] as $oneTemplate) {
+ if (empty($oneTemplate->thumbnail)) {
+ $oneTemplate->thumbnail = ACYM_IMAGES.'default_template_thumbnail.png';
+ }
+
+ $return .= '
+
';
+
+ $thumbnail = $oneTemplate->thumbnail;
+ if (strpos($oneTemplate->thumbnail, 'default_template') === false) {
+ $thumbnail = ACYM_TEMPLATE_THUMBNAILS.$oneTemplate->thumbnail;
+ }
+
+ $url = acym_getVar('cmd', 'ctrl').'&task=edit&step=editEmail&from='.intval($oneTemplate->id);
+ if (!empty($this->data['campaignInformation'])) $url .= '&id='.intval($this->data['campaignInformation']);
+ $return .= '
';
+
+
+ $return .= ' ';
+ $return .= ' ';
+ if ($oneTemplate->drag_editor) {
+ $return .= '
';
+ }
+
+ if (strlen($oneTemplate->name) > 55) {
+ $oneTemplate->name = substr($oneTemplate->name, 0, 50).'...';
+ }
+ $return .= '
+
+
';
+ }
+
+ $return .= '
';
+
+ $pagination = acym_get('helper.pagination');
+ $pagination->setStatus($matchingMails['total'], $page, $mailsPerPage);
+
+ $return .= $pagination->displayAjax();
+
+ echo $return;
+ exit;
+ }
+
+ public function getMailContent()
+ {
+ $mailClass = acym_get('class.mail');
+ $from = acym_getVar('string', 'from', '');
+
+ if (empty($from)) {
+ echo 'error';
+ exit;
+ }
+
+ $echo = $mailClass->getOneById($from);
+
+ if ($echo->drag_editor == 0) {
+ echo 'no_new_editor';
+ exit;
+ }
+
+ $echo = ['mailSettings' => $echo->settings, 'content' => $echo->body, 'stylesheet' => $echo->stylesheet];
+
+ $echo = json_encode($echo);
+
+ echo $echo;
+ exit;
+ }
+
+ public function test()
+ {
+ $this->store();
+ $mailId = acym_getVar('int', 'mailID', 0);
+ acym_setVar('id', $mailId);
+
+ $mailClass = acym_get('class.mail');
+ $mail = $mailClass->getOneById($mailId);
+
+ if (empty($mail)) {
+ acym_enqueueNotification(acym_translation('ACYM_CAMPAIGN_NOT_FOUND'), 'error', 5000);
+ $this->edit();
+
+ return;
+ }
+
+ $mailerHelper = acym_get('helper.mailer');
+ $mailerHelper->autoAddUser = true;
+ $mailerHelper->checkConfirmField = false;
+ $mailerHelper->report = false;
+
+ $currentEmail = acym_currentUserEmail();
+ if ($mailerHelper->sendOne($mailId, $currentEmail)) {
+ acym_enqueueNotification(acym_translation_sprintf('ACYM_SEND_SUCCESS', $mail->name, $currentEmail), 'info', 5000);
+ } else {
+ acym_enqueueNotification(acym_translation_sprintf('ACYM_SEND_ERROR', $mail->name, $currentEmail), 'error', 5000);
+ }
+
+ $this->edit();
+ }
+
+ public function setNewThumbnail()
+ {
+ acym_checkToken();
+ $contentThumbnail = acym_getVar('string', 'content', '');
+ $file = acym_getVar('string', 'thumbnail', '');
+
+ $config = acym_config();
+
+ if (empty($file) || strpos($file, 'http') === 0) {
+ $thumbNb = $config->get('numberThumbnail', 2);
+ $file = 'thumbnail_'.($thumbNb + 1).'.png';
+ $newConfig = new stdClass();
+ $newConfig->numberThumbnail = $thumbNb + 1;
+ $config->save($newConfig);
+ }
+
+ $extension = acym_fileGetExt($file);
+ if (strpos($file, 'thumbnail_') === false || !in_array($extension, ['png', 'jpeg', 'jpg', 'gif'])) exit;
+
+ acym_createFolder(ACYM_UPLOAD_FOLDER_THUMBNAIL);
+ file_put_contents(ACYM_UPLOAD_FOLDER_THUMBNAIL.$file, base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $contentThumbnail)));
+ echo $file;
+
+ exit;
+ }
+
+ public function loadCSS()
+ {
+ $idMail = acym_getVar('int', 'id', 0);
+ if (empty($idMail)) {
+ exit;
+ }
+
+ $mailClass = acym_get('class.mail');
+ $mail = $mailClass->getOneById($idMail);
+
+ echo $mailClass->buildCSS($mail->stylesheet);
+ exit;
+ }
+
+ public function doUploadTemplate()
+ {
+ $mailClass = acym_get('class.mail');
+ $mailClass->doupload();
+
+ $this->listing();
+ }
+
+ public function setNewIconShare()
+ {
+ $socialName = acym_getVar('string', 'social', '');
+ $extension = pathinfo($_FILES['file']['name']);
+ $newPath = ACYM_UPLOAD_FOLDER.'socials'.DS.$socialName.'.'.$extension['extension'];
+
+ if (!acym_uploadFile($_FILES['file']['tmp_name'], ACYM_ROOT.$newPath) || empty($socialName)) {
+ echo 'error';
+ exit;
+ }
+
+ $config = acym_config();
+ $newConfig = new stdClass();
+ $newConfig->social_icons = json_decode($config->get('social_icons', '{}'), true);
+
+ $newImg = acym_rootURI().$newPath;
+
+ $newConfig->social_icons[$socialName] = $newImg;
+ $newConfig->social_icons = json_encode($newConfig->social_icons);
+ $config->save($newConfig);
+
+ echo $newImg;
+ exit;
+ }
+
+ public function deleteMailAutomation()
+ {
+ $mailClass = acym_get('class.mail');
+ $mailId = acym_getVar('int', 'id', 0);
+
+ if (!empty($mailId)) $mailClass->delete($mailId);
+
+
+ exit;
+ }
+
+ public function duplicateMailAutomation()
+ {
+ $mailClass = acym_get('class.mail');
+ $mailId = acym_getVar('int', 'id', 0);
+ $prevMail = acym_getVar('int', 'previousId');
+
+ if (!empty($prevMail)) $mailClass->delete($prevMail);
+
+ if (empty($mailId)) {
+ echo json_encode(['error' => acym_translation_sprintf('ACYM_NOT_FOUND', acym_translation('ACYM_ID'))]);
+ exit;
+ }
+
+ $mail = $mailClass->getOneById($mailId);
+
+ if (empty($mail)) {
+ echo json_encode(['error' => acym_translation_sprintf('ACYM_NOT_FOUND', acym_translation('ACYM_EMAIL'))]);
+ exit;
+ }
+
+ $newMail = new stdClass();
+ $newMail->name = $mail->name.'_copy';
+ $newMail->thumbnail = '';
+ $newMail->type = 'automation';
+ $newMail->drag_editor = $mail->drag_editor;
+ $newMail->library = 0;
+ $newMail->body = $mail->body;
+ $newMail->subject = $mail->subject;
+ $newMail->template = 2;
+ $newMail->from_name = $mail->from_name;
+ $newMail->from_email = $mail->from_email;
+ $newMail->reply_to_name = $mail->reply_to_name;
+ $newMail->reply_to_email = $mail->reply_to_email;
+ $newMail->bcc = $mail->bcc;
+ $newMail->settings = $mail->settings;
+ $newMail->stylesheet = $mail->stylesheet;
+ $newMail->attachments = $mail->attachments;
+ $newMail->headers = $mail->headers;
+
+ $newMail->id = $mailClass->save($newMail);
+
+ if (empty($newMail->id)) {
+ echo json_encode(['error' => acym_translation('ACYM_COULD_NOT_DUPLICATE_EMAIL')]);
+ exit;
+ }
+
+ echo json_encode($newMail);
+ exit;
+ }
+
+ public function saveAjax()
+ {
+ $return = $this->store(true);
+ echo json_encode(['error' => !$return ? acym_translation('ACYM_ERROR_SAVING') : '', 'data' => $return]);
+ exit;
+ }
+}
+
diff --git a/deployed/acym/administrator/components/com_acym/controllers/queue.php b/deployed/acym/administrator/components/com_acym/controllers/queue.php
new file mode 100644
index 00000000..347d9641
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/controllers/queue.php
@@ -0,0 +1,204 @@
+breadcrumb[acym_translation('ACYM_QUEUE')] = acym_completeLink('queue');
+ $this->setDefaultTask('campaigns');
+ }
+
+ public function campaigns()
+ {
+ acym_setVar('layout', 'campaigns');
+
+ $config = acym_config();
+ if (acym_level(1) && $config->get('cron_last', 0) < (time() - 43200)){
+ acym_enqueueMessage(acym_translation('ACYM_CREATE_CRON_REMINDER').' '.acym_translation('ACYM_GOTO_CONFIG').' ', 'warning');
+ }
+
+ $searchFilter = acym_getVar('string', 'cqueue_search', '');
+ $tagFilter = acym_getVar('string', 'cqueue_tag', '');
+ $status = acym_getVar('string', 'cqueue_status', '');
+
+ $campaignsPerPage = acym_getCMSConfig('list_limit', 20);
+ $page = acym_getVar('int', 'cqueue_pagination_page', 1);
+
+ $queueClass = acym_get('class.queue');
+ $matchingElements = $queueClass->getMatchingCampaigns(
+ [
+ 'search' => $searchFilter,
+ 'tag' => $tagFilter,
+ 'status' => $status,
+ 'campaignsPerPage' => $campaignsPerPage,
+ 'offset' => ($page - 1) * $campaignsPerPage,
+ ]
+ );
+
+ $pagination = acym_get('helper.pagination');
+ $pagination->setStatus($matchingElements['total'], $page, $campaignsPerPage);
+
+ $viewData = [
+ 'allElements' => $matchingElements['elements'],
+ 'pagination' => $pagination,
+ 'search' => $searchFilter,
+ 'tag' => $tagFilter,
+ 'tags' => acym_get('class.tag')->getAllTagsByType('mail'),
+ 'numberPerStatus' => $matchingElements['status'],
+ 'status' => $status,
+ ];
+
+ $this->breadcrumb[acym_translation('ACYM_CAMPAIGNS')] = acym_completeLink('queue');
+ parent::display($viewData);
+ }
+
+ public function automated()
+ {
+ }
+
+ public function detailed()
+ {
+ acym_setVar("layout", "detailed");
+
+ $searchFilter = acym_getVar('string', 'dqueue_search', '');
+ $tagFilter = acym_getVar('string', 'dqueue_tag', '');
+
+ $elementsPerPage = acym_getCMSConfig('list_limit', 20);
+ $page = acym_getVar('int', 'dqueue_pagination_page', 1);
+
+ $queueClass = acym_get('class.queue');
+ $matchingElements = $queueClass->getMatchingResults(
+ [
+ 'search' => $searchFilter,
+ 'tag' => $tagFilter,
+ 'elementsPerPage' => $elementsPerPage,
+ 'offset' => ($page - 1) * $elementsPerPage,
+ ]
+ );
+
+ $pagination = acym_get('helper.pagination');
+ $pagination->setStatus($matchingElements['total'], $page, $elementsPerPage);
+
+ $viewData = [
+ 'allElements' => $matchingElements['elements'],
+ 'pagination' => $pagination,
+ 'search' => $searchFilter,
+ 'tag' => $tagFilter,
+ 'tags' => acym_get('class.tag')->getAllTagsByType('mail'),
+ ];
+
+ $this->breadcrumb[acym_translation('ACYM_QUEUE_DETAILED')] = acym_completeLink('queue&task=detailed');
+ parent::display($viewData);
+ }
+
+ public function scheduleReady()
+ {
+ $queueClass = acym_get('class.queue');
+ $queueClass->scheduleReady();
+ }
+
+ public function continuesend()
+ {
+ $config = acym_config();
+
+ if ($config->get('queue_type') == 'onlyauto') {
+ acym_setNoTemplate();
+ acym_display(acym_translation('ACYM_ONLYAUTOPROCESS'), 'warning');
+
+ exit;
+ }
+
+ $newcrontime = time() + 120;
+ if ($config->get('cron_next') < $newcrontime) {
+ $newValue = new stdClass();
+ $newValue->cron_next = $newcrontime;
+ $config->save($newValue);
+ }
+
+ $mailid = acym_getCID('id');
+
+ $totalSend = acym_getVar('int', 'totalsend', 0);
+ if (empty($totalSend)) {
+ $query = 'SELECT COUNT(queue.user_id) FROM #__acym_queue AS queue LEFT JOIN #__acym_campaign AS campaign ON queue.mail_id = campaign.mail_id WHERE (campaign.id IS NULL OR campaign.active = 1) AND queue.sending_date < '.acym_escapeDB(acym_date('now', 'Y-m-d H:i:s', false));
+ if (!empty($mailid)) {
+ $query .= ' AND queue.mail_id = '.intval($mailid);
+ }
+ $totalSend = acym_loadResult($query);
+ }
+
+ $alreadySent = acym_getVar('int', 'alreadysent', 0);
+
+ $helperQueue = acym_get('helper.queue');
+ $helperQueue->id = $mailid;
+ $helperQueue->report = true;
+ $helperQueue->total = $totalSend;
+ $helperQueue->start = $alreadySent;
+ $helperQueue->pause = $config->get('queue_pause');
+ $helperQueue->process();
+
+ acym_setNoTemplate();
+ exit;
+ }
+
+ public function cancelSending()
+ {
+ $mailId = acym_getVar('int', 'acym__queue__cancel__mail_id');
+
+ if (!empty($mailId)) {
+ $hasStat = acym_loadResult("SELECT COUNT(*) FROM #__acym_user_stat WHERE mail_id = ".intval($mailId));
+
+ $result = [];
+
+ $result[] = acym_query('DELETE FROM #__acym_queue WHERE mail_id = '.intval($mailId));
+ if (empty($hasStat)) {
+ $result[] = acym_query('UPDATE #__acym_campaign SET draft = "1", sent = "0", sending_date = NULL WHERE mail_id = '.intval($mailId));
+ $result[] = acym_query('DELETE FROM #__acym_mail_stat WHERE mail_id = '.intval($mailId));
+ }
+ } else {
+ acym_enqueueNotification(acym_translation("ACYM_ERROR_QUEUE_CANCEL_CAMPAIGN"), "error", 10000);
+ }
+ $this->campaigns();
+ }
+
+ public function playPauseSending()
+ {
+ $active = acym_getVar("int", "acym__queue__play_pause__active__new_value");
+ $campaignId = acym_getVar("int", "acym__queue__play_pause__campaign_id");
+
+ if (!empty($campaignId)) {
+ $queueClass = acym_get('class.queue');
+ $queueClass->unpauseCampaign($campaignId, $active);
+ } else {
+ if (!empty($active)) {
+ acym_enqueueNotification(acym_translation("ACYM_ERROR_QUEUE_RESUME"), "error", 10000);
+ } else {
+ acym_enqueueNotification(acym_translation("ACYM_ERROR_QUEUE_PAUSE"), "error", 10000);
+ }
+ }
+
+ $this->campaigns();
+ }
+
+ public function emptyQueue()
+ {
+ acym_checkToken();
+
+ $queueClass = acym_get('class.queue');
+ $deleted = $queueClass->emptyQueue();
+ acym_enqueueNotification(acym_translation_sprintf('ACYM_EMAILS_REMOVED_QUEUE', $deleted));
+
+ $this->campaigns();
+ }
+}
+
diff --git a/deployed/acym/administrator/components/com_acym/controllers/stats.php b/deployed/acym/administrator/components/com_acym/controllers/stats.php
new file mode 100644
index 00000000..9673fef3
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/controllers/stats.php
@@ -0,0 +1,379 @@
+breadcrumb[acym_translation('ACYM_STATISTICS')] = acym_completeLink('stats');
+ $this->loadScripts = [
+ 'all' => ['datepicker'],
+ ];
+ }
+
+ public function saveSendingStatUser($userId, $mailId, $sendDate = null)
+ {
+ $userStatClass = acym_get('class.userstat');
+
+ if ($sendDate == null) {
+ $sendDate = acym_date();
+ }
+
+ $userStat = new stdClass();
+ $userStat->mail_id = $mailId;
+ $userStat->user_id = $userId;
+ $userStat->send_date = $sendDate;
+
+ $userStatClass->save($userStat);
+ }
+
+ public function listing()
+ {
+ acym_setVar("layout", "listing");
+
+ $selectedMail = acym_getVar('int', 'mail_id');
+ $data = [];
+ $campaignClass = acym_get('class.campaign');
+ $mailStatsClass = acym_get('class.mailstat');
+ $userStatClass = acym_get('class.userstat');
+ $urlClickClass = acym_get('class.urlclick');
+ $mailClass = acym_get('class.mail');
+ $mails = $mailStatsClass->getAllMailsForStats();
+ $tab = acym_get('helper.tab');
+
+ $data['tab'] = $tab;
+
+ $ordering = acym_getVar('string', 'detailed_stats_ordering', 'send_date');
+ $orderingSortOrder = acym_getVar('string', 'detailed_stats_ordering_sort_order', 'desc');
+ $search = acym_getVar('string', 'detailed_stats_search', '');
+
+ $detailedStatsPerPage = acym_getCMSConfig('list_limit', 20);
+ $page = acym_getVar('int', 'detailed_stats_pagination_page', 1);
+
+ $matchingDetailedStats = $userStatClass->getDetailedStats(
+ [
+ 'ordering' => $ordering,
+ 'search' => $search,
+ 'detailedStatsPerPage' => $detailedStatsPerPage,
+ 'offset' => ($page - 1) * $detailedStatsPerPage,
+ 'ordering_sort_order' => $orderingSortOrder,
+ 'mail_id' => $selectedMail,
+ ]
+ );
+
+ $pagination = acym_get('helper.pagination');
+ $pagination->setStatus($matchingDetailedStats['total'], $page, $detailedStatsPerPage);
+
+ $data['pagination'] = $pagination;
+ $data['detailed_stats'] = $matchingDetailedStats['detailed_stats'];
+ $data['search'] = $search;
+ $data['ordering'] = $ordering;
+ $data['orderingSortOrder'] = $orderingSortOrder;
+ $data['selectedCampaingDetailedStats'] = $selectedMail;
+
+ if (empty($mails)) {
+ $data['emptyGlobal'] = empty($selectedMail) ? 'campaigns' : 'stats';
+ }
+
+ if (empty($matchingDetailedStats['detailed_stats'])) {
+ $data['emptyDetailed'] = empty($selectedMail) ? 'campaigns' : 'stats';
+ }
+
+ $data['mails'] = [];
+
+ foreach ($mails as $mail) {
+ if ((empty($mail->name) || empty($mail->id) && $mail->sent != 1)) {
+ continue;
+ }
+ $newMail = new stdClass();
+ $newMail->name = $mail->name;
+ $newMail->value = $mail->id;
+ $data['mails'][] = $newMail;
+ }
+ $data['selectedMailid'] = empty($selectedMail) ? '' : $selectedMail;
+
+ if (!empty($selectedMail)) {
+ $data['selectedMailid'] = $selectedMail;
+ $allClickInfo = $urlClickClass->getAllLinkFromEmail($selectedMail);
+ $data['url_click'] = [];
+ $allPercentage = [];
+ foreach ($allClickInfo['urls_click'] as $url) {
+ $percentage = 0;
+ if (empty($url->click)) {
+ $data['url_click'][$url->name] = ['percentage' => $percentage, 'numberClick' => '0'];
+ } else {
+ $percentage = intval(($url->click * 100) / $allClickInfo['allClick']);
+ $data['url_click'][$url->name] = ['percentage' => $percentage, 'numberClick' => $url->click];
+ }
+ $allPercentage[] = $percentage;
+ }
+ $data['mailInformation'] = $mailClass->getOneById($selectedMail);
+ $data['mailInformation']->body = $this->_replaceLink($data['mailInformation']->body);
+ $data['url_click']['allClick'] = $allClickInfo['allClick'];
+ if (!empty($allPercentage)) {
+ $maxPercentage = max($allPercentage);
+
+ foreach ($data['url_click'] as $name => $val) {
+ if ($name === 'allClick') continue;
+ $percentageRecalc = intval(($val['percentage'] * 100) / $maxPercentage);
+ if ($percentageRecalc <= 33) {
+ $data['url_click'][$name]['color'] = '0, 164, 255';
+ } elseif ($percentageRecalc <= 66) {
+ $data['url_click'][$name]['color'] = '248, 31, 255';
+ } else {
+ $data['url_click'][$name]['color'] = '255, 82, 89';
+ }
+ }
+ }
+
+ $data['url_click'] = acym_escape(json_encode($data['url_click']));
+ }
+
+ $statsMailSelected = $mailStatsClass->getOneByMailId($data['selectedMailid']);
+
+ if (empty($statsMailSelected)) {
+ $data['empty'] = empty($data['selectedMailid']) ? 'campaigns' : 'stats';
+ }
+
+ if (empty($statsMailSelected->sent)) {
+ $data['empty'] = 'stats';
+ }
+
+ $statsMailSelected->totalMail = $statsMailSelected->sent + $statsMailSelected->fail;
+ $statsMailSelected->pourcentageSent = empty($statsMailSelected->totalMail) ? 0 : intval(($statsMailSelected->sent * 100) / $statsMailSelected->totalMail);
+ $statsMailSelected->allSent = empty($statsMailSelected->totalMail) ? acym_translation_sprintf('ACYM_X_MAIL_SUCCESSFULLY_SENT_OF_X', 0, 0) : acym_translation_sprintf('ACYM_X_MAIL_SUCCESSFULLY_SENT_OF_X', $statsMailSelected->sent, $statsMailSelected->totalMail);
+
+ $openRateCampaign = empty($data['selectedMailid']) ? $campaignClass->getOpenRateAllCampaign() : $campaignClass->getOpenRateOneCampaign($data['selectedMailid']);
+ $statsMailSelected->pourcentageOpen = empty($openRateCampaign->sent) ? 0 : intval(($openRateCampaign->open_unique * 100) / $openRateCampaign->sent);
+ $statsMailSelected->allOpen = empty($openRateCampaign->sent) ? acym_translation_sprintf('ACYM_X_MAIL_OPENED_OF_X', 0, 0) : acym_translation_sprintf('ACYM_X_MAIL_OPENED_OF_X', $openRateCampaign->open_unique, $openRateCampaign->sent);
+
+ $clickRateCampaign = $urlClickClass->getClickRate($data['selectedMailid']);
+ $statsMailSelected->pourcentageClick = empty($statsMailSelected->sent) ? 0 : intval(($clickRateCampaign->click * 100) / $statsMailSelected->sent);
+ $statsMailSelected->allClick = empty($statsMailSelected->sent) ? acym_translation_sprintf('ACYM_X_MAIL_CLICKED_OF_X', 0, 0) : acym_translation_sprintf('ACYM_X_MAIL_CLICKED_OF_X', $clickRateCampaign->click, $statsMailSelected->sent);
+
+ $bounceRateCampaign = empty($data['selectedMailid']) ? $campaignClass->getBounceRateAllCampaign() : $campaignClass->getBounceRateOneCampaign($data['selectedMailid']);
+ $statsMailSelected->pourcentageBounce = empty($statsMailSelected->sent) ? 0 : intval(($bounceRateCampaign->bounce_unique * 100) / $statsMailSelected->sent);
+ $statsMailSelected->allBounce = empty($statsMailSelected->sent) ? acym_translation_sprintf('ACYM_X_BOUNCE_OF_X', 0, 0) : acym_translation_sprintf('ACYM_X_BOUNCE_OF_X', $bounceRateCampaign->bounce_unique, $statsMailSelected->sent);
+
+ $this->_timeData($statsMailSelected, $data['selectedMailid']);
+
+ if ($statsMailSelected->empty) {
+ $data['stats_mail_1'] = $statsMailSelected;
+
+ parent::display($data);
+
+ return;
+ }
+
+ $allHour = array_keys($statsMailSelected->hour);
+
+ $statsMailSelected->startEndDateHour = [];
+ $statsMailSelected->startEndDateHour['start'] = $allHour[0];
+ $statsMailSelected->startEndDateHour['end'] = end($allHour);
+
+ $data['stats_mail_1'] = $statsMailSelected;
+
+ parent::display($data);
+ }
+
+ private function _replaceLink($body)
+ {
+ $urlClass = acym_get('class.url');
+
+ if ($urlClass === null) {
+ return;
+ }
+
+ $urls = [];
+
+ $config = acym_config();
+
+ preg_match_all('#href[ ]*=[ ]*"(?!mailto:|\#|ymsgr:|callto:|file:|ftp:|webcal:|skype:|tel:)([^"]+)"#Ui', $body, $results);
+
+ if (empty($results)) {
+ return;
+ }
+
+ $countLinks = array_count_values($results[1]);
+ if (array_product($countLinks) != 1) {
+ foreach ($results[1] as $key => $url) {
+ if ($countLinks[$url] == 1) {
+ continue;
+ }
+ $countLinks[$url]--;
+
+ $toAddUrl = (strpos($url, '?') === false ? '?' : '&').'idU='.$countLinks[$url];
+
+ $posHash = strpos($url, '#');
+ if ($posHash !== false) {
+ $newURL = substr($url, 0, $posHash).$toAddUrl.substr($url, $posHash);
+ } else {
+ $newURL = $url.$toAddUrl;
+ }
+
+ $body = preg_replace('#href="('.preg_quote($url, '#').')"#Uis', 'href="'.$newURL.'"', $body, 1);
+ }
+ }
+
+ return $body;
+ }
+
+ public function setDataForChartLine()
+ {
+ $newStart = acym_date(acym_getVar('string', 'start'), 'Y-m-d H:i:s');
+ $newEnd = acym_date(acym_getVar('string', 'end'), 'Y-m-d H:i:s');
+ $mailIdOfCampaign = acym_getVar('int', 'id');
+
+ if ($newStart >= $newEnd) {
+ echo 'error';
+ exit;
+ }
+
+ $statsCampaignSelected = new stdClass();
+
+ $this->_timeData($statsCampaignSelected, $mailIdOfCampaign, $newStart, $newEnd);
+
+ echo acym_line_chart('', $statsCampaignSelected->month, $statsCampaignSelected->day, $statsCampaignSelected->hour);
+ exit;
+ }
+
+
+ private function _timeData(&$statsCampaignSelected, $mailIdOfCampaign, $newStart = '', $newEnd = '')
+ {
+ $urlClickClass = acym_get('class.urlclick');
+ $campaignClass = acym_get('class.campaign');
+ $statsCampaignSelected->empty = false;
+
+
+ $campaignOpenByMonth = $campaignClass->getOpenByMonth($mailIdOfCampaign, $newStart, $newEnd);
+ $campaignOpenByDay = $campaignClass->getOpenByDay($mailIdOfCampaign, $newStart, $newEnd);
+ $campaignOpenByHour = $campaignClass->getOpenByHour($mailIdOfCampaign, $newStart, $newEnd);
+
+ $campaignClickByMonth = $urlClickClass->getAllClickByMailMonth($mailIdOfCampaign, $newStart, $newEnd);
+ $campaignClickByDay = $urlClickClass->getAllClickByMailDay($mailIdOfCampaign, $newStart, $newEnd);
+ $campaignClickByHour = $urlClickClass->getAllClickByMailHour($mailIdOfCampaign, $newStart, $newEnd);
+
+ if (empty($campaignOpenByMonth) || empty($campaignOpenByDay) || empty($campaignOpenByHour)) {
+ $statsCampaignSelected->empty = true;
+
+ return;
+ }
+
+ #To get all the month between the first open date and the last
+ $begin = new DateTime(empty($campaignClickByMonth) ? $campaignOpenByMonth[0]->open_date : min([$campaignOpenByMonth[0]->open_date, $campaignClickByMonth[0]->date_click]));
+ $end = new DateTime(empty($campaignClickByMonth) ? end($campaignOpenByMonth)->open_date : max([end($campaignOpenByMonth)->open_date, end($campaignClickByMonth)->date_click]));
+
+ $end->modify('+1 day');
+
+ $interval = new DateInterval('P1M');
+ $daterange = new DatePeriod($begin, $interval, $end);
+
+ $rangeMonth = [];
+
+ foreach ($daterange as $date) {
+ $rangeMonth[] = acym_getTime($date->format('Y-m-d H:i:s'));
+ }
+
+ #To get all the day between the first open date and the last
+ $begin = new DateTime(empty($campaignClickByDay) ? $campaignOpenByDay[0]->open_date : min([$campaignOpenByDay[0]->open_date, $campaignClickByDay[0]->date_click]));
+ $end = new DateTime(empty($campaignClickByDay) ? end($campaignOpenByDay)->open_date : max([end($campaignOpenByDay)->open_date, end($campaignClickByDay)->date_click]));
+
+ $end->modify('+1 hour');
+
+ $interval = new DateInterval('P1D');
+ $daterange = new DatePeriod($begin, $interval, $end);
+
+ $rangeDay = [];
+
+ foreach ($daterange as $date) {
+ $rangeDay[] = acym_getTime($date->format('Y-m-d H:i:s'));
+ }
+
+
+ #To get all the hour between the first open date and the last
+ $begin = new DateTime(empty($campaignClickByHour) ? $campaignOpenByHour[0]->open_date : min([$campaignOpenByHour[0]->open_date, $campaignClickByHour[0]->date_click]));
+ $end = new DateTime(empty($campaignClickByHour) ? end($campaignOpenByHour)->open_date : max([end($campaignOpenByHour)->open_date, end($campaignClickByHour)->date_click]));
+
+ $end->modify('+1 min');
+
+ $interval = new DateInterval('PT1H');
+ $daterange = new DatePeriod($begin, $interval, $end);
+
+ $rangeHour = [];
+
+ foreach ($daterange as $date) {
+ $rangeHour[] = acym_getTime($date->format('Y-m-d H:i:s'));
+ }
+
+ $openMonthArray = [];
+ $openDayArray = [];
+ $openHourArray = [];
+
+ foreach ($campaignOpenByMonth as $one) {
+ $openMonthArray[acym_date(acym_getTime($one->open_date), 'M Y')] = $one->open;
+ }
+
+ foreach ($campaignOpenByDay as $one) {
+ $openDayArray[acym_date(acym_getTime($one->open_date), 'd M Y')] = $one->open;
+ }
+
+ foreach ($campaignOpenByHour as $one) {
+ $openHourArray[acym_date(acym_getTime($one->open_date), 'd M Y H')] = $one->open;
+ }
+
+ $clickMonthArray = [];
+ $clickDayArray = [];
+ $clickHourArray = [];
+
+ foreach ($campaignClickByMonth as $one) {
+ $clickMonthArray[acym_date(acym_getTime($one->date_click), 'M Y')] = $one->click;
+ }
+
+ foreach ($campaignClickByDay as $one) {
+ $clickDayArray[acym_date(acym_getTime($one->date_click), 'd M Y')] = $one->click;
+ }
+
+ foreach ($campaignClickByHour as $one) {
+ $clickHourArray[acym_date(acym_getTime($one->date_click), 'd M Y H')] = $one->click;
+ }
+
+ $statsCampaignSelected->month = [];
+ foreach ($rangeMonth as $one) {
+ $one = acym_date($one, 'M Y');
+ $currentMonth = [];
+ $currentMonth['open'] = empty($openMonthArray[$one]) ? 0 : $openMonthArray[$one];
+ $currentMonth['click'] = empty($clickMonthArray[$one]) ? 0 : $clickMonthArray[$one];
+ $statsCampaignSelected->month[$one] = $currentMonth;
+ }
+
+ $statsCampaignSelected->day = [];
+ foreach ($rangeDay as $one) {
+ $one = acym_date($one, 'd M Y');
+ $currentDay = [];
+ $currentDay['open'] = empty($openDayArray[$one]) ? 0 : $openDayArray[$one];
+ $currentDay['click'] = empty($clickDayArray[$one]) ? 0 : $clickDayArray[$one];
+ $statsCampaignSelected->day[$one] = $currentDay;
+ }
+
+ $statsCampaignSelected->hour = [];
+ foreach ($rangeHour as $one) {
+ $one = acym_date($one, 'd M Y H');
+ $currentHour = [];
+ $currentHour['open'] = empty($openHourArray[$one]) ? 0 : $openHourArray[$one];
+ $currentHour['click'] = empty($clickHourArray[$one]) ? 0 : $clickHourArray[$one];
+ $statsCampaignSelected->hour[$one.':00'] = $currentHour;
+ }
+ }
+}
+
diff --git a/deployed/acym/administrator/components/com_acym/controllers/toggle.php b/deployed/acym/administrator/components/com_acym/controllers/toggle.php
new file mode 100644
index 00000000..3ecc1a77
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/controllers/toggle.php
@@ -0,0 +1,175 @@
+defaulttask = 'toggle';
+
+ $this->toggleableColumns['automation'] = ['active' => 'id'];
+ $this->toggleableColumns['campaign'] = ['active' => 'id'];
+ $this->toggleableColumns['field'] = ['active' => 'id', 'required' => 'id', 'backend_profile' => 'id', 'backend_listing' => 'id', 'frontend_profile' => 'id', 'frontend_listing' => 'id'];
+ $this->toggleableColumns['list'] = ['active' => 'id', 'visible' => 'id'];
+ $this->toggleableColumns['rule'] = ['active' => 'id'];
+ $this->toggleableColumns['user'] = ['active' => 'id', 'confirmed' => 'id'];
+
+ $this->icons['automation']['active'][1] = 'fa fa-check-circle-o acym__color__green';
+ $this->icons['automation']['active'][0] = 'fa fa-times-circle-o acym__color__red';
+ $this->icons['campaign']['active'][0] = 'fa fa-play-circle-o';
+ $this->icons['campaign']['active'][1] = 'fa fa-pause-circle-o';
+ $this->icons['field']['active'][1] = 'fa fa-check-circle-o acym__color__green';
+ $this->icons['field']['active'][0] = 'fa fa-times-circle-o acym__color__red';
+ $this->icons['field']['required'][1] = 'fa fa-check-circle-o acym__color__green';
+ $this->icons['field']['required'][0] = 'fa fa-times-circle-o acym__color__red';
+ $this->icons['field']['backend_profile'][1] = 'fa fa-check-circle-o acym__color__green';
+ $this->icons['field']['backend_profile'][0] = 'fa fa-times-circle-o acym__color__red';
+ $this->icons['field']['backend_listing'][1] = 'fa fa-check-circle-o acym__color__green';
+ $this->icons['field']['backend_listing'][0] = 'fa fa-times-circle-o acym__color__red';
+ $this->icons['field']['frontend_profile'][1] = 'fa fa-check-circle-o acym__color__green';
+ $this->icons['field']['frontend_profile'][0] = 'fa fa-times-circle-o acym__color__red';
+ $this->icons['field']['frontend_listing'][1] = 'fa fa-check-circle-o acym__color__green';
+ $this->icons['field']['frontend_listing'][0] = 'fa fa-times-circle-o acym__color__red';
+ $this->icons['list']['active'][1] = 'fa fa-check-circle-o acym__color__green';
+ $this->icons['list']['active'][0] = 'fa fa-times-circle-o acym__color__red';
+ $this->icons['list']['visible'][1] = 'fa fa-eye';
+ $this->icons['list']['visible'][0] = 'fa fa-eye-slash acym__color__dark-gray';
+ $this->icons['rule']['active'][0] = 'fa fa-times-circle acym__color__red';
+ $this->icons['rule']['active'][1] = 'fa fa-check-circle acym__color__green';
+ $this->icons['user']['active'][1] = 'fa fa-check-circle-o acym__color__green';
+ $this->icons['user']['active'][0] = 'fa fa-times-circle-o acym__color__red';
+ $this->icons['user']['confirmed'][1] = 'fa fa-check-circle-o acym__color__green';
+ $this->icons['user']['confirmed'][0] = 'fa fa-times-circle-o acym__color__red';
+
+ $this->deletableRows[] = 'list';
+ $this->deletableRows[] = 'mail';
+ $this->deletableRows[] = 'queue';
+
+ acym_noCache();
+ }
+
+ public function toggle()
+ {
+ acym_checkToken();
+
+
+ $table = acym_getVar('word', 'table', '');
+ $field = acym_getVar('cmd', 'field', '');
+ $id = acym_getVar('int', 'id', 0);
+ $newValue = acym_getVar('int', 'value', 0);
+ if (!empty($newValue)) {
+ $newValue = 1;
+ }
+
+
+ if (empty($table) || empty($field) || empty($id) || empty($this->toggleableColumns[$table][$field])) {
+ exit;
+ }
+ $pkey = $this->toggleableColumns[$table][$field];
+
+ $function = $table.$field;
+ if (method_exists($this, $function)) {
+ $this->$function($id, $newValue);
+ } else {
+ acym_query('UPDATE '.acym_secureDBColumn(ACYM_DBPREFIX.$table).' SET `'.acym_secureDBColumn($field).'` = '.intval($newValue).' WHERE `'.acym_secureDBColumn($pkey).'` = '.intval($id).' LIMIT 1');
+ }
+
+ acym_trigger('onAcymToggle'.ucfirst($table).ucfirst($field), [&$id, &$newValue]);
+
+
+ if (empty($this->icons[$table][$field][$newValue])) {
+ echo 'test';
+ exit;
+ }
+
+ $result = [];
+ $result['value'] = 1 - $newValue;
+ $result['classes'] = 'acym_toggleable '.$this->icons[$table][$field][$newValue];
+
+ echo json_encode($result);
+
+ exit;
+ }
+
+ public function delete()
+ {
+ acym_checkToken();
+
+ $table = acym_getVar('word', 'table', '');
+ $id = acym_getVar('cmd', 'id', 0);
+ $method = acym_getVar('word', 'method', 'delete');
+
+ if (empty($table) || !in_array($table, $this->deletableRows) || empty($id)) {
+ exit;
+ }
+
+ $elementClass = acym_get('class.'.$table);
+ $elementClass->$method($id);
+
+ exit;
+ }
+
+ public function getIntroJSConfig()
+ {
+ $config = acym_config();
+ echo $config->get('introjs', '[]');
+ exit;
+ }
+
+ public function toggleIntroJS()
+ {
+ $config = acym_config();
+ $toggleElement = acym_getVar('string', 'where');
+ $intro = json_decode($config->get('introjs', '[]'), true);
+ $intro[$toggleElement] = 1;
+ $newConfig = new stdClass();
+ $newConfig->introjs = json_encode($intro);
+ $config->save($newConfig);
+ exit;
+ }
+
+ public function setDoNotRemindMe()
+ {
+ $newValue = acym_getVar('string', 'value');
+
+ $return = [];
+ $return['error'] = '';
+
+ if (empty($newValue)) {
+ $return['error'] = acym_translation('ACYM_ERROR_SAVING');
+ echo json_encode($return);
+ exit;
+ }
+ $config = acym_config();
+ $newConfig = new stdClass();
+
+ $newConfig->remindme = json_decode($config->get('remindme', '[]'));
+ if (!in_array($newValue, $newConfig->remindme)) array_push($newConfig->remindme, $newValue);
+ $newConfig->remindme = json_encode($newConfig->remindme);
+
+ if ($config->save($newConfig)) {
+ $return['message'] = acym_translation('ACYM_THANKS');
+ } else {
+ $return['error'] = acym_translation('ACYM_ERROR_SAVING');
+ }
+
+ echo json_encode($return);
+ exit;
+ }
+}
+
diff --git a/deployed/acym/administrator/components/com_acym/controllers/update.php b/deployed/acym/administrator/components/com_acym/controllers/update.php
new file mode 100644
index 00000000..1e9cd854
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/controllers/update.php
@@ -0,0 +1,26 @@
+checkVersionArea();
+
+ echo json_encode(['content' => $myAcyArea, 'lastcheck' => acym_date($lastlicensecheck, 'Y/m/d H:i')]);
+ exit;
+ }
+}
+
diff --git a/deployed/acym/administrator/components/com_acym/controllers/users.php b/deployed/acym/administrator/components/com_acym/controllers/users.php
new file mode 100644
index 00000000..9fe0d451
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/controllers/users.php
@@ -0,0 +1,730 @@
+breadcrumb[acym_translation('ACYM_USERS')] = acym_completeLink('users');
+ $this->loadScripts = [
+ 'edit' => ['datepicker'],
+ ];
+ }
+
+ public function listing()
+ {
+ acym_setVar("layout", "listing");
+
+ $searchFilter = acym_getVar('string', 'users_search', '');
+ $status = acym_getVar('string', 'users_status', '');
+ $ordering = acym_getVar('string', 'users_ordering', 'id');
+ $orderingSortOrder = acym_getVar('string', 'users_ordering_sort_order', 'desc');
+
+ $usersPerPage = acym_getCMSConfig('list_limit', 20);
+ $page = acym_getVar('int', 'users_pagination_page', 1);
+
+ $userClass = acym_get('class.user');
+ $matchingUsers = $userClass->getMatchingUsers(
+ [
+ 'search' => $searchFilter,
+ 'usersPerPage' => $usersPerPage,
+ 'offset' => ($page - 1) * $usersPerPage,
+ 'status' => $status,
+ 'ordering' => $ordering,
+ 'ordering_sort_order' => $orderingSortOrder,
+ ]
+ );
+
+ $pagination = acym_get('helper.pagination');
+ $pagination->setStatus($matchingUsers['total'], $page, $usersPerPage);
+
+ if (!empty($matchingUsers['users'])) {
+ $fieldClass = acym_get('class.field');
+ $fieldsToDisplay = $fieldClass->getAllFieldsBackendListing();
+ if (!empty($fieldsToDisplay['ids'])) {
+ $userIds = [];
+ foreach ($matchingUsers['users'] as $user) {
+ $userIds[] = $user->id;
+ }
+ $fieldValue = $fieldClass->getAllfieldBackEndListingByUserIds($userIds, $fieldsToDisplay['ids']);
+ foreach ($matchingUsers['users'] as $user) {
+ $user->fields = [];
+ foreach ($fieldsToDisplay['ids'] as $fieldId) {
+ $user->fields[$fieldId] = empty($fieldValue[$fieldId.$user->id]) ? '' : $fieldValue[$fieldId.$user->id];
+ }
+ }
+ }
+ }
+
+ $usersData = [
+ 'require_confirmation' => acym_config()->get('require_confirmation', '0'),
+ 'allUsers' => $matchingUsers['users'],
+ 'pagination' => $pagination,
+ 'search' => $searchFilter,
+ 'userNumberPerStatus' => $matchingUsers['status'],
+ 'status' => $status,
+ 'usersSubscriptions' => $this->getUsersSubscriptionsByIds($matchingUsers['users']),
+ 'orderingSortOrder' => $orderingSortOrder,
+ 'ordering' => $ordering,
+ 'fields' => empty($fieldsToDisplay['names']) ? '' : $fieldsToDisplay['names'],
+ ];
+
+ parent::display($usersData);
+ }
+
+ public function edit()
+ {
+ acym_setVar("layout", "edit");
+ $userId = acym_getVar("int", "id", 0);
+ $userClass = acym_get('class.user');
+ $userStatClass = acym_get('class.userstat');
+ $fieldClass = acym_get('class.field');
+ $historyClass = acym_get('class.history');
+
+ $userData = [];
+ $allFields = $fieldClass->getMatchingFields();
+ $userData['allFields'] = [];
+ $userData['pourcentageOpen'] = 0;
+ $userData['pourcentageClick'] = 0;
+
+ if (!empty($userId)) {
+ $fieldsValues = $fieldClass->getFieldsValueByUserId($userId);
+ $userData['fieldsValues'] = [];
+ foreach ($fieldsValues as $one) {
+ $userData['fieldsValues'][$one->field_id] = $one->value;
+ }
+ $userData['user-information'] = $userClass->getOneById($userId);
+
+ if (empty($userData['user-information'])) {
+ acym_enqueueNotification(acym_translation('ACYM_USER_NOT_FOUND'), 'error', 0);
+ $this->listing();
+
+ return;
+ }
+
+ $userData['allSubscriptions'] = $userClass->getUserSubscriptionById($userId);
+
+ $userData['subscriptions'] = [];
+ $userData['unsubscribe'] = [];
+
+ foreach ($userData['allSubscriptions'] as $sub) {
+ if ($sub->status == 1) {
+ $userData['subscriptions'][] = $sub;
+ } else {
+ $userData['unsubscribe'][] = $sub;
+ }
+ }
+
+ $userData['subscriptionsIds'] = [];
+
+ if (!empty($userData['subscriptions'])) {
+ $userData['subscriptionsIds'] = [];
+ foreach ($userData['subscriptions'] as $list) {
+ $userData['subscriptionsIds'][] = $list->id;
+ }
+ }
+
+ $userStatFromDB = $userStatClass->getAllUserStatByUserId($userId);
+
+ if (!empty($userStatFromDB)) {
+ $userStat = new stdClass();
+ $userStat->totalSent = 0;
+ $userStat->open = 0;
+
+ foreach ($userStatFromDB as $oneStat) {
+ if ($oneStat->sent > 0) {
+ $userStat->totalSent++;
+ }
+ if ($oneStat->open > 0) {
+ $userStat->open++;
+ }
+ }
+
+ $userStat->pourcentageOpen = empty($userStat->open) ? 0 : intval(($userStat->open * 100) / $userStat->totalSent);
+
+ $userData['pourcentageOpen'] = $userStat->pourcentageOpen;
+ $userData['pourcentageClick'] = $userStat->pourcentageOpen;
+ }
+
+ $this->breadcrumb[acym_escape($userData['user-information']->email)] = acym_completeLink('users&task=edit&id='.$userId);
+
+ $userHistory = $historyClass->getHistoryOfOneById($userId);
+ $this->prepareHistoryContent($userHistory);
+ $userData['userHistory'] = $userHistory;
+ } else {
+ $userData['user-information'] = new stdClass();
+ $userData['user-information']->name = '';
+ $userData['user-information']->email = '';
+ $userData['user-information']->active = '1';
+ $userData['user-information']->confirmed = '1';
+ $userData['user-information']->cms_id = null;
+ $userData['subscriptions'] = [];
+ $userData['subscriptionsIds'] = [];
+ $userData['subscriptions'] = [];
+ $userData['unsubscribe'] = [];
+
+ $this->breadcrumb[acym_escape(acym_translation('ACYM_NEW_USER'))] = acym_completeLink('users&task=edit');
+ }
+
+ foreach ($allFields as $one) {
+ $one->option = json_decode($one->option);
+ $one->value = empty($one->value) ? '' : json_decode($one->value);
+ $fieldDB = empty($one->option->fieldDB) ? '' : json_decode($one->option->fieldDB);
+ $displayIf = empty($one->option->display) ? '' : 'data-display-optional=\''.$one->option->display.'\'';
+
+ $valuesArray = [];
+ if (!empty($one->value)) {
+ foreach ($one->value as $value) {
+ $valueTmp = new stdClass();
+ $valueTmp->text = $value->title;
+ $valueTmp->value = $value->value;
+ if ($value->disabled == 'y') $valueTmp->disable = true;
+ $valuesArray[$value->value] = $valueTmp;
+ }
+ }
+ if (!empty($fieldDB) && !empty($fieldDB->value)) {
+ $fromDB = $fieldClass->getValueFromDB($fieldDB);
+ foreach ($fromDB as $value) {
+ $valuesArray[$value->value] = $value->title;
+ }
+ }
+
+ $one->display = empty($one->option->display) ? '' : json_decode($one->option->display);
+ $userData['allFields'][$one->id] = $one;
+ if ($one->id == 1) {
+ $defaultValue = acym_escape(empty($userData['user-information']->id) ? '' : $userData['user-information']->name);
+ } elseif ($one->id == 2) {
+ $defaultValue = acym_escape(empty($userData['user-information']->id) ? '' : $userData['user-information']->email);
+ } elseif (!empty($userData['fieldsValues'][$one->id])) {
+ $defaultValue = is_null(json_decode($userData['fieldsValues'][$one->id])) ? $userData['fieldsValues'][$one->id] : json_decode($userData['fieldsValues'][$one->id]);
+ } else {
+ $defaultValue = $one->default_value;
+ }
+ $size = empty($one->option->size) ? '' : 'width:'.$one->option->size.'px';
+
+ $userData['allFields'][$one->id]->html = $fieldClass->displayField($one, $defaultValue, $size, $valuesArray, true, false, null, $one->backend_profile);
+ }
+
+ $tabHelper = acym_get('helper.tab');
+
+ $userData['tab'] = $tabHelper;
+
+ parent::display($userData);
+ }
+
+ public function import()
+ {
+ acym_setVar("layout", "import");
+
+ $tab = acym_get('helper.tab');
+ $userClass = acym_get('class.user');
+
+ $nbUsersAcymailing = $userClass->getCountTotalUsers();
+ $nbUsersCMS = acym_loadResult('SELECT count('.$this->cmsUserVars->id.') FROM '.$this->cmsUserVars->table);
+
+ $tables = acym_getTables();
+ $arrayTables = [];
+ foreach ($tables as $key => $tableName) {
+ $arrayTables[$tableName] = $tableName;
+ }
+
+ $data = [
+ 'tab' => $tab,
+ 'nbUsersAcymailing' => $nbUsersAcymailing,
+ 'nbUsersCMS' => $nbUsersCMS,
+ 'tables' => $arrayTables,
+ ];
+
+ $this->breadcrumb[acym_translation('ACYM_IMPORT')] = acym_completeLink('users&task=import');
+
+
+ parent::display($data);
+ }
+
+ public function ajaxEncoding()
+ {
+ acym_setVar('layout', 'ajaxencoding');
+ parent::display();
+ exit;
+ }
+
+ public function doImport()
+ {
+ acym_checkToken();
+
+ $function = acym_getVar('cmd', 'import_from');
+ $importHelper = acym_get('helper.import');
+
+ if (empty($function) || !$importHelper->$function()) {
+ return $this->import();
+ }
+
+ if ($function == 'textarea' || $function == 'file') {
+ if (file_exists(ACYM_MEDIA.'import'.DS.acym_getVar('cmd', 'filename'))) {
+ $importContent = file_get_contents(ACYM_MEDIA.'import'.DS.acym_getVar('cmd', 'filename'));
+ }
+ if (empty($importContent)) {
+ acym_enqueueNotification(acym_translation('ACYM_EMPTY_TEXTAREA'), 'error', 5000);
+ $this->import();
+ } else {
+ acym_setVar('layout', 'genericimport');
+ $this->breadcrumb[acym_translation('ACYM_IMPORT')] = acym_completeLink('users&task=import');
+
+ return parent::display();
+ }
+ } else {
+ $this->listing();
+ }
+ }
+
+ public function finalizeImport()
+ {
+ $importHelper = acym_get('helper.import');
+ $importHelper->finalizeImport();
+
+ $this->listing();
+ }
+
+ function downloadImport()
+ {
+ $filename = acym_getVar('cmd', 'filename');
+ if (!file_exists(ACYM_MEDIA.'import'.DS.$filename.'.csv')) {
+ return;
+ }
+ acym_noTemplate();
+ $exportHelper = acym_get('helper.export');
+ $exportHelper->setDownloadHeaders($filename);
+ echo file_get_contents(ACYM_MEDIA.'import'.DS.$filename.'.csv');
+ exit;
+ }
+
+ public function getAll()
+ {
+ $userClass = acym_get('class.user');
+
+ return $userClass->getAll();
+ }
+
+ public function getUsersSubscriptionsByIds($usersData)
+ {
+ $userClass = acym_get('class.user');
+ $usersId = [];
+ foreach ($usersData as $oneUser) {
+ $usersId[] = $oneUser->id;
+ }
+
+ $subscriptions = [];
+
+ if (!empty($usersId)) {
+ $subscriptionsArray = $userClass->getUsersSubscriptionsByIds($usersId);
+
+ foreach ($subscriptionsArray as $oneSubscription) {
+ $subscriptions[$oneSubscription->user_id][$oneSubscription->id] = $oneSubscription;
+ }
+ }
+
+ return $subscriptions;
+ }
+
+ public function export()
+ {
+ acym_setVar("layout", "export");
+ $this->breadcrumb[acym_translation('ACYM_EXPORT_USERS')] = acym_completeLink('users&task=export');
+
+ $listClass = acym_get('class.list');
+ $lists = $listClass->getAll();
+
+ $checkedUsers = acym_getVar('array', 'elements_checked', []);
+
+ $fields = acym_getColumns('user');
+
+ $fieldClass = acym_get('class.field');
+ $customFields = $fieldClass->getAllfields();
+
+ $data = [
+ 'lists' => $lists,
+ 'checkedUsers' => $checkedUsers,
+ 'fields' => $fields,
+ 'customfields' => $customFields,
+ 'config' => acym_config(),
+ ];
+
+ parent::display($data);
+ }
+
+ public function doexport()
+ {
+ acym_checkToken();
+ acym_increasePerf();
+
+ $usersToExport = acym_getVar('string', 'export_users-to-export', 'all');
+ $listsToExport = json_decode(acym_getVar('string', 'lists_selected'));
+ if ($usersToExport == "list" && empty($listsToExport)) {
+ acym_enqueueNotification(acym_translation('ACYM_EXPORT_SELECT_LIST'), 'error', 5000);
+
+ return $this->exportError(acym_translation('ACYM_EXPORT_SELECT_LIST'));
+ }
+ acym_arrayToInteger($listsToExport);
+
+ $exportUsersType = 'all';
+ if ($usersToExport == 'list') {
+ $exportUsersType = acym_getVar('string', 'export_list', 'all');
+ }
+
+ $selectedUsers = acym_getVar('string', 'selected_users', null);
+
+ if (!empty($selectedUsers)) {
+ $selectedUsersArray = explode(',', $selectedUsers);
+ acym_arrayToInteger($selectedUsersArray);
+ }
+
+ $fieldsToExport = acym_getVar('array', 'export_fields', []);
+ if (empty($fieldsToExport)) {
+ if (!empty($selectedUsersArray)) {
+ acym_setVar('elements_checked', $selectedUsersArray);
+ } else {
+ acym_setVar('elements_checked', []);
+ }
+
+ return $this->exportError(acym_translation('ACYM_EXPORT_SELECT_FIELD'));
+ }
+
+ $tableFields = acym_getColumns('user');
+ $fieldClass = acym_get('class.field');
+ $customFields = $fieldClass->getAllfields();
+
+ $customFieldsToExport = [];
+
+ foreach ($fieldsToExport as $i => $oneField) {
+ if (empty($customFields[$oneField])) continue;
+ $customFieldsToExport[$oneField] = acym_translation($customFields[$oneField]->name, true);
+ unset($fieldsToExport[$i]);
+ }
+
+ $notAllowedFields = array_diff($fieldsToExport, $tableFields);
+ if (in_array('id', $fieldsToExport)) $notAllowedFields[] = 'id';
+ if (!empty($notAllowedFields)) {
+ return $this->exportError(acym_translation_sprintf('ACYM_NOT_ALLOWED_FIELDS', implode(', ', $notAllowedFields), implode(', ', $tableFields)));
+ }
+
+ $charset = acym_getVar('string', 'export_charset', 'UTF-8');
+ $excelsecurity = acym_getVar('string', 'export_excelsecurity', 0);
+ $separator = acym_getVar('string', 'export_separator', ',');
+ if (!in_array($separator, [',', ';'])) {
+ $separator = ',';
+ }
+
+
+ $config = acym_config();
+ $newConfig = new stdClass();
+ $newConfig->export_separator = $separator;
+ $newConfig->export_charset = $charset;
+ $newConfig->export_excelsecurity = $excelsecurity;
+ $newConfig->export_fields = implode(',', array_merge($fieldsToExport, array_keys($customFieldsToExport)));
+ if (empty($selectedUsers)) {
+ $newConfig->export_lists = implode(',', $listsToExport);
+ }
+ $config->save($newConfig);
+
+ foreach ($fieldsToExport as $oneField) {
+ acym_secureDBColumn($oneField);
+ }
+ $query = 'SELECT DISTINCT user.`id`, user.`'.implode('`, user.`', $fieldsToExport).'` FROM #__acym_user AS user';
+
+ $where = [];
+
+ if (!empty($selectedUsersArray)) {
+ acym_arrayToInteger($selectedUsersArray);
+ $where[] = 'user.id IN ('.implode(',', $selectedUsersArray).')';
+ } elseif ($usersToExport == "list" && !empty($listsToExport)) {
+ $query .= ' JOIN #__acym_user_has_list AS userlist ON userlist.user_id = user.id';
+ acym_arrayToInteger($listsToExport);
+ $where[] = 'userlist.list_id IN ('.implode(',', $listsToExport).')';
+
+ if ($exportUsersType == 'sub') $where[] = 'userlist.status = 1';
+ if ($exportUsersType == 'unsub') $where[] = 'userlist.status = 0';
+ }
+
+ if (!empty($where)) $query .= ' WHERE ('.implode(') AND (', $where).')';
+
+ $exportHelper = acym_get('helper.export');
+ $exportHelper->exportCSV($query, $fieldsToExport, $customFieldsToExport, $separator, $charset);
+
+ exit;
+ }
+
+ private function exportError($message)
+ {
+ acym_enqueueMessage($message, 'error', 0);
+ acym_setNoTemplate(false);
+
+ return acym_redirect(acym_completeLink('users&task=export', false, true));
+ }
+
+ public function unsubscribe()
+ {
+ $userId = acym_getVar('int', 'id');
+
+ if (empty($userId)) {
+ $this->listing();
+
+ return;
+ }
+
+ $lists = json_decode(acym_getVar('string', 'lists_selected'));
+ if (!is_array($lists)) {
+ $lists = (array)$lists;
+ }
+
+ $userClass = acym_get('class.user');
+ $userClass->unsubscribe($userId, $lists);
+
+ $this->edit();
+ }
+
+ public function subscribe($listing = false)
+ {
+ $userClass = acym_get('class.user');
+ $userId = acym_getVar('int', 'id');
+ $lists = json_decode(acym_getVar('string', 'lists_selected'));
+
+ if (empty($userId)) {
+ $userId = $userClass->save();
+ }
+
+ if (!is_array($lists)) {
+ $lists = (array)$lists;
+ }
+
+ $userClass->subscribe($userId, $lists);
+
+ if (!$listing) {
+ $this->edit();
+ } else {
+ $this->listing();
+ }
+ }
+
+ public function save()
+ {
+ $this->apply(true);
+ }
+
+ public function apply($listing = false)
+ {
+ $userClass = acym_get('class.user');
+
+ $userInformation = acym_getVar('array', 'user');
+ $userId = acym_getVar('int', 'id');
+ $listsToAdd = json_decode(acym_getVar('string', 'lists_selected'));
+ $user = new stdClass();
+ $user->name = $userInformation['name'];
+ $user->email = $userInformation['email'];
+ $user->active = $userInformation['active'];
+ $user->confirmed = $userInformation['confirmed'];
+ $customFields = acym_getVar('array', 'customField');
+
+ preg_match('/'.acym_getEmailRegex().'/i', $user->email, $matches);
+
+ if (empty($matches)) {
+ $this->edit();
+ acym_enqueueNotification(acym_translation_sprintf('ACYM_VALID_EMAIL', $user->email), 'error', 0);
+
+ return;
+ }
+
+ if (empty($userId)) {
+ $existingUser = $userClass->getOneByEmail($user->email);
+ if (!empty($existingUser)) {
+ acym_enqueueNotification(acym_translation_sprintf('ACYM_X_ALREADY_EXIST', $user->email), 'error', 0);
+
+ $this->edit();
+
+ return;
+ }
+
+ $user->creation_date = acym_date('now', 'Y-m-d H:i:s', false);
+ $userId = $userClass->save($user, $customFields);
+ acym_setVar('id', $userId);
+ } else {
+ $user->id = $userId;
+ $userClass->save($user, $customFields);
+ }
+
+ if (!empty($listsToAdd)) {
+ $this->subscribe($listing);
+
+ return;
+ }
+
+
+ if ($listing) {
+ $this->listing();
+ } else {
+ $this->edit();
+ }
+ }
+
+ public function deleteOne()
+ {
+ $userClass = acym_get('class.user');
+
+ $userId = acym_getVar('int', 'id');
+
+ $userClass->delete($userId);
+
+ $this->listing();
+ }
+
+ public function getColumnsFromTable()
+ {
+ $tableName = acym_secureDBColumn(acym_getVar('string', 'tablename', ''));
+ if (empty($tableName)) {
+ exit;
+ }
+ $columns = acym_getColumns($tableName, false, false);
+ $allColumnsSelect = ' ';
+ foreach ($columns as $oneColumn) {
+ $allColumnsSelect .= ''.$oneColumn.' ';
+ }
+
+ echo $allColumnsSelect;
+ exit;
+ }
+
+ public function addToList()
+ {
+ $listsSelected = json_decode(acym_getVar('string', 'lists_selected', ''));
+ $userSelected = acym_getVar('array', 'elements_checked');
+ $userClass = acym_get('class.user');
+ foreach ($userSelected as $user) {
+ $userClass->subscribe($user, $listsSelected);
+ }
+ $this->listing();
+ }
+
+ public function setAjaxListing()
+ {
+ $userClass = acym_get('class.user');
+
+ $showSelected = acym_getVar('string', 'showSelected');
+ $matchingUsersData = new stdClass();
+ $matchingUsersData->ordering = 'name';
+ $matchingUsersData->searchFilter = acym_getVar('string', 'searchUsers');
+ $matchingUsersData->usersPerPage = acym_getVar('string', 'usersPerPage');
+ $matchingUsersData->idsSelected = json_decode(acym_getVar('string', 'selectedUsers'));
+ $matchingUsersData->idsHidden = json_decode(acym_getVar('string', 'hiddenUsers'));
+ $matchingUsersData->page = acym_getVar('int', 'pagination_page_ajax');
+ if (empty($matchingUsersData->page)) {
+ $matchingUsersData->page = 1;
+ }
+
+ $options = [
+ 'ordering' => $matchingUsersData->ordering,
+ 'search' => $matchingUsersData->searchFilter,
+ 'usersPerPage' => $matchingUsersData->usersPerPage,
+ 'offset' => ($matchingUsersData->page - 1) * $matchingUsersData->usersPerPage,
+ 'hiddenUsers' => $matchingUsersData->idsHidden,
+ ];
+
+ if ($showSelected == 'true') {
+ $options['selectedUsers'] = $matchingUsersData->idsSelected;
+ $options['showOnlySelected'] = true;
+ }
+
+ $users = $userClass->getMatchingUsers($options);
+
+ $return = '';
+
+ if (empty($users['users'])) {
+ $return .= ''.acym_translation('ACYM_NO_RESULTS_FOUND').' ';
+ }
+
+ foreach ($users['users'] as $user) {
+ $return .= '';
+ }
+
+ $pagination = acym_get('helper.pagination');
+ $pagination->setStatus($users['total'], $matchingUsersData->page, $matchingUsersData->usersPerPage);
+
+ $return .= $pagination->displayAjax();
+
+ echo $return;
+ exit;
+ }
+
+ private function prepareHistoryContent(&$userHistory)
+ {
+ foreach ($userHistory as &$oneHistory) {
+ if (!empty($oneHistory->data)) {
+ $historyData = explode("\n", $oneHistory->data);
+ $details = '
'.acym_translation('ACYM_DETAILS').' ';
+ if (!empty($oneHistory->mail_id)) {
+ $details .= ''.acym_translation('NEWSLETTER').' : ';
+ $details .= acym_escape($oneHistory->subject).' ( '.acym_translation('ACYM_ID').' : '.$oneHistory->mail_id.' ) ';
+ }
+
+ foreach ($historyData as $value) {
+ if (!strpos($value, '::')) {
+ $details .= $value.' ';
+ continue;
+ }
+ list($part1, $part2) = explode("::", $value);
+ if (preg_match('#^[A-Z_]*$#', $part2)) $part2 = acym_translation($part2);
+ $details .= ''.acym_escape(acym_translation($part1)).' : '.acym_escape($part2).' ';
+ }
+ $details .= '';
+
+ $oneHistory->data = acym_modal(
+ acym_translation('ACYM_VIEW_DETAILS'),
+ $details,
+ null,
+ 'style="word-break: break-word;"',
+ 'class="history_details"',
+ true,
+ false
+ );
+ }
+
+ if (!empty($oneHistory->source)) {
+ $source = explode("\n", $oneHistory->source);
+ $details = '
'.acym_translation('ACYM_SOURCE').' ';
+ foreach ($source as $value) {
+ if (!strpos($value, '::')) continue;
+ list($part1, $part2) = explode("::", $value);
+ $details .= ''.acym_escape($part1).' : '.acym_escape($part2).' ';
+ }
+ $details .= '';
+
+ $oneHistory->source = acym_modal(
+ acym_translation('ACYM_VIEW_SOURCE'),
+ $details,
+ null,
+ 'style="word-break: break-word;"',
+ 'class="history_details"'
+ );
+ }
+ }
+ }
+}
+
diff --git a/deployed/acym/administrator/components/com_acym/dynamics/article/index.html b/deployed/acym/administrator/components/com_acym/dynamics/article/index.html
new file mode 100644
index 00000000..fa6d84e8
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/dynamics/article/index.html
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/deployed/acym/administrator/components/com_acym/dynamics/article/plugin.php b/deployed/acym/administrator/components/com_acym/dynamics/article/plugin.php
new file mode 100644
index 00000000..363d01b2
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/dynamics/article/plugin.php
@@ -0,0 +1,350 @@
+cms = 'Joomla';
+ $this->name = 'article';
+ }
+
+ public function insertOptions()
+ {
+ $plugin = new stdClass();
+ $plugin->name = acym_translation('ACYM_ARTICLE');
+ $plugin->icon = ' ';
+ $plugin->icontype = 'raw';
+ $plugin->plugin = __CLASS__;
+
+ return $plugin;
+ }
+
+ public function contentPopup()
+ {
+ $this->categories = acym_loadObjectList(
+ 'SELECT id, parent_id, title
+ FROM `#__categories`
+ WHERE extension = "com_content"'
+ );
+
+ $tabHelper = acym_get('helper.tab');
+ $tabHelper->startTab(acym_translation('ACYM_ONE_BY_ONE'));
+
+ $displayOptions = [
+ [
+ 'title' => 'ACYM_DISPLAY',
+ 'type' => 'checkbox',
+ 'name' => 'display',
+ 'options' => [
+ 'title' => ['ACYM_TITLE', true],
+ 'content' => ['ACYM_CONTENT', true],
+ 'cat' => ['ACYM_CATEGORY', false],
+ 'readmore' => ['ACYM_READ_MORE', false],
+ ],
+ ],
+ [
+ 'title' => 'ACYM_CLICKABLE_TITLE',
+ 'type' => 'boolean',
+ 'name' => 'clickable',
+ 'default' => true,
+ ],
+ [
+ 'title' => 'ACYM_TRUNCATE',
+ 'type' => 'intextfield',
+ 'name' => 'wrap',
+ 'text' => 'ACYM_TRUNCATE_AFTER',
+ 'default' => 0,
+ ],
+ [
+ 'title' => 'ACYM_DISPLAY_PICTURES',
+ 'type' => 'pictures',
+ 'name' => 'pictures',
+ ],
+ ];
+
+ echo $this->acympluginHelper->displayOptions($displayOptions, $this->name);
+
+ echo $this->getFilteringZone();
+
+ $this->displayListing();
+
+ $tabHelper->endTab();
+ $tabHelper->startTab(acym_translation('ACYM_BY_CATEGORY'));
+
+ $catOptions = [
+ [
+ 'title' => 'ACYM_ORDER_BY',
+ 'type' => 'select',
+ 'name' => 'order',
+ 'options' => [
+ 'id' => 'ACYM_ID',
+ 'publish_up' => 'ACYM_PUBLISHING_DATE',
+ 'modified' => 'ACYM_MODIFICATION_DATE',
+ 'title' => 'ACYM_TITLE',
+ 'rand' => 'ACYM_RANDOM',
+ ],
+ ],
+ [
+ 'title' => 'ACYM_COLUMNS',
+ 'type' => 'number',
+ 'name' => 'cols',
+ 'default' => 1,
+ 'min' => 1,
+ 'max' => 10,
+ ],
+ [
+ 'title' => 'ACYM_MAX_NB_ELEMENTS',
+ 'type' => 'number',
+ 'name' => 'max',
+ 'default' => 20,
+ ],
+ ];
+
+ $displayOptions = array_merge($displayOptions, $catOptions);
+
+ echo $this->acympluginHelper->displayOptions($displayOptions, 'auto'.$this->name, 'grouped');
+
+ echo $this->getCategoryListing();
+
+ $tabHelper->endTab();
+
+ $tabHelper->display('plugin');
+ }
+
+ public function displayListing()
+ {
+ $querySelect = 'SELECT article.id, article.title, article.publish_up ';
+ $query = 'FROM #__content AS article ';
+ $filters = [];
+
+ $this->pageInfo = new stdClass();
+ $this->pageInfo->limit = acym_getCMSConfig('list_limit');
+ $this->pageInfo->page = acym_getVar('int', 'pagination_page_ajax', 1);
+ $this->pageInfo->start = ($this->pageInfo->page - 1) * $this->pageInfo->limit;
+ $this->pageInfo->search = acym_getVar('string', 'plugin_search', '');
+ $this->pageInfo->filter_cat = acym_getVar('int', 'plugin_category', 0);
+ $this->pageInfo->order = 'article.id';
+ $this->pageInfo->orderdir = 'DESC';
+
+ $searchFields = ['article.id', 'article.title'];
+ if (!empty($this->pageInfo->search)) {
+ $searchVal = '%'.acym_getEscaped($this->pageInfo->search, true).'%';
+ $filters[] = implode(' LIKE '.acym_escapeDB($searchVal).' OR ', $searchFields).' LIKE '.acym_escapeDB($searchVal);
+ }
+
+ if (!empty($this->pageInfo->filter_cat)) {
+ $filters[] = "article.catid = ".intval($this->pageInfo->filter_cat);
+ }
+
+ $filters[] = 'article.state = 1';
+
+ $query .= ' WHERE ('.implode(') AND (', $filters).')';
+ if (!empty($this->pageInfo->order)) $query .= ' ORDER BY '.acym_secureDBColumn($this->pageInfo->order).' '.acym_secureDBColumn($this->pageInfo->orderdir);
+
+ $rows = acym_loadObjectList($querySelect.$query, '', $this->pageInfo->start, $this->pageInfo->limit);
+ $this->pageInfo->total = acym_loadResult('SELECT COUNT(*) '.$query);
+
+
+ $listingOptions = [
+ 'header' => [
+ 'title' => [
+ 'label' => 'ACYM_TITLE',
+ 'size' => '7',
+ ],
+ 'publish_up' => [
+ 'label' => 'ACYM_PUBLISHING_DATE',
+ 'size' => '4',
+ 'type' => 'date',
+ ],
+ 'id' => [
+ 'label' => 'ACYM_ID',
+ 'size' => '1',
+ 'class' => 'text-center',
+ ],
+ ],
+ 'id' => 'id',
+ 'rows' => $rows,
+ ];
+
+ echo $this->getElementsListing($listingOptions);
+ }
+
+ public function replaceContent(&$email)
+ {
+ $this->replaceAuto($email);
+ $this->replaceOne($email);
+ }
+
+ private function replaceAuto(&$email)
+ {
+ $this->generateByCategory($email);
+ if (empty($this->tags)) return;
+ $this->acympluginHelper->replaceTags($email, $this->tags, true);
+ }
+
+ private function generateByCategory(&$email)
+ {
+ $tags = $this->acympluginHelper->extractTags($email, 'auto'.$this->name);
+ $return = new stdClass();
+ $return->status = true;
+ $return->message = '';
+ $this->tags = [];
+ $time = time();
+
+ if (empty($tags)) return $return;
+
+ foreach ($tags as $oneTag => $parameter) {
+ if (isset($this->tags[$oneTag])) continue;
+
+ $allcats = explode('-', $parameter->id);
+ $selectedArea = [];
+ foreach ($allcats as $oneCat) {
+ if (empty($oneCat)) continue;
+
+ $selectedArea[] = intval($oneCat);
+ }
+
+ $query = 'SELECT DISTINCT article.`id` FROM #__content AS article ';
+
+ $where = [];
+
+ if (!empty($selectedArea)) {
+ $where[] = 'article.catid IN ('.implode(',', $selectedArea).')';
+ }
+
+ $where[] = 'article.state = 1';
+ $where[] = '`publish_up` < '.acym_escapeDB(date('Y-m-d H:i:s', $time - date('Z')));
+ $where[] = '`publish_down` > '.acym_escapeDB(date('Y-m-d H:i:s', $time - date('Z'))).' OR `publish_down` = 0';
+
+ $query .= ' WHERE ('.implode(') AND (', $where).')';
+
+ if (!empty($parameter->order)) {
+ $ordering = explode(',', $parameter->order);
+ if ($ordering[0] == 'rand') {
+ $query .= ' ORDER BY rand()';
+ } else {
+ $query .= ' ORDER BY article.`'.acym_secureDBColumn(trim($ordering[0])).'` '.acym_secureDBColumn(trim($ordering[1]));
+ }
+ }
+
+ if (empty($parameter->max)) $parameter->max = 20;
+ $query .= ' LIMIT '.intval($parameter->max);
+
+ $allArticles = acym_loadResultArray($query);
+
+ $this->tags[$oneTag] = $this->finalizeCategoryFormat($this->name, $allArticles, $parameter);
+ }
+
+ return $return;
+ }
+
+ private function replaceOne(&$email)
+ {
+ $tags = $this->acympluginHelper->extractTags($email, $this->name);
+ if (empty($tags)) return;
+
+ require_once JPATH_SITE.DS.'components'.DS.'com_content'.DS.'helpers'.DS.'route.php';
+
+ $tagsReplaced = [];
+ foreach ($tags as $i => $oneTag) {
+ if (isset($tagsReplaced[$i])) continue;
+
+ $tagsReplaced[$i] = $this->replaceIndividualContent($oneTag);
+ }
+
+ $this->acympluginHelper->replaceTags($email, $tagsReplaced, true);
+ }
+
+ private function replaceIndividualContent($tag)
+ {
+ $query = 'SELECT article.*
+ FROM #__content AS article
+ WHERE article.state = 1
+ AND article.id = '.intval($tag->id);
+
+ $element = acym_loadObject($query);
+
+ if (empty($element)) {
+ if (acym_isAdmin()) {
+ acym_enqueueMessage('The article "'.$tag->id.'" could not be found', 'notice');
+ }
+
+ return '';
+ }
+
+ if (empty($tag->display)) {
+ $tag->display = [];
+ } else {
+ $tag->display = explode(',', $tag->display);
+ }
+
+ $varFields = [];
+ $varFields['{picthtml}'] = '';
+ foreach ($element as $fieldName => $oneField) {
+ $varFields['{'.$fieldName.'}'] = $oneField;
+ }
+
+ $completeId = $element->id;
+ if (!empty($element->alias)) $completeId .= ':'.$element->alias;
+
+ $link = ContentHelperRoute::getArticleRoute($completeId, $element->catid);
+ $link = acym_frontendLink($link, false);
+ $varFields['{link}'] = $link;
+
+ $title = $element->title;
+
+ $afterTitle = '';
+ $afterArticle = '';
+
+ $imagePath = '';
+ if (!empty($tag->pict) && !empty($element->images)) {
+ $images = json_decode($element->images);
+ $pictVar = empty($images->image_fulltext) ? 'image_intro' : 'image_fulltext';
+ if (!empty($images->$pictVar)) {
+ $imagePath = acym_rootURI().$images->$pictVar;
+ $varFields['{picthtml}'] = ' ';
+ }
+ }
+
+ $contentText = '';
+ if (in_array('content', $tag->display)) $contentText .= $element->introtext.$element->fulltext;
+
+ $customFields = [];
+ if (in_array('cat', $tag->display)) {
+ $category = acym_loadResult('SELECT title FROM #__categories WHERE id = '.intval($element->catid));
+ $customFields[] = [
+ ''.acym_escape($category).' ',
+ acym_translation('ACYM_CATEGORY'),
+ ];
+ }
+
+ $readMoreText = empty($tag->readmore) ? acym_translation('ACYM_READ_MORE') : $tag->readmore;
+ $varFields['{readmore}'] = ''.acym_escape($readMoreText).' ';
+ if (in_array('readmore', $tag->display)) $afterArticle .= $varFields['{readmore}'];
+
+ $format = new stdClass();
+ $format->tag = $tag;
+ $format->title = $title;
+ $format->afterTitle = $afterTitle;
+ $format->afterArticle = $afterArticle;
+ $format->imagePath = $imagePath;
+ $format->description = $contentText;
+ $format->link = empty($tag->clickable) ? '' : $link;
+ $format->cols = empty($tag->nbcols) ? 1 : intval($tag->nbcols);
+ $format->customFields = $customFields;
+ $result = ''.$this->acympluginHelper->getStandardDisplay($format).'
';
+
+ return $this->finalizeElementFormat($this->name, $result, $tag, $varFields);
+ }
+}
diff --git a/deployed/acym/administrator/components/com_acym/dynamics/cbuilder/index.html b/deployed/acym/administrator/components/com_acym/dynamics/cbuilder/index.html
new file mode 100644
index 00000000..fa6d84e8
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/dynamics/cbuilder/index.html
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/deployed/acym/administrator/components/com_acym/dynamics/cbuilder/plugin.php b/deployed/acym/administrator/components/com_acym/dynamics/cbuilder/plugin.php
new file mode 100644
index 00000000..93f34965
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/dynamics/cbuilder/plugin.php
@@ -0,0 +1,287 @@
+cms = 'Joomla';
+ if (!defined('JPATH_ADMINISTRATOR') || !file_exists(rtrim(JPATH_ADMINISTRATOR, DS).DS.'components'.DS.'com_comprofiler'.DS)) {
+ $this->installed = false;
+ }
+ }
+
+ function dynamicText()
+ {
+ $onePlugin = new stdClass();
+ $onePlugin->name = 'Community Builder';
+ $onePlugin->plugin = __CLASS__;
+ $onePlugin->type = 'joomla';
+ $onePlugin->help = 'plugin-cbuilder';
+
+ return $onePlugin;
+ }
+
+ function textPopup()
+ {
+ ?>
+
+
+
+ ';
+
+ $typeinfo = [];
+ $typeinfo[] = acym_selectOption('receiver', 'ACYM_RECEIVER_INFORMATION');
+ $typeinfo[] = acym_selectOption('sender', 'ACYM_SENDER_INFORMATION');
+ $text .= acym_radio($typeinfo, 'typeinfo', 'receiver');
+
+ $fieldType = acym_loadObjectList('SELECT name, type FROM #__comprofiler_fields', 'name');
+
+ $text .= '';
+
+ $fields = acym_getColumns('comprofiler', false);
+ foreach ($fields as $fieldname) {
+ $type = '';
+ if (strpos(strtolower($fieldname), 'date') !== false) {
+ $type = '| type:date';
+ }
+ if (!empty($fieldType[$fieldname]) && $fieldType[$fieldname]->type == 'image') {
+ $type = '| type:image';
+ }
+ $text .= '';
+ }
+
+ $otherFields = acym_loadObjectList("SELECT * FROM #__comprofiler_fields WHERE tablecolumns = '' AND published = 1");
+ foreach ($otherFields as $oneField) {
+ $text .= '';
+ }
+
+ $text .= '';
+
+ echo $text;
+ }
+
+ function replaceUserInformation(&$email, &$user, $send = true)
+ {
+ $extractedTags = $this->acympluginHelper->extractTags($email, 'cbtag');
+ if (empty($extractedTags)) return;
+
+ $uservalues = null;
+ if (!empty($user->cms_id)) {
+ $uservalues = acym_loadObject('SELECT * FROM #__comprofiler WHERE user_id = '.intval($user->cms_id).' LIMIT 1');
+ }
+
+ $fieldObjects = acym_loadObjectList('SELECT fieldid, `table`, name, type, params FROM #__comprofiler_fields', 'name');
+
+ if (!include_once ACYM_ROOT.'administrator'.DS.'components'.DS.'com_comprofiler'.DS.'plugin.foundation.php') return;
+ cbimport('cb.database');
+ $currentCBUser = null;
+
+ $tags = [];
+ foreach ($extractedTags as $i => $oneTag) {
+ if (isset($tags[$i])) continue;
+
+ $field = $oneTag->id;
+ $values = new stdClass();
+
+ if (!empty($oneTag->info) && $oneTag->info == 'sender') {
+ if (empty($this->sendervalues[$email->id]) && !empty($email->creator_id)) {
+ $this->sendervalues[$email->id] = acym_loadObject('SELECT * FROM #__comprofiler WHERE user_id = '.intval($email->creator_id).' LIMIT 1');
+ }
+ if (!empty($this->sendervalues[$email->id])) {
+ $values = $this->sendervalues[$email->id];
+ }
+ } else {
+ $values = $uservalues;
+ }
+
+ if (substr($field, 0, 6) == 'cbapi_') {
+ if (!empty($oneTag->info) && $oneTag->info == 'sender') {
+ if (empty($this->sendervalues[$email->id]->$field) && !empty($email->creator_id)) {
+ $currentSender = CBuser::getInstance($email->creator_id);
+ $values->$field = $currentSender->getField(substr($field, 6), $oneTag->default, 'html', 'none', 'profile', 0, true);
+ $this->sendervalues[$email->id]->$field = $values->$field;
+ } elseif (!empty($this->sendervalues[$email->id]->$field)) {
+ $values->$field = @$this->sendervalues[$email->id]->$field;
+ }
+ } elseif (!empty($user->cms_id)) {
+ if (empty($currentCBUser)) {
+ $currentCBUser = CBuser::getInstance($user->cms_id);
+ }
+ if (!empty($currentCBUser)) {
+ $values->$field = $currentCBUser->getField(substr($field, 6), $oneTag->default, 'html', 'none', 'profile', 0, true);
+ }
+
+ $fieldName = substr($field, 6);
+ if (empty($values->$field) && !empty($fieldObjects[$fieldName]) && $fieldObjects[$fieldName]->type == 'progress') {
+ $fieldObjects[$fieldName]->decodedParams = json_decode($fieldObjects[$fieldName]->params);
+ if (!empty($fieldObjects[$fieldName]->decodedParams->prg_fields)) {
+ $requiredFields = explode('|*|', $fieldObjects[$fieldName]->decodedParams->prg_fields);
+ $filled_in = 0;
+ foreach ($fieldObjects as $oneField) {
+ if (!in_array($oneField->fieldid, $requiredFields) || !in_array($oneField->table, ['#__comprofiler', '#__users'])) continue;
+
+ $fieldName = $oneField->name;
+ if (!empty($currentCBUser->_cbuser->$fieldName)) {
+ $filled_in++;
+ }
+ }
+ $values->$field = intval(($filled_in * 100) / count($requiredFields)).'%';
+ }
+ }
+ }
+ }
+
+ $replaceme = isset($values->$field) ? $values->$field : $oneTag->default;
+ if (!empty($oneTag->type)) {
+ if ($oneTag->type == 'image' && !empty($replaceme)) {
+ $url = 'images/comprofiler/'.$replaceme;
+ $canvasUrl = str_replace('gallery/', 'gallery/canvas/', $url);
+ if (!file_exists(ACYM_ROOT.$url) && file_exists(ACYM_ROOT.$canvasUrl)) $url = $canvasUrl;
+ $replaceme = ' ';
+ }
+ }
+
+ if ($field == 'thumb') {
+ $replaceme = ' ';
+ } elseif ($field == 'avatar') {
+ $replaceme = ' ';
+ }
+
+ $tags[$i] = $replaceme;
+ $this->acympluginHelper->formatString($tags[$i], $oneTag);
+ }
+
+ $this->acympluginHelper->replaceTags($email, $tags);
+ }
+
+ function onAcymDeclareConditions(&$conditions)
+ {
+ $languages = [];
+ $langPath = JPATH_SITE.DS.'components'.DS.'com_comprofiler'.DS.'plugin'.DS.'language'.DS.'default_language'.DS;
+ if (file_exists($langPath.'language.php')) {
+ if (!defined('CBLIB')) include_once JPATH_SITE.DS.'libraries/CBLib/CB/Application/CBApplication.php';
+ $languages = include_once $langPath.'language.php';
+ } elseif (file_exists($langPath.'default_language.php')) {
+ include_once $langPath.'default_language.php';
+ }
+
+ $fieldTitles = acym_loadObjectList('SELECT `name`, `title` FROM #__comprofiler_fields WHERE `table` LIKE "#__comprofiler"', 'name');
+ $fields = acym_getColumns('comprofiler', false);
+
+ $cbfields = [];
+ foreach ($fields as $alias) {
+ $text = $alias;
+
+ if (!empty($fieldTitles[$alias])) {
+ if (empty($languages[$fieldTitles[$alias]->title])) {
+ if (defined($fieldTitles[$alias]->title)) {
+ $text = constant($fieldTitles[$alias]->title);
+ } else {
+ $text = $fieldTitles[$alias]->title;
+ }
+ } else {
+ $text = $languages[$fieldTitles[$alias]->title];
+ }
+ }
+
+ $cbfields[] = acym_selectOption($alias, $text);
+ }
+
+ usort($cbfields, [$this, 'sortFields']);
+
+ $operator = acym_get('type.operator');
+
+ $conditions['user']['cbfield'] = new stdClass();
+ $conditions['user']['cbfield']->name = acym_translation_sprintf('ACYM_COMBINED_TRANSLATIONS', 'Community Builder', acym_translation('ACYM_FIELDS'));
+ $conditions['user']['cbfield']->option = '';
+ $conditions['user']['cbfield']->option .= acym_select($cbfields, 'acym_condition[conditions][__numor__][__numand__][cbfield][field]', null, 'class="acym__select"');
+ $conditions['user']['cbfield']->option .= '
';
+ $conditions['user']['cbfield']->option .= '';
+ $conditions['user']['cbfield']->option .= $operator->display('acym_condition[conditions][__numor__][__numand__][cbfield][operator]');
+ $conditions['user']['cbfield']->option .= '
';
+ $conditions['user']['cbfield']->option .= ' ';
+ }
+
+ public function sortFields($a, $b)
+ {
+ return strcmp($a->text, $b->text);
+ }
+
+ public function onAcymProcessCondition_cbfield(&$query, $options, $num, &$conditionNotValid)
+ {
+ $this->processConditionFilter_cbfield($query, $options, $num);
+ $affectedRows = $query->count();
+ if (empty($affectedRows)) $conditionNotValid++;
+ }
+
+ public function processConditionFilter_cbfield(&$query, $options, $num)
+ {
+ if (empty($options['field'])) return;
+
+ $query->leftjoin['cbfield'.$num] = '#__comprofiler AS cbfield'.$num.' ON cbfield'.$num.'.id = user.cms_id';
+ $query->where[] = $query->convertQuery('cbfield'.$num, $options['field'], $options['operator'], $options['value']);
+ }
+
+ public function onAcymDeclareSummary_conditions(&$automationCondition)
+ {
+ $this->summaryConditionFilters($automationCondition);
+ }
+
+ public function summaryConditionFilters(&$automationCondition)
+ {
+ if (!empty($automationCondition['cbfield'])) {
+ $automationCondition = acym_translation_sprintf('ACYM_CONDITION_ACY_FIELD_SUMMARY', $automationCondition['cbfield']['field'], $automationCondition['cbfield']['operator'], $automationCondition['cbfield']['value']);
+ }
+ }
+
+ public function onAcymDeclareFilters(&$filters)
+ {
+ $newFilters = [];
+
+ $this->onAcymDeclareConditions($newFilters);
+ foreach ($newFilters as $oneType) {
+ foreach ($oneType as $oneFilterName => $oneFilter) {
+ if (!empty($oneFilter->option)) $oneFilter->option = str_replace(['acym_condition', '[conditions]'], ['acym_action', '[filters]'], $oneFilter->option);
+ $filters[$oneFilterName] = $oneFilter;
+ }
+ }
+ }
+
+ public function onAcymProcessFilterCount_cbfield(&$query, $options, $num)
+ {
+ $this->onAcymProcessFilter_cbfield($query, $options, $num);
+
+ return acym_translation_sprintf('ACYM_SELECTED_USERS', $query->count());
+ }
+
+ public function onAcymProcessFilter_cbfield(&$query, $options, $num)
+ {
+ $this->processConditionFilter_cbfield($query, $options, $num);
+ }
+
+ public function onAcymDeclareSummary_filters(&$automationFilter)
+ {
+ $this->summaryConditionFilters($automationFilter);
+ }
+}
+
diff --git a/deployed/acym/administrator/components/com_acym/dynamics/eventbooking/icon.png b/deployed/acym/administrator/components/com_acym/dynamics/eventbooking/icon.png
new file mode 100644
index 00000000..08f3bfcf
Binary files /dev/null and b/deployed/acym/administrator/components/com_acym/dynamics/eventbooking/icon.png differ
diff --git a/deployed/acym/administrator/components/com_acym/dynamics/eventbooking/index.html b/deployed/acym/administrator/components/com_acym/dynamics/eventbooking/index.html
new file mode 100644
index 00000000..fa6d84e8
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/dynamics/eventbooking/index.html
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/deployed/acym/administrator/components/com_acym/dynamics/eventbooking/plugin.php b/deployed/acym/administrator/components/com_acym/dynamics/eventbooking/plugin.php
new file mode 100644
index 00000000..e04b5cfb
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/dynamics/eventbooking/plugin.php
@@ -0,0 +1,824 @@
+cms = 'Joomla';
+ if (!defined('JPATH_ADMINISTRATOR') || !file_exists(rtrim(JPATH_ADMINISTRATOR, DS).DS.'components'.DS.'com_eventbooking'.DS)) {
+ $this->installed = false;
+ }
+ $this->name = 'eventbooking';
+ $this->rootCategoryId = 0;
+ }
+
+ public function insertOptions()
+ {
+ $plugin = new stdClass();
+ $plugin->name = 'Event Booking';
+ $plugin->icon = ACYM_DYNAMICS_URL.basename(__DIR__).'/icon.png';
+ $plugin->plugin = __CLASS__;
+
+ return $plugin;
+ }
+
+ public function contentPopup()
+ {
+ acym_loadLanguageFile('com_eventbooking', JPATH_SITE);
+ $this->categories = acym_loadObjectList('SELECT `id`, `parent` AS `parent_id`, `name` AS `title` FROM `#__eb_categories` WHERE published = 1', 'id');
+
+ $tabHelper = acym_get('helper.tab');
+ $tabHelper->startTab(acym_translation('ACYM_ONE_BY_ONE'));
+
+ $displayOptions = [
+ [
+ 'title' => 'ACYM_DISPLAY',
+ 'type' => 'checkbox',
+ 'name' => 'display',
+ 'options' => [
+ 'title' => ['ACYM_TITLE', true],
+ 'price' => ['ACYM_PRICE', true],
+ 'sdate' => ['ACYM_DATE', true],
+ 'edate' => ['EB_EVENT_END_DATE', true],
+ 'image' => ['ACYM_IMAGE', true],
+ 'short' => ['ACYM_SHORT_DESCRIPTION', true],
+ 'desc' => ['ACYM_DESCRIPTION', false],
+ 'cats' => ['ACYM_CATEGORIES', false],
+ 'location' => ['ACYM_LOCATION', true],
+ 'capacity' => ['EB_CAPACTIY', false],
+ 'regstart' => ['EB_REGISTRATION_START_DATE', false],
+ 'cut' => ['EB_CUT_OFF_DATE', false],
+ 'indiv' => ['EB_REGISTER_INDIVIDUAL', false],
+ 'group' => ['EB_REGISTER_GROUP', false],
+ ],
+ ],
+ ];
+
+ if (file_exists(JPATH_ROOT.DS.'components'.DS.'com_eventbooking'.DS.'fields.xml')) {
+ $xml = JFactory::getXML(JPATH_ROOT.'/components/com_eventbooking/fields.xml');
+ if (!empty($xml->fields)) {
+ $fields = $xml->fields->fieldset->children();
+ $customFields = [];
+ foreach ($fields as $oneCustomField) {
+ $name = $oneCustomField->attributes()->name;
+ $label = acym_translation($oneCustomField->attributes()->label);
+ $customFields["$name"] = [$label, false];
+ }
+
+ $displayOptions[] = [
+ 'title' => 'ACYM_CUSTOM_FIELDS',
+ 'type' => 'checkbox',
+ 'name' => 'custom',
+ 'options' => $customFields,
+ ];
+ }
+ }
+
+ $displayOptions = array_merge(
+ $displayOptions,
+ [
+ [
+ 'title' => 'ACYM_CLICKABLE_TITLE',
+ 'type' => 'boolean',
+ 'name' => 'clickable',
+ 'default' => true,
+ ],
+ [
+ 'title' => 'ACYM_TRUNCATE',
+ 'type' => 'intextfield',
+ 'name' => 'wrap',
+ 'text' => 'ACYM_TRUNCATE_AFTER',
+ 'default' => 0,
+ ],
+ [
+ 'title' => 'ACYM_READ_MORE',
+ 'type' => 'boolean',
+ 'name' => 'readmore',
+ 'default' => true,
+ ],
+ [
+ 'title' => 'ACYM_DISPLAY_PICTURES',
+ 'type' => 'pictures',
+ 'name' => 'pictures',
+ ],
+ ]
+ );
+
+ echo $this->acympluginHelper->displayOptions($displayOptions, $this->name);
+
+ echo $this->getFilteringZone();
+
+ $this->displayListing();
+
+ $tabHelper->endTab();
+ $tabHelper->startTab(acym_translation('ACYM_BY_CATEGORY'));
+
+ $catOptions = [
+ [
+ 'title' => 'ACYM_COLUMNS',
+ 'type' => 'number',
+ 'name' => 'cols',
+ 'default' => 1,
+ 'min' => 1,
+ 'max' => 10,
+ ],
+ [
+ 'title' => 'ACYM_MAX_NB_ELEMENTS',
+ 'type' => 'number',
+ 'name' => 'max',
+ 'default' => 20,
+ ],
+ [
+ 'title' => 'ACYM_FROM',
+ 'type' => 'date',
+ 'name' => 'from',
+ 'default' => date('Y-m-d'),
+ ],
+ [
+ 'title' => 'ACYM_TO',
+ 'type' => 'date',
+ 'name' => 'to',
+ 'default' => '',
+ ],
+ [
+ 'title' => 'ACYM_ORDER_BY',
+ 'type' => 'select',
+ 'name' => 'order',
+ 'options' => [
+ 'id' => 'ACYM_ID',
+ 'event_date' => 'ACYM_DATE',
+ 'cut_off_date' => 'EB_CUT_OFF_DATE',
+ 'title' => 'ACYM_TITLE',
+ 'rand' => 'ACYM_RANDOM',
+ ],
+ 'default' => 'event_date',
+ 'defaultdir' => 'asc',
+ ],
+ ];
+
+ $displayOptions = array_merge($displayOptions, $catOptions);
+
+ echo $this->acympluginHelper->displayOptions($displayOptions, 'auto'.$this->name, 'grouped');
+
+ echo $this->getCategoryListing();
+
+ $tabHelper->endTab();
+
+ $tabHelper->display('plugin');
+ }
+
+ public function displayListing()
+ {
+ $querySelect = 'SELECT event.* ';
+ $query = 'FROM `#__eb_events` AS event ';
+ $filters = [];
+
+ $this->pageInfo = new stdClass();
+ $this->pageInfo->limit = acym_getCMSConfig('list_limit');
+ $this->pageInfo->page = acym_getVar('int', 'pagination_page_ajax', 1);
+ $this->pageInfo->start = ($this->pageInfo->page - 1) * $this->pageInfo->limit;
+ $this->pageInfo->search = acym_getVar('string', 'plugin_search', '');
+ $this->pageInfo->filter_cat = acym_getVar('int', 'plugin_category', 0);
+ $this->pageInfo->order = 'event.id';
+ $this->pageInfo->orderdir = 'DESC';
+
+ $searchFields = ['event.id', 'event.title'];
+ if (!empty($this->pageInfo->search)) {
+ $searchVal = '%'.acym_getEscaped($this->pageInfo->search, true).'%';
+ $filters[] = implode(" LIKE ".acym_escapeDB($searchVal)." OR ", $searchFields)." LIKE ".acym_escapeDB($searchVal);
+ }
+
+ if (!empty($this->pageInfo->filter_cat)) {
+ $query .= 'JOIN `#__eb_event_categories` AS cat ON event.id = cat.event_id ';
+ $filters[] = 'cat.category_id = '.intval($this->pageInfo->filter_cat);
+ }
+
+ $filters[] = 'event.published = 1';
+
+ if (!empty($filters)) {
+ $query .= ' WHERE ('.implode(') AND (', $filters).')';
+ }
+
+ if (!empty($this->pageInfo->order)) {
+ $query .= ' ORDER BY '.acym_secureDBColumn($this->pageInfo->order).' '.acym_secureDBColumn($this->pageInfo->orderdir);
+ }
+
+ $rows = acym_loadObjectList($querySelect.$query, '', $this->pageInfo->start, $this->pageInfo->limit);
+ $this->pageInfo->total = acym_loadResult('SELECT COUNT(*) '.$query);
+
+
+ $listingOptions = [
+ 'header' => [
+ 'title' => [
+ 'label' => 'ACYM_TITLE',
+ 'size' => '8',
+ ],
+ 'event_date' => [
+ 'label' => 'ACYM_DATE',
+ 'size' => '3',
+ 'type' => 'date',
+ ],
+ 'id' => [
+ 'label' => 'ACYM_ID',
+ 'size' => '1',
+ 'class' => 'text-center',
+ ],
+ ],
+ 'id' => 'id',
+ 'rows' => $rows,
+ ];
+
+ echo $this->getElementsListing($listingOptions);
+ }
+
+ public function replaceContent(&$email)
+ {
+ $this->_replaceAuto($email);
+ $this->_replaceOne($email);
+ }
+
+ public function _replaceAuto(&$email)
+ {
+ $this->generateByCategory($email);
+ if (empty($this->tags)) return;
+ $this->acympluginHelper->replaceTags($email, $this->tags, true);
+ }
+
+ public function generateByCategory(&$email)
+ {
+ $time = time();
+
+ $tags = $this->acympluginHelper->extractTags($email, 'auto'.$this->name);
+ $return = new stdClass();
+ $return->status = true;
+ $return->message = '';
+ $this->tags = [];
+
+ if (empty($tags)) return $return;
+
+ foreach ($tags as $oneTag => $parameter) {
+ if (isset($this->tags[$oneTag])) continue;
+
+ $allcats = explode('-', $parameter->id);
+ $selectedArea = [];
+ foreach ($allcats as $oneCat) {
+ if (empty($oneCat)) continue;
+
+ $selectedArea[] = intval($oneCat);
+ }
+ if (empty($parameter->from)) {
+ $parameter->from = date('Y-m-d H:i:s', $time);
+ } else {
+ $parameter->from = acym_date(acym_replaceDate($parameter->from), 'Y-m-d H:i:s');
+ }
+ if (!empty($parameter->to)) $parameter->to = acym_date(acym_replaceDate($parameter->to), 'Y-m-d H:i:s');
+
+ $query = 'SELECT DISTINCT event.id FROM `#__eb_events` AS event ';
+
+ $where = [];
+ $where[] = 'event.`published` = 1';
+
+ if (!empty($selectedArea)) {
+ $query .= 'JOIN `#__eb_event_categories` AS cat ON event.id = cat.event_id ';
+ $where[] = 'cat.category_id IN ('.implode(',', $selectedArea).')';
+ }
+
+ if ((empty($parameter->mindelay) || substr($parameter->mindelay, 0, 1) != '-') && (empty($parameter->delay) || substr($parameter->delay, 0, 1) != '-')) {
+ if (!empty($parameter->addcurrent)) {
+ $where[] = 'event.`event_end_date` >= '.acym_escapeDB($parameter->from);
+ } else {
+ $where[] = 'event.`event_date` >= '.acym_escapeDB($parameter->from);
+ }
+ }
+
+ if (!empty($parameter->todaysevent)) {
+ $where[] = 'event.`event_date` <= '.acym_escapeDB(date('Y-m-d 23:59:59', $time));
+ }
+
+ if (!empty($parameter->mindelay)) $where[] = 'event.`event_date` >= '.acym_escapeDB(date('Y-m-d H:i:s', $time + $parameter->mindelay));
+ if (!empty($parameter->delay)) $where[] = 'event.`event_date` <= '.acym_escapeDB(date('Y-m-d H:i:s', $time + $parameter->delay));
+ if (!empty($parameter->to)) $where[] = 'event.`event_date` <= '.acym_escapeDB($parameter->to);
+
+ $query .= ' WHERE ('.implode(') AND (', $where).')';
+
+ $ordering = explode(',', $parameter->order);
+ if ($ordering[0] == 'rand') {
+ $query .= ' ORDER BY rand()';
+ } else {
+ $query .= ' ORDER BY '.acym_secureDBColumn(trim($ordering[0])).' '.acym_secureDBColumn(trim($ordering[1]));
+ }
+
+ if (empty($parameter->max)) $parameter->max = 20;
+ $query .= ' LIMIT '.intval($parameter->max);
+
+ $allArticles = acym_loadResultArray($query);
+
+ if (!empty($parameter->min) && count($allArticles) < $parameter->min) {
+ $return->status = false;
+ $return->message = 'Not enough events for the tag '.$oneTag.' : '.count($allArticles).' / '.$parameter->min;
+ }
+
+ $this->tags[$oneTag] = $this->finalizeCategoryFormat($this->name, $allArticles, $parameter);
+ }
+
+ return $return;
+ }
+
+ public function _replaceOne(&$email)
+ {
+ $tags = $this->acympluginHelper->extractTags($email, $this->name);
+ if (empty($tags)) return;
+
+ acym_loadLanguageFile('com_eventbooking', JPATH_SITE);
+
+ if (!include_once JPATH_ROOT.'/components/com_eventbooking/helper/helper.php') {
+ if (acym_isAdmin()) acym_enqueueMessage('Could not load the Event Booking helper', 'notice');
+
+ return;
+ }
+
+ $this->eventbookingconfig = EventBookingHelper::getConfig();
+
+ $tagsReplaced = [];
+ foreach ($tags as $i => $params) {
+ if (isset($tagsReplaced[$i])) continue;
+
+ $tagsReplaced[$i] = $this->_replaceContent($tags[$i]);
+ }
+
+ $this->acympluginHelper->replaceTags($email, $tagsReplaced, true);
+ }
+
+ public function _replaceContent(&$tag)
+ {
+ $query = 'SELECT event.*, location.name AS location_name FROM `#__eb_events` AS event ';
+ $query .= 'LEFT JOIN `#__eb_locations` AS location ON event.location_id = location.id ';
+ $query .= 'WHERE event.id = '.intval($tag->id);
+
+ $element = acym_loadObject($query);
+
+ if (empty($element)) {
+ if (acym_isAdmin()) acym_enqueueMessage('The event "'.$tag->id.'" could not be loaded', 'notice');
+
+ return '';
+ }
+
+ $varFields = [];
+ foreach ($element as $fieldName => $oneField) {
+ $varFields['{'.$fieldName.'}'] = $oneField;
+ }
+
+ $tag->display = empty($tag->display) ? [] : explode(',', $tag->display);
+ $tag->custom = empty($tag->custom) ? [] : explode(',', $tag->custom);
+
+ $link = acym_frontendLink('index.php?option=com_eventbooking&view=event&id='.intval($tag->id), false);
+ $varFields['{link}'] = $link;
+
+ $title = '';
+ $afterTitle = '';
+ $afterArticle = '';
+
+ $imagePath = '';
+ $contentText = '';
+ $customFields = [];
+
+
+ if (in_array('title', $tag->display)) $title = $element->title;
+ if (in_array('short', $tag->display)) $contentText .= $element->short_description;
+ if (in_array('desc', $tag->display)) $contentText .= $element->description;
+
+ if (in_array('image', $tag->display) && !empty($element->image)) $imagePath = acym_frontendLink($element->image, false);
+
+
+ if (in_array('sdate', $tag->display) && $element->event_date > '0001-00-00') {
+ $customFields[] = [acym_date($element->event_date, $this->eventbookingconfig->event_date_format, null), acym_translation('EB_EVENT_DATE')];
+ }
+
+ if (in_array('edate', $tag->display) && $element->event_end_date > '0001-00-00') {
+ $customFields[] = [acym_date($element->event_end_date, $this->eventbookingconfig->event_date_format, null), acym_translation('EB_EVENT_END_DATE')];
+ }
+
+ if (in_array('location', $tag->display) && !empty($element->location_id)) {
+ $location = ''.$element->location_name.' ';
+ $customFields[] = [$location, acym_translation('EB_LOCATION')];
+ }
+
+ if (in_array('cats', $tag->display)) {
+ $categories = acym_loadObjectList(
+ 'SELECT cat.id, cat.name
+ FROM #__eb_categories AS cat
+ JOIN #__eb_event_categories AS eventcats ON cat.id = eventcats.category_id
+ WHERE eventcats.event_id = '.intval($tag->id).'
+ ORDER BY cat.name ASC'
+ );
+
+ foreach ($categories as $i => $oneCat) {
+ $categories[$i] = ''.acym_escape($oneCat->name).' ';
+ }
+ $customFields[] = [implode(', ', $categories), acym_translation('ACYM_CATEGORIES')];
+ }
+
+ if (in_array('capacity', $tag->display)) {
+ $capacity = empty($element->event_capacity) ? acym_translation('EB_UNLIMITED') : $element->event_capacity;
+ $customFields[] = [$capacity, acym_translation('EB_CAPACTIY')];
+ }
+
+ if (in_array('price', $tag->display)) {
+ if ($element->individual_price > 0) {
+ $price = @EventBookingHelper::formatCurrency($element->individual_price, $this->eventbookingconfig, $element->currency_symbol);
+ } else {
+ $price = acym_translation('EB_FREE');
+ }
+
+ $customFields[] = [$price, acym_translation('EB_PRICE')];
+ }
+
+ if (!empty($tag->custom) && !empty($element->custom_fields)) {
+ $customFields = array_merge($customFields, $this->_handleCustomFields($element->custom_fields, $tag->custom));
+ }
+
+ if (in_array('regstart', $tag->display) && $element->registration_start_date > '0001-00-00') {
+ $customFields[] = [acym_date($element->registration_start_date, $this->eventbookingconfig->date_format, null), acym_translation('EB_REGISTRATION_START_DATE')];
+ }
+
+ if (in_array('cut', $tag->display) && $element->cut_off_date > '0001-00-00') {
+ $customFields[] = [acym_date($element->cut_off_date, $this->eventbookingconfig->date_format, null), acym_translation('EB_CUT_OFF_DATE')];
+ }
+
+ if (in_array('indiv', $tag->display) || in_array('group', $tag->display)) {
+ $value = [];
+
+ if (in_array('indiv', $tag->display)) {
+ $reglink = acym_frontendLink('index.php?option=com_eventbooking&task=register.individual_registration&event_id='.$tag->id, false);
+ $varFields['{individualregbutton}'] = ''.acym_translation('EB_REGISTER_INDIVIDUAL').' ';
+ $value[] = $varFields['{individualregbutton}'];
+ }
+
+ if (in_array('group', $tag->display)) {
+ $reglink = acym_frontendLink('index.php?option=com_eventbooking&task=register.group_registration&event_id='.$tag->id, false);
+ $varFields['{groupregbutton}'] = ''.acym_translation('EB_REGISTER_GROUP').' ';
+ $value[] = $varFields['{groupregbutton}'];
+ }
+
+ $customFields[] = [implode(' ', $value)];
+ }
+
+ $varFields['{readmore}'] = ''.acym_translation('ACYM_READ_MORE').' ';
+ if (!empty($tag->readmore)) {
+ $afterArticle .= $varFields['{readmore}'];
+ }
+
+ $format = new stdClass();
+ $format->tag = $tag;
+ $format->title = $title;
+ $format->afterTitle = $afterTitle;
+ $format->afterArticle = $afterArticle;
+ $format->imagePath = $imagePath;
+ $format->description = $contentText;
+ $format->link = empty($tag->clickable) ? '' : $link;
+ $format->cols = empty($tag->nbcols) ? 1 : intval($tag->nbcols);
+ $format->customFields = $customFields;
+ $result = ''.$this->acympluginHelper->getStandardDisplay($format).'
';
+
+ return $this->finalizeElementFormat($this->name, $result, $tag, $varFields);
+ }
+
+ private function _handleCustomFields($customFields, $selected)
+ {
+ $result = [];
+
+ if (!file_exists(JPATH_ROOT.DS.'components'.DS.'com_eventbooking'.DS.'fields.xml')) return $result;
+
+ $xml = JFactory::getXML(JPATH_ROOT.'/components/com_eventbooking/fields.xml');
+ $fields = $xml->fields->fieldset->children();
+ $params = new JRegistry();
+ $params->loadString($customFields, 'INI');
+ $decodedFields = json_decode($customFields);
+
+ foreach ($fields as $oneCustomField) {
+ $name = $oneCustomField->attributes()->name;
+ $label = acym_translation($oneCustomField->attributes()->label);
+ $value = $params->get($name);
+ $name = (string)$name;
+
+ if ($value === null && !empty($decodedFields) && !empty($decodedFields->$name)) {
+ $value = $decodedFields->$name;
+ }
+
+ if (empty($value) || !in_array($name, $selected)) continue;
+
+ $result[] = [$value, $label];
+ }
+
+ return $result;
+ }
+
+ public function searchEvent()
+ {
+ $id = acym_getVar('int', 'id');
+ if (!empty($id)) {
+ $subject = acym_loadResult('SELECT `title` FROM #__eb_events WHERE `id` = '.intval($id));
+ if (empty($subject)) $subject = '';
+ echo json_encode(['value' => $id.' - '.$subject]);
+ exit;
+ }
+
+ $return = [];
+ $search = acym_getVar('cmd', 'search', '');
+ $products = acym_loadObjectList('SELECT `id`, `title` FROM `#__eb_events` WHERE `title` LIKE '.acym_escapeDB('%'.$search.'%').' ORDER BY `title` ASC');
+
+ foreach ($products as $oneProduct) {
+ $return[] = [$oneProduct->id, $oneProduct->id.' - '.$oneProduct->title];
+ }
+
+ echo json_encode($return);
+ exit;
+ }
+
+ public function onAcymDeclareConditions(&$conditions)
+ {
+ acym_loadLanguageFile('com_eventbooking', JPATH_SITE);
+
+ $conditions['user']['ebregistration'] = new stdClass();
+ $conditions['user']['ebregistration']->name = acym_translation_sprintf('ACYM_COMBINED_TRANSLATIONS', 'Event Booking', acym_translation('EB_REGISTRANTS'));
+ $conditions['user']['ebregistration']->option = '';
+
+ $conditions['user']['ebregistration']->option .= '
';
+ $ajaxParams = json_encode(
+ [
+ 'plugin' => __CLASS__,
+ 'trigger' => 'searchEvent',
+ ]
+ );
+ $conditions['user']['ebregistration']->option .= acym_select(
+ [],
+ 'acym_condition[conditions][__numor__][__numand__][ebregistration][event]',
+ null,
+ 'class="acym__select acym_select2_ajax" data-placeholder="'.acym_translation('ACYM_ANY_EVENT', true).'" data-params="'.acym_escape($ajaxParams).'"'
+ );
+ $conditions['user']['ebregistration']->option .= '
';
+
+ $status = [];
+ $status[] = acym_selectOption('-1', 'ACYM_STATUS');
+ $status[] = acym_selectOption('0', 'EB_PENDING');
+ $status[] = acym_selectOption('1', 'EB_PAID');
+ $status[] = acym_selectOption('2', 'EB_CANCELLED');
+
+ $conditions['user']['ebregistration']->option .= '
';
+ $conditions['user']['ebregistration']->option .= acym_select($status, 'acym_condition[conditions][__numor__][__numand__][ebregistration][status]', '-1', 'class="acym__select"');
+ $conditions['user']['ebregistration']->option .= '
';
+
+ $conditions['user']['ebregistration']->option .= '
';
+
+ $conditions['user']['ebregistration']->option .= '';
+ $conditions['user']['ebregistration']->option .= acym_dateField('acym_condition[conditions][__numor__][__numand__][ebregistration][datemin]', '', 'cell shrink');
+ $conditions['user']['ebregistration']->option .= '< ';
+ $conditions['user']['ebregistration']->option .= ''.acym_translation('EB_REGISTRATION_DATE').' ';
+ $conditions['user']['ebregistration']->option .= '< ';
+ $conditions['user']['ebregistration']->option .= acym_dateField('acym_condition[conditions][__numor__][__numand__][ebregistration][datemax]', '', 'cell shrink');
+ $conditions['user']['ebregistration']->option .= '
';
+ }
+
+ public function onAcymProcessCondition_ebregistration(&$query, $options, $num, &$conditionNotValid)
+ {
+ $this->processConditionFilter_ebregistration($query, $options, $num);
+ $affectedRows = $query->count();
+ if (empty($affectedRows)) $conditionNotValid++;
+ }
+
+ private function processConditionFilter_ebregistration(&$query, $options, $num)
+ {
+ $query->join['ebregistration'.$num] = '`#__eb_registrants` AS eventbooking'.$num.' ON (
+ eventbooking'.$num.'.email = user.email
+ OR (
+ eventbooking'.$num.'.user_id != 0
+ AND eventbooking'.$num.'.user_id = user.cms_id
+ )
+ )';
+
+ if (!empty($options['event'])) $query->where[] = 'eventbooking'.$num.'.event_id = '.intval($options['event']);
+ if (!empty($options['status']) && $options['status'] != -1) $query->where[] = 'eventbooking'.$num.'.published = '.intval($options['status']);
+
+ if (!empty($options['datemin'])) {
+ $options['datemin'] = acym_replaceDate($options['datemin']);
+ if (!is_numeric($options['datemin'])) $options['datemin'] = strtotime($options['datemin']);
+ if (!empty($options['datemin'])) {
+ $query->where[] = 'eventbooking'.$num.'.register_date > '.acym_escapeDB(date('Y-m-d H:i:s', $options['datemin']));
+ }
+ }
+
+ if (!empty($options['datemax'])) {
+ $options['datemax'] = acym_replaceDate($options['datemax']);
+ if (!is_numeric($options['datemax'])) $options['datemax'] = strtotime($options['datemax']);
+ if (!empty($options['datemax'])) {
+ $query->where[] = 'eventbooking'.$num.'.register_date < '.acym_escapeDB(date('Y-m-d H:i:s', $options['datemax']));
+ }
+ }
+ }
+
+ public function onAcymDeclareSummary_conditions(&$automationCondition)
+ {
+ $this->summaryConditionFilters($automationCondition);
+ }
+
+ private function summaryConditionFilters(&$automationCondition)
+ {
+ if (!empty($automationCondition['ebregistration'])) {
+ if (empty($automationCondition['ebregistration']['event'])) {
+ $event = acym_translation('ACYM_ANY_EVENT');
+ } else {
+ $event = acym_loadResult('SELECT `title` FROM #__eb_events WHERE `id` = '.intval($automationCondition['ebregistration']['event']));
+ }
+
+ $status = [
+ '-1' => 'ACYM_ANY',
+ '0' => 'EB_PENDING',
+ '1' => 'EB_PAID',
+ '2' => 'EB_CANCELLED',
+ ];
+
+ $status = acym_translation($status[$automationCondition['ebregistration']['status']]);
+
+ $finalText = acym_translation_sprintf('ACYM_REGISTERED', $event, $status);
+
+ $dates = [];
+ if (!empty($automationCondition['ebregistration']['datemin'])) {
+ $dates[] = acym_translation('ACYM_AFTER').' '.acym_replaceDate($automationCondition['ebregistration']['datemin'], true);
+ }
+
+ if (!empty($automationCondition['ebregistration']['datemax'])) {
+ $dates[] = acym_translation('ACYM_BEFORE').' '.acym_replaceDate($automationCondition['ebregistration']['datemax'], true);
+ }
+
+ if (!empty($dates)) {
+ $finalText .= ' '.implode(' '.acym_translation('ACYM_AND').' ', $dates);
+ }
+
+ $automationCondition = $finalText;
+ }
+ }
+
+ public function onAcymDeclareFilters(&$filters)
+ {
+ $newFilters = [];
+
+ $this->onAcymDeclareConditions($newFilters);
+ foreach ($newFilters as $oneType) {
+ foreach ($oneType as $oneFilterName => $oneFilter) {
+ if (!empty($oneFilter->option)) $oneFilter->option = str_replace(['acym_condition', '[conditions]'], ['acym_action', '[filters]'], $oneFilter->option);
+ $filters[$oneFilterName] = $oneFilter;
+ }
+ }
+ }
+
+ public function onAcymProcessFilterCount_ebregistration(&$query, $options, $num)
+ {
+ $this->onAcymProcessFilter_ebregistration($query, $options, $num);
+
+ return acym_translation_sprintf('ACYM_SELECTED_USERS', $query->count());
+ }
+
+ public function onAcymProcessFilter_ebregistration(&$query, $options, $num)
+ {
+ $this->processConditionFilter_ebregistration($query, $options, $num);
+ }
+
+ public function onAcymDeclareSummary_filters(&$automationFilter)
+ {
+ $this->summaryConditionFilters($automationFilter);
+ }
+
+ public function onAcymDeclareTriggers(&$triggers, &$defaultValues)
+ {
+
+ $every = [
+ '3600' => acym_translation('ACYM_HOURS'),
+ '86400' => acym_translation('ACYM_DAYS'),
+ ];
+
+ $when = [
+ 'before' => acym_translation('ACYM_BEFORE'),
+ 'after' => acym_translation('ACYM_AFTER'),
+ ];
+
+ $categories = acym_loadObjectList('SELECT `id`, `name` FROM #__eb_categories', 'id');
+
+ foreach ($categories as $key => $category) {
+ $categories[$key] = $category->name;
+ }
+
+ $categories = ['' => acym_translation('ACYM_ANY_CATEGORY')] + $categories;
+
+ $triggers['classic']['eventbooking_reminder'] = new stdClass();
+ $triggers['classic']['eventbooking_reminder']->name = acym_translation_sprintf('ACYM_COMBINED_TRANSLATIONS', 'EventBooking', acym_translation('ACYM_REMINDER'));
+ $triggers['classic']['eventbooking_reminder']->option = '';
+ $triggers['classic']['eventbooking_reminder']->option .= '
+
+
';
+ $triggers['classic']['eventbooking_reminder']->option .= '
'.acym_select(
+ $every,
+ '[triggers][classic][eventbooking_reminder][time]',
+ empty($defaultValues['eventbooking_reminder']) ? '86400' : $defaultValues['eventbooking_reminder']['time'],
+ 'data-class="intext_select acym__select"'
+ ).'
';
+ $triggers['classic']['eventbooking_reminder']->option .= '
'.acym_select(
+ $when,
+ '[triggers][classic][eventbooking_reminder][when]',
+ empty($defaultValues['eventbooking_reminder']) ? 'before' : $defaultValues['eventbooking_reminder']['when'],
+ 'data-class="intext_select acym__select"'
+ ).'
';
+ $triggers['classic']['eventbooking_reminder']->option .= '
'.acym_translation('ACYM_AN_EVENT_IN').'
';
+ $triggers['classic']['eventbooking_reminder']->option .= '
'.acym_select(
+ $categories,
+ '[triggers][classic][eventbooking_reminder][cat]',
+ empty($defaultValues['eventbooking_reminder']) ? '' : $defaultValues['eventbooking_reminder']['cat'],
+ 'data-class="intext_select_larger intext_select acym__select"'
+ ).'
';
+ $triggers['classic']['eventbooking_reminder']->option .= '
';
+ }
+
+ public function onAcymExecuteTrigger(&$step, &$execute, $data)
+ {
+ $time = $data['time'];
+ $triggers = json_decode($step->triggers, true);
+
+ if (!empty($triggers['eventbooking_reminder']['number'])) {
+ $config = acym_config();
+ $triggerReminder = $triggers['eventbooking_reminder'];
+
+ $timestamp = ($triggerReminder['number'] * $triggerReminder['time']);
+
+ if ($triggerReminder['when'] == 'before') {
+ $timestamp += $time;
+ } else {
+ $timestamp -= $time;
+ }
+
+
+ $join = [];
+ $where = [];
+
+ if (!empty($triggerReminder['cat'])) {
+ $join[] = 'LEFT JOIN #__eb_event_categories as cat ON `event`.`id` = `cat`.`event_id`';
+ $where[] = '`cat`.`category_id` = '.intval($triggerReminder['cat']);
+ }
+
+ $where[] = '`event`.`event_date` >= '.acym_escapeDB(acym_date($timestamp, 'Y-m-d H:i:s', true));
+ $where[] = '`event`.`event_date` <= '.acym_escapeDB(acym_date($timestamp + $config->get('cron_frequency', '900'), 'Y-m-d H:i:s', true));
+ $where[] = '`event`.`published` = 1';
+
+ $events = acym_loadObjectList('SELECT * FROM `#__eb_events` as event '.implode(' ', $join).' WHERE '.implode(' AND ', $where));
+ if (!empty($events)) $execute = true;
+ }
+ }
+
+ public function onAcymDeclareSummary_triggers(&$automation)
+ {
+ if (!empty($automation->triggers['eventbooking_reminder'])) {
+ $every = [
+ '3600' => acym_translation('ACYM_HOURS'),
+ '86400' => acym_translation('ACYM_DAYS'),
+ ];
+
+ $when = [
+ 'before' => acym_translation('ACYM_BEFORE'),
+ 'after' => acym_translation('ACYM_AFTER'),
+ ];
+
+ $categories = acym_loadObjectList('SELECT `id`, `name` FROM #__eb_categories', 'id');
+
+ foreach ($categories as $key => $category) {
+ $categories[$key] = $category->name;
+ }
+
+ $categories = ['' => acym_translation('ACYM_ANY_CATEGORY')] + $categories;
+
+ $final = $automation->triggers['eventbooking_reminder']['number'].' ';
+ $final .= $every[$automation->triggers['eventbooking_reminder']['time']].' ';
+ $final .= $when[$automation->triggers['eventbooking_reminder']['when']].' ';
+ $final .= acym_translation('ACYM_AN_EVENT_IN').' '.strtolower($categories[$automation->triggers['eventbooking_reminder']['cat']]);
+
+ $automation->triggers['eventbooking_reminder'] = $final;
+ }
+ }
+}
+
diff --git a/deployed/acym/administrator/components/com_acym/dynamics/hikashop/icon.ico b/deployed/acym/administrator/components/com_acym/dynamics/hikashop/icon.ico
new file mode 100644
index 00000000..edad0409
Binary files /dev/null and b/deployed/acym/administrator/components/com_acym/dynamics/hikashop/icon.ico differ
diff --git a/deployed/acym/administrator/components/com_acym/dynamics/hikashop/index.html b/deployed/acym/administrator/components/com_acym/dynamics/hikashop/index.html
new file mode 100644
index 00000000..fa6d84e8
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/dynamics/hikashop/index.html
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/deployed/acym/administrator/components/com_acym/dynamics/hikashop/plugin.php b/deployed/acym/administrator/components/com_acym/dynamics/hikashop/plugin.php
new file mode 100644
index 00000000..b38f473c
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/dynamics/hikashop/plugin.php
@@ -0,0 +1,1090 @@
+cms = 'Joomla';
+ if (!defined('JPATH_ADMINISTRATOR') || !file_exists(rtrim(JPATH_ADMINISTRATOR, DS).DS.'components'.DS.'com_hikashop'.DS)) {
+ $this->installed = false;
+ }
+ $this->name = 'hikashop';
+ }
+
+ public function insertOptions()
+ {
+ $plugin = new stdClass();
+ $plugin->name = 'HikaShop';
+ $plugin->icon = ACYM_DYNAMICS_URL.basename(__DIR__).'/icon.ico';
+ $plugin->plugin = __CLASS__;
+
+ return $plugin;
+ }
+
+ public function contentPopup()
+ {
+ acym_loadLanguageFile('com_hikashop', JPATH_SITE);
+
+ $this->categories = acym_loadObjectList("SELECT category_id AS id, category_parent_id AS parent_id, category_name AS title FROM `#__hikashop_category` WHERE category_type = 'product'", 'id');
+
+ $tabHelper = acym_get('helper.tab');
+ $tabHelper->startTab(acym_translation('ACYM_ONE_BY_ONE'));
+
+ $displayOptions = [
+ [
+ 'title' => 'ACYM_DISPLAY',
+ 'type' => 'radio',
+ 'name' => 'type',
+ 'options' => [
+ 'title' => 'ACYM_TITLE_ONLY',
+ 'intro' => 'ACYM_INTRO_ONLY',
+ 'full' => 'ACYM_FULL_TEXT',
+ ],
+ 'default' => 'full',
+ ],
+ [
+ 'title' => 'ACYM_PRICE',
+ 'type' => 'radio',
+ 'name' => 'price',
+ 'options' => [
+ 'full' => 'ACYM_APPLY_DISCOUNTS',
+ 'no_discount' => 'ACYM_NO_DISCOUNT',
+ 'none' => 'ACYM_NO',
+ ],
+ 'default' => 'full',
+ ],
+ ];
+
+ echo $this->acympluginHelper->displayOptions($displayOptions, $this->name);
+
+ echo $this->getFilteringZone();
+
+ $this->displayListing();
+
+ $tabHelper->endTab();
+ $tabHelper->startTab(acym_translation('ACYM_BY_CATEGORY'));
+
+ $catOptions = [
+ [
+ 'title' => 'ACYM_ORDER_BY',
+ 'type' => 'select',
+ 'name' => 'order',
+ 'options' => [
+ 'product_id' => 'ACYM_ID',
+ 'product_created' => 'ACYM_DATE_CREATED',
+ 'product_modified' => 'ACYM_MODIFICATION_DATE',
+ 'product_name' => 'ACYM_TITLE',
+ 'rand' => 'ACYM_RANDOM',
+ ],
+ ],
+ [
+ 'title' => 'ACYM_COLUMNS',
+ 'type' => 'text',
+ 'name' => 'cols',
+ 'default' => 1,
+ ],
+ [
+ 'title' => 'ACYM_MAX_NB_ELEMENTS',
+ 'type' => 'text',
+ 'name' => 'max',
+ 'default' => 20,
+ ],
+ ];
+
+ $displayOptions = array_merge($displayOptions, $catOptions);
+
+ echo $this->acympluginHelper->displayOptions($displayOptions, 'auto'.$this->name, 'grouped');
+
+ echo $this->getCategoryListing();
+
+ $tabHelper->endTab();
+ $tabHelper->startTab(acym_translation('HIKA_ABANDONED_CART'));
+
+ $methods = acym_loadObjectList('SELECT payment_id, payment_name FROM #__hikashop_payment', 'payment_id');
+
+ $paymentMethods = ['' => 'ALL_PAYMENT_METHODS'];
+ foreach ($methods as $method) {
+ $paymentMethods[$method->payment_id] = $method->payment_name;
+ }
+
+ $displayOptions = [
+ [
+ 'title' => 'ACYM_DISPLAY',
+ 'type' => 'radio',
+ 'name' => 'type',
+ 'options' => [
+ 'title' => 'ACYM_TITLE_ONLY',
+ 'intro' => 'ACYM_INTRO_ONLY',
+ 'full' => 'ACYM_FULL_TEXT',
+ ],
+ 'default' => 'full',
+ ],
+ [
+ 'title' => 'PAYMENT_METHOD',
+ 'type' => 'select',
+ 'name' => 'paymentcart',
+ 'options' => $paymentMethods,
+ ],
+ [
+ 'title' => 'ACYM_DATE_CREATED',
+ 'type' => 'intextfield',
+ 'name' => 'nbdayscart',
+ 'text' => 'DAYS_AFTER_ORDERING',
+ 'default' => 1,
+ ],
+ ];
+
+ echo $this->acympluginHelper->displayOptions($displayOptions, 'hikashop_abandonedcart', 'simple');
+
+ $tabHelper->endTab();
+ $tabHelper->startTab(acym_translation('ACYM_COUPON'));
+
+ $query = "SELECT `product_id`, CONCAT(product_name, ' ( ', product_code, ' )') AS `title`
+ FROM #__hikashop_product
+ WHERE `product_type`='main' AND `product_published` = 1
+ ORDER BY `product_code` ASC";
+ $results = acym_loadObjectList($query);
+
+ $products = [0 => 'ACYM_NONE'];
+ foreach ($results as $result) {
+ $products[$result->product_id] = $result->title;
+ }
+
+ $parent = acym_loadResult('SELECT category_id FROM #__hikashop_category WHERE category_parent_id = 0');
+
+ $query = 'SELECT a.category_id, a.category_name
+ FROM #__hikashop_category AS a
+ WHERE a.category_type = "tax"
+ AND a.category_published = 1
+ AND a.category_parent_id != '.intval($parent).'
+ ORDER BY a.category_ordering ASC';
+
+ $results = acym_loadObjectList($query);
+
+ $taxes = [0 => 'ACYM_NONE'];
+ foreach ($results as $result) {
+ $taxes[$result->category_id] = $result->category_name;
+ }
+
+ $query = 'SELECT currency_id AS value, CONCAT(currency_symbol, " ", currency_code) AS text FROM #__hikashop_currency WHERE currency_published = 1';
+ $currencies = acym_loadObjectList($query);
+
+ $displayOptions = [
+ [
+ 'title' => 'DISCOUNT_CODE',
+ 'type' => 'text',
+ 'name' => 'code',
+ 'default' => '[name][key][value]',
+ 'class' => 'acym_plugin__larger_text_field',
+ 'large' => true,
+ ],
+ [
+ 'title' => 'DISCOUNT_FLAT_AMOUNT',
+ 'type' => 'custom',
+ 'name' => 'flat',
+ 'output' => '
+ '.acym_select($currencies, 'currencyhikashop_coupon', null, 'onchange="updateDynamichikashop_coupon();" style="width: 80px;"'),
+ 'js' => 'otherinfo += "| flat:" + jQuery(\'input[name="flathikashop_coupon"]\').val();
+ otherinfo += "| currency:" + jQuery(\'[name="currencyhikashop_coupon"]\').val();',
+ ],
+ [
+ 'title' => 'DISCOUNT_PERCENT_AMOUNT',
+ 'type' => 'text',
+ 'name' => 'percent',
+ 'default' => '0',
+ ],
+ [
+ 'title' => 'DISCOUNT_START_DATE',
+ 'type' => 'date',
+ 'name' => 'start',
+ 'default' => '',
+ ],
+ [
+ 'title' => 'DISCOUNT_END_DATE',
+ 'type' => 'date',
+ 'name' => 'end',
+ 'default' => '',
+ ],
+ [
+ 'title' => 'MINIMUM_ORDER_VALUE',
+ 'type' => 'text',
+ 'name' => 'min',
+ 'default' => '0',
+ ],
+ [
+ 'title' => 'DISCOUNT_QUOTA',
+ 'type' => 'text',
+ 'name' => 'quota',
+ 'default' => '',
+ ],
+ [
+ 'title' => 'PRODUCT',
+ 'type' => 'select',
+ 'name' => 'product',
+ 'options' => $products,
+ 'default' => '0',
+ ],
+ [
+ 'title' => 'TAXATION_CATEGORY',
+ 'type' => 'select',
+ 'name' => 'tax',
+ 'options' => $taxes,
+ 'default' => '0',
+ ],
+ ];
+
+ echo $this->acympluginHelper->displayOptions($displayOptions, 'hikashop_coupon', 'simple');
+
+ $tabHelper->endTab();
+
+ $tabHelper->display('plugin');
+ }
+
+ public function displayListing()
+ {
+ $querySelect = 'SELECT a.* ';
+ $query = 'FROM #__hikashop_product AS a ';
+ $filters = [];
+
+ $this->pageInfo = new stdClass();
+ $this->pageInfo->limit = acym_getCMSConfig('list_limit');
+ $this->pageInfo->page = acym_getVar('int', 'pagination_page_ajax', 1);
+ $this->pageInfo->start = ($this->pageInfo->page - 1) * $this->pageInfo->limit;
+ $this->pageInfo->search = acym_getVar('string', 'plugin_search', '');
+ $this->pageInfo->filter_cat = acym_getVar('int', 'plugin_category', 0);
+ $this->pageInfo->order = 'a.product_id';
+ $this->pageInfo->orderdir = 'DESC';
+
+ $searchFields = ['a.product_id', 'a.product_name', 'a.product_code'];
+ if (!empty($this->pageInfo->search)) {
+ $searchVal = '%'.acym_getEscaped($this->pageInfo->search, true).'%';
+ $filters[] = implode(" LIKE ".acym_escapeDB($searchVal)." OR ", $searchFields)." LIKE ".acym_escapeDB($searchVal);
+ }
+ if (!empty($this->pageInfo->filter_cat)) {
+ $query .= 'JOIN #__hikashop_product_category AS b ON a.product_id = b.product_id';
+ $filters[] = "b.category_id = ".intval($this->pageInfo->filter_cat);
+ }
+ if (!empty($filters)) {
+ $query .= ' WHERE ('.implode(') AND (', $filters).')';
+ }
+ if (!empty($this->pageInfo->order)) {
+ $query .= ' ORDER BY '.acym_secureDBColumn($this->pageInfo->order).' '.acym_secureDBColumn($this->pageInfo->orderdir);
+ }
+
+ $rows = acym_loadObjectList($querySelect.$query, '', $this->pageInfo->start, $this->pageInfo->limit);
+ $this->pageInfo->total = acym_loadResult('SELECT COUNT(*) '.$query);
+
+
+ $listingOptions = [
+ 'header' => [
+ 'product_name' => [
+ 'label' => 'ACYM_TITLE',
+ 'size' => '7',
+ ],
+ 'product_created' => [
+ 'label' => 'ACYM_DATE_CREATED',
+ 'size' => '4',
+ 'type' => 'date',
+ ],
+ 'product_id' => [
+ 'label' => 'ACYM_ID',
+ 'size' => '1',
+ 'class' => 'text-center',
+ ],
+ ],
+ 'id' => 'product_id',
+ 'rows' => $rows,
+ ];
+
+ echo $this->getElementsListing($listingOptions);
+ }
+
+ public function replaceContent(&$email)
+ {
+ $this->_replaceAuto($email);
+ $this->_replaceOne($email);
+ }
+
+ public function _replaceAuto(&$email)
+ {
+ $this->generateByCategory($email);
+ if (empty($this->tags)) {
+ return;
+ }
+ $this->acympluginHelper->replaceTags($email, $this->tags, true);
+ }
+
+ public function generateByCategory(&$email)
+ {
+ $tags = $this->acympluginHelper->extractTags($email, 'auto'.$this->name);
+ $return = new stdClass();
+ $return->status = true;
+ $return->message = '';
+ $this->tags = [];
+
+ if (empty($tags)) {
+ return $return;
+ }
+
+ foreach ($tags as $oneTag => $parameter) {
+ if (isset($this->tags[$oneTag])) continue;
+
+ $allcats = explode('-', $parameter->id);
+ $selectedArea = [];
+ foreach ($allcats as $oneCat) {
+ if (empty($oneCat)) continue;
+ $selectedArea[] = intval($oneCat);
+ }
+
+ $query = 'SELECT DISTINCT b.`product_id` FROM #__hikashop_product_category AS a
+ LEFT JOIN #__hikashop_product AS b ON a.product_id = b.product_id';
+
+ $where = [];
+
+ if (!empty($selectedArea)) {
+ $where[] = 'a.category_id IN ('.implode(',', $selectedArea).')';
+ }
+
+ $where[] = "b.`product_published` = 1";
+
+ if (!empty($parameter->filter) && !empty($email->params['lastgenerateddate'])) {
+ $condition = 'b.`product_created` > '.acym_escapeDB($email->params['lastgenerateddate']);
+ if ($parameter->filter == 'modify') {
+ $condition .= ' OR b.`product_modified` > '.acym_escapeDB($email->params['lastgenerateddate']);
+ }
+ $where[] = $condition;
+ }
+
+ $query .= ' WHERE ('.implode(') AND (', $where).')';
+
+ if (!empty($parameter->order)) {
+ $ordering = explode(',', $parameter->order);
+ if ($ordering[0] == 'rand') {
+ $query .= ' ORDER BY rand()';
+ } else {
+ $query .= ' ORDER BY b.`'.acym_secureDBColumn(trim($ordering[0])).'` '.acym_secureDBColumn(trim($ordering[1]));
+ }
+ }
+
+ if (!empty($parameter->max)) {
+ $query .= ' LIMIT '.intval($parameter->max);
+ }
+ $allArticles = acym_loadResultArray($query);
+
+ if (!empty($parameter->min) && count($allArticles) < $parameter->min) {
+ $return->status = false;
+ $return->message = 'Not enough products for the tag '.$oneTag.' : '.count($allArticles).' / '.$parameter->min;
+ }
+
+ $this->tags[$oneTag] = $this->finalizeCategoryFormat($this->name, $allArticles, $parameter);
+ }
+
+ return $return;
+ }
+
+ private function _replaceOne(&$email)
+ {
+ $tags = $this->acympluginHelper->extractTags($email, $this->name);
+ if (empty($tags)) return;
+
+ $this->readmore = empty($email->template->readmore) ? acym_translation('ACYM_READ_MORE') : ' ';
+
+ if (!include_once(rtrim(JPATH_ADMINISTRATOR, DS).DS.'components'.DS.'com_hikashop'.DS.'helpers'.DS.'helper.php')) return;
+
+ $this->hikaConfig = hikashop_config();
+ $this->productClass = hikashop_get('class.product');
+ $this->imageHelper = hikashop_get('helper.image');
+ $this->currencyClass = hikashop_get('class.currency');
+ $this->translationHelper = hikashop_get('helper.translation');
+
+ $tagsReplaced = [];
+ foreach ($tags as $i => $oneTag) {
+ if (isset($tagsReplaced[$i])) continue;
+ $tagsReplaced[$i] = $this->_replaceContent($oneTag, $email);
+ }
+
+ $this->acympluginHelper->replaceTags($email, $tagsReplaced, true);
+ }
+
+ public function _replaceContent($tag, &$email)
+ {
+ if (empty($tag->lang) && !empty($email->language)) {
+ $tag->lang = $email->language;
+ }
+
+ $query = 'SELECT b.*, a.*
+ FROM #__hikashop_product AS a
+ LEFT JOIN #__hikashop_file AS b ON a.product_id = b.file_ref_id AND file_type = "product"
+ WHERE a.product_id = '.intval($tag->id).'
+ ORDER BY b.file_ordering ASC, b.file_id ASC';
+
+ $product = acym_loadObject($query);
+
+ if (empty($product)) {
+ if (acym_isAdmin()) {
+ acym_enqueueMessage('The product "'.$tag->id.'" could not be loaded', 'notice');
+ }
+
+ return '';
+ }
+
+ if ($product->product_type == 'variant') {
+ $query = 'SELECT *
+ FROM #__hikashop_variant AS a
+ LEFT JOIN #__hikashop__characteristic AS b ON a.variant_characteristic_id = b.characteristic_id
+ WHERE a.variant_product_id = '.intval($tag->id).'
+ ORDER BY a.ordering';
+ $product->characteristics = acym_loadObjectList($query);
+
+ $query = 'SELECT b.*, a.*
+ FROM #__hikashop_product AS a
+ LEFT JOIN #__hikashop_file AS b ON a.product_id = b.file_ref_id AND file_type = "product"
+ WHERE a.product_id = '.intval($product->product_parent_id).'
+ ORDER BY b.file_ordering ASC, b.file_id ASC';
+ $parentProduct = acym_loadObject($query);
+
+ $this->productClass->checkVariant($product, $parentProduct);
+ }
+
+ if ($this->translationHelper->isMulti(true, false)) {
+ $this->acympluginHelper->translateItem($product, $tag, 'hikashop_product');
+ }
+
+ $varFields = [];
+ foreach ($product as $fieldName => $oneField) {
+ $varFields['{'.$fieldName.'}'] = $oneField;
+ }
+
+ $tag->itemid = 0;
+ $main_currency = $currency_id = (int)$this->hikaConfig->get('main_currency', 1);
+ $zone_id = explode(',', $this->hikaConfig->get('main_tax_zone', 0));
+
+ $zone_id = count($zone_id) ? array_shift($zone_id) : 0;
+
+ $ids = [$product->product_id];
+ $discount_before_tax = (int)$this->hikaConfig->get('discount_before_tax', 0);
+ $this->currencyClass->getPrices($product, $ids, $currency_id, $main_currency, $zone_id, $discount_before_tax);
+ $finalPrice = '';
+ if (empty($tag->price) || $tag->price == 'full') {
+ $finalPrice = @$this->currencyClass->format($product->prices[0]->price_value_with_tax, $product->prices[0]->price_currency_id);
+ if (!empty($product->discount)) {
+ $finalPrice = ''.$this->currencyClass->format($product->prices[0]->price_value_without_discount_with_tax, $product->prices[0]->price_currency_id).' '.$finalPrice;
+ }
+ } elseif ($tag->price == 'no_discount') {
+ $finalPrice = $this->currencyClass->format($product->prices[0]->price_value_without_discount_with_tax, $product->prices[0]->price_currency_id);
+ }
+ $varFields['{finalPrice}'] = $finalPrice;
+
+ if (empty($tag->type) || $tag->type == 'full') {
+ $description = $product->product_description;
+ } else {
+ $pos = strpos($product->product_description, ' product_description, 0, $pos);
+ } else {
+ $description = substr($product->product_description, 0, 100).'...';
+ }
+ }
+
+ $link = 'index.php?option=com_hikashop&ctrl=product&task=show&cid='.$product->product_id;
+ if (!empty($tag->lang)) {
+ $link .= '&lang='.substr($tag->lang, 0, strpos($tag->lang, ','));
+ }
+ if (!empty($tag->itemid)) {
+ $link .= '&Itemid='.$tag->itemid;
+ }
+ if (!empty($product->product_canonical)) {
+ $link = $product->product_canonical;
+ }
+ $link = acym_frontendLink($link, false);
+ $varFields['{link}'] = $link;
+
+ $varFields['{pictHTML}'] = '';
+ if (!empty($product->file_path)) {
+ $img = $this->imageHelper->getThumbnail($product->file_path, null);
+ if ($img->success) {
+ $varFields['{pictHTML}'] = $img->url;
+ } else {
+ $varFields['{pictHTML}'] = $this->imageHelper->display($product->file_path, false, $product->product_name);
+ }
+ }
+ $varFields['{pictHTML}'] = ltrim($varFields['{pictHTML}'], './');
+
+ $title = $product->product_name;
+ if (!empty($finalPrice)) {
+ $title .= ' '.$finalPrice;
+ }
+
+ $picture = '';
+ $contentText = '';
+ if (empty($tag->type) || $tag->type != 'title') {
+ $picture = $varFields['{pictHTML}'];
+ $contentText = $description;
+ }
+
+ $format = new stdClass();
+ $format->tag = $tag;
+ $format->title = $title;
+ $format->afterTitle = '';
+ $format->afterArticle = '';
+ $format->imagePath = $picture;
+ $format->description = $contentText;
+ $format->link = $link;
+ $format->cols = empty($tag->nbcols) ? 1 : intval($tag->nbcols);
+ $format->customFields = [];
+ $result = ''.$this->acympluginHelper->getStandardDisplay($format).'
';
+
+ return $this->finalizeElementFormat($this->name, $result, $tag, $varFields);
+ }
+
+ public function replaceUserInformation(&$email, &$user, $send = true)
+ {
+ if (!include_once(rtrim(JPATH_ADMINISTRATOR, DS).DS.'components'.DS.'com_hikashop'.DS.'helpers'.DS.'helper.php')) return;
+
+ $this->hikaConfig = hikashop_config();
+
+ $this->_replaceAbandonedCarts($email, $user);
+ $this->_replaceCoupons($email, $user, $send);
+ }
+
+ public function _replaceAbandonedCarts(&$email, &$user)
+ {
+ $tags = $this->acympluginHelper->extractTags($email, 'hikashop_abandonedcart');
+ if (empty($tags)) {
+ return;
+ }
+
+ $tagsReplaced = [];
+ foreach ($tags as $i => $oneTag) {
+ if (isset($tagsReplaced[$i])) {
+ continue;
+ }
+ $tagsReplaced[$i] = $this->_replaceAbandonedCart($oneTag, $user);
+ }
+
+ $this->acympluginHelper->replaceTags($email, $tagsReplaced, true);
+
+ $this->_replaceOne($email);
+ }
+
+ public function _replaceAbandonedCart($oneTag, $user)
+ {
+ if (empty($user->cms_id)) {
+ return '';
+ }
+
+ $delay = 0;
+ if (!empty($oneTag->nbdayscart)) {
+ $delay = ($oneTag->nbdayscart * 86400);
+ }
+
+ $senddate = time() - intval($delay);
+
+ $createdstatus = $this->hikaConfig->get('order_created_status', 'created');
+
+ $myquery = 'SELECT c.product_id
+ FROM #__hikashop_order AS a
+ LEFT JOIN #__hikashop_order AS b
+ ON a.order_user_id = b.order_user_id
+ AND b.order_id > a.order_id
+ JOIN #__hikashop_order_product AS c
+ ON a.order_id = c.order_id
+ JOIN #__hikashop_user AS hikauser
+ ON a.order_user_id = hikauser.user_id ';
+
+ if (!empty($oneTag->paymentcart)) {
+ $myquery .= 'JOIN #__hikashop_payment AS payment
+ ON payment.payment_type = a.order_payment_method
+ AND payment.payment_id = '.intval($oneTag->paymentcart);
+ }
+
+ $myquery .= ' WHERE hikauser.user_cms_id = '.intval($user->cms_id).' AND a.order_status = '.acym_escapeDB($createdstatus).' AND b.order_id IS NULL ';
+ $myquery .= ' AND FROM_UNIXTIME(a.order_created,"%Y %d %m") = FROM_UNIXTIME('.$senddate.',"%Y %d %m")';
+
+ $allArticles = acym_loadResultArray($myquery);
+
+ return $this->finalizeCategoryFormat($this->name, $allArticles, $oneTag);
+ }
+
+ public function _replaceCoupons(&$email, &$user, $send = true)
+ {
+ $tags = $this->acympluginHelper->extractTags($email, 'hikashop_coupon');
+ if (empty($tags)) {
+ return;
+ }
+
+ $tagsReplaced = [];
+ foreach ($tags as $i => $oneTag) {
+ if (isset($tagsReplaced[$i])) {
+ continue;
+ }
+ if (!$send || empty($user->id)) {
+ $tagsReplaced[$i] = ''.acym_translation('ACYM_CHECK_EMAIL_COUPON').' ';
+ } else {
+ $tagsReplaced[$i] = $this->generateCoupon($oneTag, $user, $i);
+ }
+ }
+
+ $this->acympluginHelper->replaceTags($email, $tagsReplaced, true);
+ }
+
+ public function generateCoupon($tag, $user, $raw)
+ {
+ if (empty($tag->code)) {
+ list($minimum_order, $quota, $start, $end, $percent_amount, $flat_amount, $currency_id, $code, $product_id, $tax_id) = explode('|', $raw);
+ $minimum_order = substr($minimum_order, strpos($minimum_order, ':') + 1);
+ $tax_id = intval($tax_id);
+ } else {
+ $minimum_order = $tag->min;
+ $quota = $tag->quota;
+ $start = $tag->start;
+ $end = $tag->end;
+ $percent_amount = $tag->percent;
+ $flat_amount = $tag->flat;
+ $currency_id = $tag->currency;
+ $code = $tag->code;
+ $product_id = $tag->product;
+ $tax_id = $tag->tax;
+ }
+
+ $key = acym_generateKey(5);
+
+ if ($percent_amount > 0) {
+ $value = $percent_amount;
+ } else {
+ $value = $flat_amount;
+ }
+
+ $value = str_replace(',', '.', $value);
+
+ if ($start) {
+ $start = hikashop_getTime($start);
+ }
+ if ($end) {
+ $end = hikashop_getTime($end);
+ }
+
+ $clean_name = strtoupper($user->name);
+ $space = strpos($clean_name, ' ');
+ if (!empty($space)) {
+ $clean_name = substr($clean_name, 0, $space);
+ }
+
+ $code = str_replace(
+ [
+ '[name]',
+ '[clean_name]',
+ '[subid]',
+ '[email]',
+ '[key]',
+ '[flat]',
+ '[percent]',
+ '[value]',
+ '[prodid]',
+ ],
+ [
+ $user->name,
+ $clean_name,
+ $user->id,
+ $user->email,
+ $key,
+ $flat_amount,
+ $percent_amount,
+ $value,
+ $product_id,
+ ],
+ $code
+ );
+
+ $query = 'INSERT IGNORE INTO #__hikashop_discount (
+ `discount_code`,
+ `discount_percent_amount`,
+ `discount_flat_amount`,
+ `discount_type`,
+ `discount_start`,
+ `discount_end`,
+ `discount_minimum_order`,
+ `discount_quota`,
+ `discount_currency_id`,
+ `discount_product_id`,
+ `discount_tax_id`,
+ `discount_published`
+ ) VALUES (
+ '.acym_escapeDB($code).',
+ '.acym_escapeDB($percent_amount).',
+ '.acym_escapeDB($flat_amount).',
+ "coupon",
+ '.acym_escapeDB($start).',
+ '.acym_escapeDB($end).',
+ '.acym_escapeDB($minimum_order).',
+ '.acym_escapeDB($quota).',
+ '.acym_escapeDB($currency_id).',
+ '.acym_escapeDB($product_id).',
+ '.acym_escapeDB($tax_id).',
+ 1
+ )';
+
+ acym_query($query);
+
+ return $code;
+ }
+
+ public function searchProduct()
+ {
+ $id = acym_getVar('int', 'id');
+ if (!empty($id)) {
+ $value = '';
+ $element = acym_loadResult('SELECT `product_name` FROM #__hikashop_product WHERE `product_id` = '.intval($id));
+ if (!empty($element)) $value = $element;
+ echo json_encode(['value' => $value]);
+ exit;
+ }
+
+ $return = [];
+ $search = acym_getVar('cmd', 'search', '');
+ $products = acym_loadObjectList('SELECT `product_id`, `product_name` FROM `#__hikashop_product` WHERE `product_name` LIKE '.acym_escapeDB('%'.$search.'%').' ORDER BY `product_name`');
+
+ foreach ($products as $oneProduct) {
+ $return[] = [$oneProduct->product_id, $oneProduct->product_name];
+ }
+
+ echo json_encode($return);
+ exit;
+ }
+
+ public function onAcymDeclareConditions(&$conditions)
+ {
+ $categories = [
+ 'any' => acym_translation('ACYM_ANY_CATEGORY'),
+ ];
+ $cats = acym_loadObjectList('SELECT `category_id`, `category_name` FROM #__hikashop_category WHERE `category_type` = "product" ORDER BY `category_name`');
+ foreach ($cats as $oneCat) {
+ $categories[$oneCat->category_id] = $oneCat->category_name;
+ }
+
+ $conditions['user']['hikapurchased'] = new stdClass();
+ $conditions['user']['hikapurchased']->name = acym_translation_sprintf('ACYM_COMBINED_TRANSLATIONS', 'HikaShop', acym_translation('ACYM_PURCHASED'));
+ $conditions['user']['hikapurchased']->option = '';
+
+ $conditions['user']['hikapurchased']->option .= '
'.acym_translation('ACYM_BOUGHT').'
';
+
+ $conditions['user']['hikapurchased']->option .= '
';
+ $ajaxParams = json_encode(
+ [
+ 'plugin' => __CLASS__,
+ 'trigger' => 'searchProduct',
+ ]
+ );
+ $conditions['user']['hikapurchased']->option .= acym_select(
+ [],
+ 'acym_condition[conditions][__numor__][__numand__][hikapurchased][product]',
+ null,
+ 'class="acym__select acym_select2_ajax" data-placeholder="'.acym_translation('ACYM_AT_LEAST_ONE_PRODUCT', true).'" data-params="'.acym_escape($ajaxParams).'"'
+ );
+ $conditions['user']['hikapurchased']->option .= '
';
+
+ $conditions['user']['hikapurchased']->option .= '
';
+ $conditions['user']['hikapurchased']->option .= acym_select($categories, 'acym_condition[conditions][__numor__][__numand__][hikapurchased][category]', 'any', 'class="acym__select"');
+ $conditions['user']['hikapurchased']->option .= '
';
+
+ $conditions['user']['hikapurchased']->option .= '
';
+
+ $conditions['user']['hikapurchased']->option .= '';
+ $conditions['user']['hikapurchased']->option .= acym_dateField('acym_condition[conditions][__numor__][__numand__][hikapurchased][datemin]', '', 'cell shrink');
+ $conditions['user']['hikapurchased']->option .= '< ';
+ $conditions['user']['hikapurchased']->option .= ''.acym_translation('ACYM_DATE_CREATED').' ';
+ $conditions['user']['hikapurchased']->option .= '< ';
+ $conditions['user']['hikapurchased']->option .= acym_dateField('acym_condition[conditions][__numor__][__numand__][hikapurchased][datemax]', '', 'cell shrink');
+ $conditions['user']['hikapurchased']->option .= '
';
+
+
+ $orderStatuses = acym_loadObjectList('SELECT `orderstatus_id` AS value, `orderstatus_name` AS text FROM #__hikashop_orderstatus ORDER BY `orderstatus_name`');
+
+ $paymentMethods = ['any' => acym_translation('ACYM_ANY_PAYMENT_METHOD')];
+ $payments = acym_loadObjectList('SELECT `payment_id`, `payment_name` FROM #__hikashop_payment ORDER BY `payment_name`');
+ foreach ($payments as $oneMethod) {
+ $paymentMethods[$oneMethod->payment_id] = $oneMethod->payment_name;
+ }
+
+ $conditions['user']['hikareminder'] = new stdClass();
+ $conditions['user']['hikareminder']->name = acym_translation_sprintf('ACYM_COMBINED_TRANSLATIONS', 'HikaShop', acym_translation('ACYM_REMINDER'));
+ $conditions['user']['hikareminder']->option = '';
+ $conditions['user']['hikareminder']->option .= acym_translation_sprintf(
+ 'ACYM_ORDER_WITH_STATUS',
+ '
',
+ '
'.acym_select(
+ $orderStatuses,
+ 'acym_condition[conditions][__numor__][__numand__][hikareminder][status]',
+ null,
+ 'class="acym__select"'
+ ).'
'
+ );
+ $conditions['user']['hikareminder']->option .= '
';
+ $conditions['user']['hikareminder']->option .= acym_select(
+ $paymentMethods,
+ 'acym_condition[conditions][__numor__][__numand__][hikareminder][payment]',
+ 'any',
+ 'class="acym__select"'
+ );
+ $conditions['user']['hikareminder']->option .= '
';
+ $conditions['user']['hikareminder']->option .= '
';
+ }
+
+ public function onAcymProcessCondition_hikapurchased(&$query, $options, $num, &$conditionNotValid)
+ {
+ $this->processConditionFilter_hikapurchased($query, $options, $num);
+ $affectedRows = $query->count();
+ if (empty($affectedRows)) $conditionNotValid++;
+ }
+
+ private function processConditionFilter_hikapurchased(&$query, $options, $num)
+ {
+ $query->join['hikapurchased_order'.$num] = '#__hikashop_order AS order'.$num.' ON order'.$num.'.order_user_id = user.cms_id';
+
+ $query->where[] = 'order'.$num.'.order_user_id != 0';
+ $query->where[] = 'order'.$num.'.order_type = "sale"';
+ $query->where[] = 'order'.$num.'.order_status = "confirmed"';
+
+ if (!empty($options['datemin'])) {
+ $options['datemin'] = acym_replaceDate($options['datemin']);
+ if (!is_numeric($options['datemin'])) $options['datemin'] = strtotime($options['datemin']);
+ if (!empty($options['datemin'])) {
+ $query->where[] = 'order'.$num.'.order_created > '.acym_escapeDB($options['datemin']);
+ }
+ }
+
+ if (!empty($options['datemax'])) {
+ $options['datemax'] = acym_replaceDate($options['datemax']);
+ if (!is_numeric($options['datemax'])) $options['datemax'] = strtotime($options['datemax']);
+ if (!empty($options['datemax'])) {
+ $query->where[] = 'order'.$num.'.order_created < '.acym_escapeDB($options['datemax']);
+ }
+ }
+
+ if (!empty($options['product'])) {
+ $query->join['hikapurchased_order_product'.$num] = '#__hikashop_order_product AS hikaop'.$num.' ON order'.$num.'.order_id = hikaop'.$num.'.order_id';
+ $query->where[] = 'hikaop'.$num.'.product_id = '.intval($options['product']);
+ } elseif (!empty($options['category']) && $options['category'] != 'any') {
+ $query->join['hikapurchased_order_product'.$num] = '#__hikashop_order_product AS hikaop'.$num.' ON order'.$num.'.order_id = hikaop'.$num.'.order_id';
+ $query->join['hikapurchased_order_cat'.$num] = '#__hikashop_product_category AS hikapc'.$num.' ON hikaop'.$num.'.product_id = hikapc'.$num.'.product_id';
+ $query->where[] = 'hikapc'.$num.'.category_id = '.intval($options['category']);
+ }
+ }
+
+ public function onAcymProcessCondition_hikareminder(&$query, $options, $num, &$conditionNotValid)
+ {
+ $this->processConditionFilter_hikareminder($query, $options, $num);
+ $affectedRows = $query->count();
+ if (empty($affectedRows)) $conditionNotValid++;
+ }
+
+ private function processConditionFilter_hikareminder(&$query, $options, $num)
+ {
+ $options['days'] = intval($options['days']);
+
+ $query->join['hikareminder_order'.$num] = '#__hikashop_order AS order'.$num.' ON order'.$num.'.order_user_id = user.cms_id';
+ $query->where[] = 'order'.$num.'.order_user_id != 0';
+ $query->where[] = 'order'.$num.'.order_type = "sale"';
+ $query->where[] = 'order'.$num.'.order_status = '.acym_escapeDB($options['status']);
+
+ $query->where[] = 'FROM_UNIXTIME(order'.$num.'.order_created, "%Y-%m-%d") = '.acym_escapeDB(date('Y-m-d', time() - ($options['days'] * 86400)));
+
+ if (!empty($options['payment']) && $options['payment'] != 'any') {
+ $query->where[] = 'order'.$num.'.order_payment_id = '.intval($options['payment']);
+ }
+ }
+
+ public function onAcymDeclareSummary_conditions(&$automationCondition)
+ {
+ $this->summaryConditionFilters($automationCondition);
+ }
+
+ private function summaryConditionFilters(&$automationCondition)
+ {
+ if (!empty($automationCondition['hikapurchased'])) {
+ if (empty($automationCondition['hikapurchased']['product'])) {
+ $product = acym_translation('ACYM_AT_LEAST_ONE_PRODUCT');
+ } else {
+ $product = acym_loadResult('SELECT `product_name` FROM #__hikashop_product WHERE `product_id` = '.intval($automationCondition['hikapurchased']['product']));
+ }
+
+ $cats = acym_loadObjectList('SELECT `category_id`, `category_name` FROM #__hikashop_category WHERE `category_type` = "product"', 'category_id');
+ $category = empty($cats[$automationCondition['hikapurchased']['category']]) ? acym_translation('ACYM_ANY_CATEGORY') : $cats[$automationCondition['hikapurchased']['category']]->category_name;
+
+ $finalText = acym_translation_sprintf('ACYM_CONDITION_PURCHASED', $product, $category);
+
+ $dates = [];
+ if (!empty($automationCondition['hikapurchased']['datemin'])) {
+ $dates[] = acym_translation('ACYM_AFTER').' '.acym_replaceDate($automationCondition['hikapurchased']['datemin'], true);
+ }
+
+ if (!empty($automationCondition['hikapurchased']['datemax'])) {
+ $dates[] = acym_translation('ACYM_BEFORE').' '.acym_replaceDate($automationCondition['hikapurchased']['datemax'], true);
+ }
+
+ if (!empty($dates)) {
+ $finalText .= ' '.implode(' '.acym_translation('ACYM_AND').' ', $dates);
+ }
+
+ $automationCondition = $finalText;
+ }
+
+ if (!empty($automationCondition['hikareminder'])) {
+
+ $orderStatuses = acym_loadObjectList('SELECT `orderstatus_id`, `orderstatus_name` FROM #__hikashop_orderstatus', 'orderstatus_id');
+ $paymentMethods = acym_loadObjectList('SELECT `payment_id`, `payment_name` FROM #__hikashop_payment', 'payment_id');
+
+ $paymentName = @$paymentMethods[$automationCondition['hikareminder']['payment']]->payment_name;
+ if (empty($paymentName)) $paymentName = 'ACYM_ANY_PAYMENT_METHOD';
+ $automationCondition = acym_translation_sprintf(
+ 'ACYM_CONDITION_ECOMMERCE_REMINDER',
+ acym_translation($paymentName),
+ intval($automationCondition['hikareminder']['days']),
+ $orderStatuses[$automationCondition['hikareminder']['status']]->orderstatus_name
+ );
+ }
+ }
+
+ public function onAcymDeclareFilters(&$filters)
+ {
+ $newFilters = [];
+
+ $this->onAcymDeclareConditions($newFilters);
+ foreach ($newFilters as $oneType) {
+ foreach ($oneType as $oneFilterName => $oneFilter) {
+ if (!empty($oneFilter->option)) $oneFilter->option = str_replace(['acym_condition', '[conditions]'], ['acym_action', '[filters]'], $oneFilter->option);
+ $filters[$oneFilterName] = $oneFilter;
+ }
+ }
+ }
+
+ public function onAcymProcessFilterCount_hikapurchased(&$query, $options, $num)
+ {
+ $this->onAcymProcessFilter_hikapurchased($query, $options, $num);
+
+ return acym_translation_sprintf('ACYM_SELECTED_USERS', $query->count());
+ }
+
+ public function onAcymProcessFilter_hikapurchased(&$query, $options, $num)
+ {
+ $this->processConditionFilter_hikapurchased($query, $options, $num);
+ }
+
+ public function onAcymProcessFilterCount_hikareminder(&$query, $options, $num)
+ {
+ $this->onAcymProcessFilter_hikareminder($query, $options, $num);
+
+ return acym_translation_sprintf('ACYM_SELECTED_USERS', $query->count());
+ }
+
+ public function onAcymProcessFilter_hikareminder(&$query, $options, $num)
+ {
+ $this->processConditionFilter_hikareminder($query, $options, $num);
+ }
+
+ public function onAcymDeclareSummary_filters(&$automationFilter)
+ {
+ $this->summaryConditionFilters($automationFilter);
+ }
+
+ public function onAcymDeclareTriggers(&$triggers, &$defaultValues)
+ {
+ if (!include_once rtrim(JPATH_ADMINISTRATOR, DS).DS.'components'.DS.'com_hikashop'.DS.'helpers'.DS.'helper.php') return;
+
+ $statusClass = hikashop_get('type.categorysub');
+ $statusClass->type = 'status';
+ $statusClass->load();
+
+ if (empty($statusClass->categories)) return;
+
+ $triggers['user']['hikashoporder'] = new stdClass();
+ $triggers['user']['hikashoporder']->name = acym_translation_sprintf('ACYM_ORDER_STATUS_CHANGED', 'HikaShop', '');
+
+ $cats = [];
+ foreach ($statusClass->categories as $category) {
+ if (empty($category->value)) {
+ $val = str_replace(' ', '_', strtoupper($category->category_name));
+ $category->value = acym_translation($val);
+ if ($val == $category->value) {
+ $category->value = $category->category_name;
+ }
+ }
+ $cats[$category->value] = $category->value;
+ }
+
+ $selectedValue = empty($defaultValues['hikashoporder']['status']) ? [] : $defaultValues['hikashoporder']['status'];
+ $triggers['user']['hikashoporder']->option = acym_selectMultiple(
+ $cats,
+ '[triggers][user][hikashoporder][status]',
+ $selectedValue,
+ ['data-class' => 'acym__select']
+ );
+ }
+
+ public function onAcymExecuteTrigger(&$step, &$execute, $data)
+ {
+ if (empty($data['userId'])) return;
+
+ $triggers = json_decode($step->triggers, true);
+
+ if (!empty($triggers['hikashoporder']) && !empty($data['order'])) {
+ if (!empty($triggers['hikashoporder']) && in_array($data['order']->order_status, $triggers['hikashoporder']['status'])) {
+ $execute = true;
+ }
+ }
+ }
+
+ public function onAfterOrderUpdate(&$order)
+ {
+ if (empty($order->order_id) || empty($order->order_status)) return;
+
+ if (empty($order->order_user_id)) {
+ $class = hikashop_get('class.order');
+ $old = $class->get($order->order_id);
+ if (empty($old)) return;
+ $order->order_user_id = $old->order_user_id;
+ }
+ $hikaUserClass = hikashop_get('class.user');
+ $hikaUser = $hikaUserClass->get($order->order_user_id);
+ if (empty($hikaUser)) return;
+
+ $userClass = acym_get('class.user');
+ $user = $userClass->getOneByEmail($hikaUser->email);
+ if (empty($user->id)) return;
+
+ $automationClass = acym_get('class.automation');
+ $automationClass->trigger(
+ 'hikashoporder',
+ [
+ 'userId' => $user->id,
+ 'order' => $order,
+ ]
+ );
+ }
+
+ function onAcymDeclareSummary_triggers(&$automation)
+ {
+ if (!empty($automation->triggers['hikashoporder']['status'])) {
+ $status = implode(', ', $automation->triggers['hikashoporder']['status']);
+ $automation->triggers['hikashoporder'] = acym_translation_sprintf('ACYM_ORDER_STATUS_CHANGED', 'HikaShop', $status);
+ }
+ }
+}
+
diff --git a/deployed/acym/administrator/components/com_acym/dynamics/index.html b/deployed/acym/administrator/components/com_acym/dynamics/index.html
new file mode 100644
index 00000000..fa6d84e8
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/dynamics/index.html
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/deployed/acym/administrator/components/com_acym/dynamics/jevents/icon.ico b/deployed/acym/administrator/components/com_acym/dynamics/jevents/icon.ico
new file mode 100644
index 00000000..07b6354b
Binary files /dev/null and b/deployed/acym/administrator/components/com_acym/dynamics/jevents/icon.ico differ
diff --git a/deployed/acym/administrator/components/com_acym/dynamics/jevents/index.html b/deployed/acym/administrator/components/com_acym/dynamics/jevents/index.html
new file mode 100644
index 00000000..fa6d84e8
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/dynamics/jevents/index.html
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/deployed/acym/administrator/components/com_acym/dynamics/jevents/plugin.php b/deployed/acym/administrator/components/com_acym/dynamics/jevents/plugin.php
new file mode 100644
index 00000000..ffe94cb5
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/dynamics/jevents/plugin.php
@@ -0,0 +1,872 @@
+cms = 'Joomla';
+ if (!defined('JPATH_ADMINISTRATOR') || !file_exists(rtrim(JPATH_ADMINISTRATOR, DS).DS.'components'.DS.'com_jevents'.DS)) {
+ $this->installed = false;
+ }
+ $this->name = 'jevents';
+ }
+
+ public function insertOptions()
+ {
+ $plugin = new stdClass();
+ $plugin->name = 'JEvents';
+ $plugin->icon = ACYM_DYNAMICS_URL.basename(__DIR__).'/icon.ico';
+ $plugin->plugin = __CLASS__;
+
+ return $plugin;
+ }
+
+ public function contentPopup()
+ {
+ acym_loadLanguageFile('com_jevents', JPATH_SITE);
+
+ $this->categories = acym_loadObjectList('SELECT id, parent_id, title FROM `#__categories` WHERE extension = "com_jevents"', 'id');
+
+ $tabHelper = acym_get('helper.tab');
+ $tabHelper->startTab(acym_translation('ACYM_ONE_BY_ONE'));
+
+ $displayOptions = [
+ [
+ 'title' => 'ACYM_DISPLAY',
+ 'type' => 'radio',
+ 'name' => 'type',
+ 'options' => [
+ 'title' => 'ACYM_TITLE_ONLY',
+ 'full' => 'ACYM_FULL_TEXT',
+ ],
+ 'default' => 'full',
+ ],
+ [
+ 'title' => 'ACYM_CLICKABLE_TITLE',
+ 'type' => 'boolean',
+ 'name' => 'clickable',
+ 'default' => true,
+ ],
+ [
+ 'title' => 'ACYM_READ_MORE',
+ 'type' => 'boolean',
+ 'name' => 'readmore',
+ 'default' => true,
+ ],
+ [
+ 'title' => 'ACYM_TRUNCATE',
+ 'type' => 'intextfield',
+ 'name' => 'wrap',
+ 'text' => 'ACYM_TRUNCATE_AFTER',
+ 'default' => 0,
+ ],
+ [
+ 'title' => 'ACYM_DISPLAY_PICTURES',
+ 'type' => 'pictures',
+ 'name' => 'pictures',
+ ],
+ ];
+
+ if (file_exists(JPATH_SITE.DS.'plugins'.DS.'jevents'.DS.'jevfiles'.DS.'jevfiles.php')) {
+ $displayOptions[] = [
+ 'title' => 'ACY_FILES',
+ 'type' => 'boolean',
+ 'name' => 'pluginFields',
+ 'default' => true,
+ ];
+ }
+
+ if (file_exists(JPATH_SITE.DS.'plugins'.DS.'jevents'.DS.'jevcustomfields')) {
+ $jevCFParams = acym_loadObject('SELECT params FROM #__extensions WHERE element = "jevcustomfields"');
+ if (!empty($jevCFParams->params)) {
+ $template = json_decode($jevCFParams->params)->template;
+ }
+ if (!empty($template)) {
+ $xmlfile = JPATH_SITE.DS.'plugins'.DS.'jevents'.DS.'jevcustomfields'.DS.'customfields'.DS.'templates'.DS.$template;
+ if (file_exists($xmlfile)) {
+ $xml = simplexml_load_file($xmlfile);
+ $jevCf = $xml->xpath('//fields/fieldset/field');
+ }
+ }
+
+ if (!empty($jevCf)) {
+ $customField = [
+ 'title' => 'ACYM_FIELDS_TO_DISPLAY',
+ 'type' => 'checkbox',
+ 'name' => 'custom',
+ 'separator' => ', ',
+ 'options' => [],
+ ];
+ foreach ($jevCf as $oneParam) {
+ $name = $oneParam->attributes()->name;
+ $label = $oneParam->attributes()->label;
+ if (!empty($name) && !empty($label)) {
+ $customField['options'][$name] = [$label, false];
+ }
+ }
+
+ $displayOptions[] = $customField;
+ }
+ }
+
+ echo $this->acympluginHelper->displayOptions($displayOptions, $this->name);
+
+ echo $this->getFilteringZone();
+
+ $this->displayListing();
+
+ $tabHelper->endTab();
+ $tabHelper->startTab(acym_translation('ACYM_BY_CATEGORY'));
+
+ $catOptions = [
+ [
+ 'title' => 'ACYM_COLUMNS',
+ 'type' => 'text',
+ 'name' => 'cols',
+ 'default' => 1,
+ ],
+ [
+ 'title' => 'ACYM_MAX_NB_ELEMENTS',
+ 'type' => 'text',
+ 'name' => 'max',
+ 'default' => 20,
+ ],
+ [
+ 'title' => 'ACYM_ORDER_BY',
+ 'type' => 'select',
+ 'name' => 'order',
+ 'options' => [
+ 'id' => 'ACYM_ID',
+ 'startrepeat' => 'JEV_EVENT_STARTDATE',
+ 'endrepeat' => 'JEV_EVENT_ENDDATE',
+ 'summary' => 'ACYM_TITLE',
+ 'rand' => 'ACYM_RANDOM',
+ ],
+ 'default' => 'startrepeat',
+ 'defaultdir' => 'asc',
+ ],
+ [
+ 'title' => 'ACYM_FROM',
+ 'type' => 'date',
+ 'name' => 'from',
+ 'default' => date('Y-m-d'),
+ 'relativeDate' => '+',
+ ],
+ [
+ 'title' => 'ACYM_TO',
+ 'type' => 'date',
+ 'name' => 'to',
+ 'default' => '',
+ 'relativeDate' => '+',
+ ],
+ ];
+
+ if (file_exists(JPATH_ADMINISTRATOR.DS.'components'.DS.'com_jevlocations')) {
+ $locs = acym_loadObjectList('SELECT loc_id, title, city, state, country FROM #__jev_locations');
+
+ if (!empty($locs)) {
+ $allCities = [0 => 'ACYM_ALL'];
+ $allStates = [0 => 'ACYM_ALL'];
+ $allCountries = [0 => 'ACYM_ALL'];
+ $locations = [0 => 'ACYM_ALL'];
+ foreach ($locs as $oneLoc) {
+ $locations[$oneLoc->loc_id] = $oneLoc->title;
+
+ if (!empty($oneLoc->city)) $allCities[$oneLoc->city] = $oneLoc->city;
+ if (!empty($oneLoc->state)) $allStates[$oneLoc->state] = $oneLoc->state;
+ if (!empty($oneLoc->country)) $allCountries[$oneLoc->country] = $oneLoc->country;
+ }
+
+ $catOptions[] = [
+ 'title' => 'ACYM_LOCATION',
+ 'type' => 'select',
+ 'name' => 'location',
+ 'options' => $locations,
+ ];
+
+ $catOptions[] = [
+ 'title' => 'ACYM_COUNTRY',
+ 'type' => 'select',
+ 'name' => 'country',
+ 'options' => $allCountries,
+ ];
+
+ $catOptions[] = [
+ 'title' => 'ACYM_STATE',
+ 'type' => 'select',
+ 'name' => 'state',
+ 'options' => $allStates,
+ ];
+
+ $catOptions[] = [
+ 'title' => 'ACYM_CITY',
+ 'type' => 'select',
+ 'name' => 'city',
+ 'options' => $allCities,
+ ];
+ }
+ }
+
+ $displayOptions = array_merge($displayOptions, $catOptions);
+
+ echo $this->acympluginHelper->displayOptions($displayOptions, 'auto'.$this->name, 'grouped');
+
+ echo $this->getCategoryListing();
+
+ $tabHelper->endTab();
+
+ $tabHelper->display('plugin');
+ }
+
+ public function displayListing()
+ {
+ $querySelect = 'SELECT rpt.*, detail.*, cat.title AS cattitle ';
+ $query = 'FROM `#__jevents_repetition` AS rpt ';
+ $query .= 'JOIN `#__jevents_vevent` AS ev ON rpt.eventid = ev.ev_id ';
+ $query .= 'JOIN `#__categories` AS cat ON ev.catid = cat.id ';
+ $query .= 'JOIN `#__jevents_vevdetail` AS detail ON ev.detail_id = detail.evdet_id ';
+ $filters = [];
+
+ $this->pageInfo = new stdClass();
+ $this->pageInfo->limit = acym_getCMSConfig('list_limit');
+ $this->pageInfo->page = acym_getVar('int', 'pagination_page_ajax', 1);
+ $this->pageInfo->start = ($this->pageInfo->page - 1) * $this->pageInfo->limit;
+ $this->pageInfo->search = acym_getVar('string', 'plugin_search', '');
+ $this->pageInfo->filter_cat = acym_getVar('int', 'plugin_category', 0);
+ $this->pageInfo->order = 'rpt.startrepeat';
+ $this->pageInfo->orderdir = 'DESC';
+
+ $searchFields = ['rpt.rp_id', 'detail.evdet_id', 'detail.description', 'detail.summary', 'detail.contact', 'detail.location'];
+ if (!empty($this->pageInfo->search)) {
+ $searchVal = '%'.acym_getEscaped($this->pageInfo->search, true).'%';
+ $filters[] = implode(" LIKE ".acym_escapeDB($searchVal)." OR ", $searchFields)." LIKE ".acym_escapeDB($searchVal);
+ }
+
+ if (!empty($this->pageInfo->filter_cat)) {
+ $filters[] = "ev.catid = ".intval($this->pageInfo->filter_cat);
+ }
+
+ if (!empty($filters)) {
+ $query .= ' WHERE ('.implode(') AND (', $filters).')';
+ }
+
+ if (!empty($this->pageInfo->order)) {
+ $query .= ' ORDER BY '.acym_secureDBColumn($this->pageInfo->order).' '.acym_secureDBColumn($this->pageInfo->orderdir);
+ }
+
+ $rows = acym_loadObjectList($querySelect.$query, '', $this->pageInfo->start, $this->pageInfo->limit);
+ $this->pageInfo->total = acym_loadResult('SELECT COUNT(*) '.$query);
+
+
+ $listingOptions = [
+ 'header' => [
+ 'summary' => [
+ 'label' => 'ACYM_TITLE',
+ 'size' => '5',
+ ],
+ 'startrepeat' => [
+ 'label' => 'ACYM_DATE',
+ 'size' => '3',
+ 'type' => 'date',
+ ],
+ 'cattitle' => [
+ 'label' => 'ACYM_CATEGORY',
+ 'size' => '3',
+ ],
+ 'rp_id' => [
+ 'label' => 'ACYM_ID',
+ 'size' => '1',
+ 'class' => 'text-center',
+ ],
+ ],
+ 'id' => 'rp_id',
+ 'rows' => $rows,
+ ];
+
+ echo $this->getElementsListing($listingOptions);
+ }
+
+ public function replaceContent(&$email)
+ {
+ $this->_replaceAuto($email);
+ $this->_replaceOne($email);
+ }
+
+ public function _replaceAuto(&$email)
+ {
+ $this->generateByCategory($email);
+ if (empty($this->tags)) return;
+ $this->acympluginHelper->replaceTags($email, $this->tags, true);
+ }
+
+ public function generateByCategory(&$email)
+ {
+ $time = time();
+
+ $tags = $this->acympluginHelper->extractTags($email, 'auto'.$this->name);
+ $return = new stdClass();
+ $return->status = true;
+ $return->message = '';
+ $this->tags = [];
+
+ if (empty($tags)) return $return;
+
+ $multicat = JComponentHelper::getParams('com_jevents')->get('multicategory', 0);
+
+ foreach ($tags as $oneTag => $parameter) {
+ if (isset($this->tags[$oneTag])) continue;
+
+ $where = [];
+ $where[] = 'ev.`state` = 1';
+
+ $query = 'SELECT DISTINCT rpt.rp_id FROM `#__jevents_repetition` AS rpt ';
+ $query .= ' JOIN `#__jevents_vevent` AS ev ON rpt.eventid = ev.ev_id ';
+
+ if (empty($parameter->order)) $parameter->order = 'startrepeat,ASC';
+ if (empty($parameter->from)) {
+ $parameter->from = date('Y-m-d H:i:s', $time);
+ } else {
+ $parameter->from = acym_date(acym_replaceDate($parameter->from), 'Y-m-d H:i:s');
+ }
+ if (!empty($parameter->to)) $parameter->to = acym_date(acym_replaceDate($parameter->to), 'Y-m-d H:i:s');
+
+ if (!empty($parameter->id)) {
+ $allCats = explode('-', $parameter->id);
+ array_pop($allCats);
+ if (!empty($allCats)) {
+ acym_arrayToInteger($allCats);
+ $catToSearch = implode(',', $allCats);
+ if ($multicat == 1) {
+ $query .= ' JOIN `#__jevents_catmap` AS cats ON ev.ev_id = cats.evid ';
+ $where[] = 'cats.catid IN ('.$catToSearch.')';
+ } else {
+ $where[] = 'ev.catid IN ('.$catToSearch.')';
+ }
+ }
+ }
+
+ $locationColumn = '';
+ if (empty($parameter->location)) {
+ if (!empty($parameter->country)) $locationColumn = 'country';
+ if (!empty($parameter->state)) $locationColumn = 'state';
+ if (!empty($parameter->city)) $locationColumn = 'city';
+ }
+
+ if (isset($parameter->priority) || !empty($parameter->location) || !empty($locationColumn) || strpos($parameter->order, 'summary') !== false) {
+ $query .= ' JOIN `#__jevents_vevdetail` AS evdet ON ev.detail_id = evdet.evdet_id ';
+ }
+
+ if (!empty($locationColumn)) {
+ $query .= ' JOIN `#__jev_locations` AS evloc ON evdet.location = evloc.loc_id';
+ $where[] = 'evloc.'.$locationColumn.' = '.acym_escapeDB($parameter->$locationColumn);
+ }
+
+ if (!empty($parameter->location)) {
+ $where[] = 'evdet.location = '.intval($parameter->location);
+ }
+
+ if (isset($parameter->priority)) {
+ $parameter->priority = explode(',', $parameter->priority);
+ acym_arrayToInteger($parameter->priority);
+ $where[] = 'evdet.priority IN ('.implode(',', $parameter->priority).')';
+ }
+
+ if ((empty($parameter->mindelay) || substr($parameter->mindelay, 0, 1) != '-') && (empty($parameter->delay) || substr($parameter->delay, 0, 1) != '-')) {
+ if (!empty($parameter->addcurrent)) {
+ $where[] = 'rpt.`endrepeat` >= '.acym_escapeDB($parameter->from);
+ } else {
+ $where[] = 'rpt.`startrepeat` >= '.acym_escapeDB($parameter->from);
+ }
+ }
+
+ if (!empty($parameter->todaysevent)) {
+ $where[] = 'rpt.`startrepeat` <= '.acym_escapeDB(date('Y-m-d 23:59:59', $time));
+ }
+
+ if (!empty($parameter->mindelay)) $where[] = 'rpt.`startrepeat` >= '.acym_escapeDB(date('Y-m-d H:i:s', $time + $parameter->mindelay));
+ if (!empty($parameter->delay)) $where[] = 'rpt.`startrepeat` <= '.acym_escapeDB(date('Y-m-d H:i:s', $time + $parameter->delay));
+ if (!empty($parameter->to)) $where[] = 'rpt.`startrepeat` <= '.acym_escapeDB($parameter->to);
+
+ if (isset($parameter->access)) {
+ $where[] = 'ev.`access` = '.intval($parameter->access);
+ }
+
+ $query .= ' WHERE ('.implode(') AND (', $where).')';
+
+ $ordering = explode(',', $parameter->order);
+ if ($ordering[0] == 'rand') {
+ $query .= ' ORDER BY rand()';
+ } else {
+ $query .= ' ORDER BY '.acym_secureDBColumn(trim($ordering[0])).' '.acym_secureDBColumn(trim($ordering[1]));
+ }
+
+ if (!empty($parameter->max)) $query .= ' LIMIT '.intval($parameter->max);
+
+ $allArticles = acym_loadResultArray($query);
+
+ if (!empty($parameter->min) && count($allArticles) < $parameter->min) {
+ $return->status = false;
+ $return->message = 'Not enough events for the tag '.$oneTag.' : '.count($allArticles).' / '.$parameter->min;
+ }
+
+ $this->tags[$oneTag] = $this->finalizeCategoryFormat($this->name, $allArticles, $parameter);
+ }
+
+ return $return;
+ }
+
+ public function _replaceOne(&$email)
+ {
+ $tags = $this->acympluginHelper->extractTags($email, $this->name);
+ if (empty($tags)) return;
+
+ acym_loadLanguageFile('com_jevents', JPATH_SITE);
+
+ if (file_exists(JPATH_SITE.DS.'plugins'.DS.'jevents'.DS.'jevfiles'.DS.'jevfiles.php')) {
+ $JEVplugin = JPluginHelper::getPlugin('jevents', 'jevfiles');
+ $JEVparams = new acymParameter($JEVplugin->params);
+ $imagesFolder = JComponentHelper::getParams('com_media')->get('image_path', 'images');
+ $this->imgFolder = ACYM_LIVE.$imagesFolder.'/'.trim($JEVparams->get('folder', 'jevents'), '/').'/';
+ }
+
+ $this->useStdTime = JComponentHelper::getParams("com_jevents")->get('com_calUseStdTime');
+
+ $tagsReplaced = [];
+ foreach ($tags as $i => $params) {
+ if (isset($tagsReplaced[$i])) continue;
+
+ $tagsReplaced[$i] = $this->_replaceContent($tags[$i]);
+ }
+
+ $this->acympluginHelper->replaceTags($email, $tagsReplaced, true);
+ }
+
+ public function _replaceContent(&$tag)
+ {
+ $query = 'SELECT rpt.*, detail.*, cat.title AS category, ev.catid, ev.uid FROM `#__jevents_repetition` AS rpt ';
+ $query .= ' JOIN `#__jevents_vevent` AS ev ON rpt.eventid = ev.ev_id ';
+ $query .= ' JOIN `#__jevents_vevdetail` AS detail ON rpt.eventdetail_id = detail.evdet_id ';
+ $query .= 'LEFT JOIN `#__categories` AS cat ON cat.id = ev.catid ';
+ $query .= 'WHERE rpt.rp_id = '.intval($tag->id).' LIMIT 1';
+
+ $element = acym_loadObject($query);
+
+ if (empty($element)) {
+ if (acym_isAdmin()) acym_enqueueMessage('The event "'.$tag->id.'" could not be loaded', 'notice');
+
+ return '';
+ }
+
+ $this->acympluginHelper->translateItem($element, $tag, 'jevents_vevdetail', $element->evdet_id);
+
+ if (file_exists(JPATH_ADMINISTRATOR.DS.'components'.DS.'com_jevlocations') && !empty($element->location) && is_numeric($element->location)) {
+ $query = 'SELECT title, street, postcode, city, state, country FROM `#__jev_locations` WHERE loc_id = '.intval($element->location);
+ $location = acym_loadObject($query);
+ if (!empty($location)) {
+ foreach ($location as $prop => $value) {
+ $element->$prop = $value;
+ }
+ $element->location = $location->title;
+ }
+ }
+
+ $varFields = [];
+ foreach ($element as $fieldName => $oneField) {
+ $varFields['{'.$fieldName.'}'] = $oneField;
+ }
+
+ $startdate = acym_date($element->startrepeat, acym_translation('ACYM_DATE_FORMAT_LC1'), null);
+ $enddate = acym_date($element->endrepeat, acym_translation('ACYM_DATE_FORMAT_LC1'), null);
+ $starttime = substr($element->startrepeat, 11, 5);
+ $endtime = substr($element->endrepeat, 11, 5);
+
+ if ($starttime == '00:00') {
+ $starttime = '';
+ $endtime = '';
+ } elseif ($element->noendtime) {
+ $endtime = '';
+ }
+
+ if (!empty($this->useStdTime)) {
+ if (!empty($starttime)) $starttime = strtolower(strftime("%#I:%M%p", strtotime($element->startrepeat)));
+ if (!empty($endtime)) $endtime = strtolower(strftime("%#I:%M%p", strtotime($element->endrepeat)));
+ }
+
+ $date = $startdate;
+ if (!empty($starttime)) $date .= ' '.$starttime;
+ if ($startdate == $enddate) {
+ if (!empty($endtime)) $date .= ' - '.$endtime;
+ } else {
+ $date .= ' - '.$enddate;
+ if (!empty($endtime)) $date .= ' '.$endtime;
+ }
+ $varFields['{date}'] = $date;
+
+
+ $link = ACYM_LIVE.'index.php?option=com_jevents&task=icalrepeat.detail&evid='.intval($element->rp_id);
+ if (empty($tag->itemid)) {
+ $areaCats = [];
+ $areaCats[] = $element->catid;
+ $cats = acym_loadObjectList('SELECT id, parent_id FROM #__categories', 'id');
+ $position = $element->catid;
+
+ while ($cats[$position]->parent_id != 0) {
+ $areaCats[] = $cats[$position]->parent_id;
+ $position = $cats[$position]->parent_id;
+ }
+
+ $menuId = '';
+ $menus = acym_loadObjectList('SELECT id, params FROM #__menu WHERE link LIKE "index.php?option=com_jevents&view=cat&layout=listevents"');
+ if (!empty($menus)) {
+ foreach ($menus as $i => $menu) {
+ $menus[$i]->params = json_decode($menus[$i]->params);
+ if (empty($menus[$i]->params->catidnew)) continue;
+ foreach ($menus[$i]->params->catidnew as $oneCatid) {
+ if (in_array($oneCatid, $areaCats)) {
+ $menuId = $menus[$i]->id;
+ break;
+ }
+ }
+ if ($menuId != '') break;
+ }
+ }
+
+ if (empty($menuId)) {
+ $summary = str_replace('-', ' ', $element->summary);
+ $summary = trim(strtolower($summary));
+ $summary = preg_replace('/(\s|[^A-Za-z0-9\-])+/', '-', $summary);
+ $summary = trim($summary, '-');
+ $time = explode('-', substr($element->startrepeat, 0, strpos($element->startrepeat, ' ')));
+ $link = 'index.php?option=com_jevents&task=icalrepeat.detail&evid='.intval($element->rp_id).'&year='.intval($time[0]).'&month='.intval($time[1]).'&day='.intval($time[2]).'&title='.$summary.'&uid='.$element->uid;
+ } else {
+ $link .= '&Itemid='.intval($menuId);
+ }
+ } else {
+ $link .= '&Itemid='.intval($tag->itemid);
+ }
+
+ if (!empty($tag->lang)) $link .= '&lang='.substr($tag->lang, 0, strpos($tag->lang, ','));
+ $varFields['{link}'] = $link;
+
+ $title = $element->summary;
+
+ $afterTitle = '';
+ $afterArticle = '';
+
+ $imagePath = '';
+ $contentText = $element->description;
+ $customFields = [];
+
+ if ($tag->type == 'full') {
+ $customFields[] = [$date];
+
+ if (!empty($element->location)) $customFields[] = [$element->location, acym_translation('ACYM_ADDRESS')];
+
+ if (!empty($tag->custom)) {
+ $tag->custom = explode(',', $tag->custom);
+ foreach ($tag->custom as $i => $oneField) {
+ $tag->custom[$i] = trim($oneField);
+ }
+
+ $jevCFParams = acym_loadObject('SELECT params FROM #__extensions WHERE element = "jevcustomfields"');
+ if (!empty($jevCFParams->params)) $template = json_decode($jevCFParams->params)->template;
+
+ if (!empty($template)) {
+ $xmlfile = JPATH_SITE.DS.'plugins'.DS.'jevents'.DS.'jevcustomfields'.DS.'customfields'.DS.'templates'.DS.$template;
+ if (file_exists($xmlfile)) {
+ $xml = simplexml_load_file($xmlfile);
+ $jevCf = $xml->xpath('//fields/fieldset/field');
+ $jevCustomFields = [];
+ foreach ($jevCf as $i => $oneField) {
+ $name = (string)$oneField->attributes()->name;
+ $jevCustomFields[$name] = new stdClass();
+ $jevCustomFields[$name]->label = (string)$oneField->attributes()->label;
+ $jevCustomFields[$name]->type = (string)$oneField->attributes()->type;
+
+ if (empty($oneField->option)) continue;
+
+ $jevCustomFields[$name]->options = [];
+ foreach ($oneField->option as $oneOption) {
+ $jevCustomFields[$name]->options[] = $oneOption;
+ }
+ }
+ }
+ }
+
+ $customVDB = acym_loadObjectList('SELECT name, value FROM #__jev_customfields WHERE evdet_id = '.intval($element->evdet_id));
+ foreach ($customVDB as $oneField) {
+ $varFields['{'.$oneField->name.'}'] = $oneField->value;
+ }
+
+ $customValues = [];
+ foreach ($customVDB as $oneCustomValue) {
+ $customValues[$oneCustomValue->name] = $oneCustomValue->value;
+ }
+
+ if (!empty($customValues)) {
+ foreach ($tag->custom as $oneCustom) {
+ $label = (!empty($jevCustomFields[$oneCustom]->label)) ? $jevCustomFields[$oneCustom]->label : $oneCustom;
+ if (!empty($jevCustomFields[$oneCustom]->options)) {
+ $multipleValues = explode(',', $customValues[$oneCustom]);
+
+ $orderedValues = [];
+ foreach ($multipleValues as $oneValue) {
+ $orderedValues[$oneValue] = $oneValue;
+ }
+
+ $possibleValues = [];
+ foreach ($jevCustomFields[$oneCustom]->options as $oneOption) {
+ $possibleValues[(string)$oneOption->attributes()->value] = (string)$oneOption;
+ }
+
+ foreach ($orderedValues as $key => $j) {
+ $orderedValues[$key] = $possibleValues[$key];
+ }
+ $customValues[$oneCustom] = implode(', ', $orderedValues);
+ } elseif ($jevCustomFields[$oneCustom]->type == 'jevrurl') { //we want a link !
+ $customValues[$oneCustom] = ''.$customValues[$oneCustom].' ';
+ } elseif ($jevCustomFields[$oneCustom]->type == 'jevrcalendar') {//comprehensible display
+ $customValues[$oneCustom] = acym_getDate(acym_getTime($customValues[$oneCustom]), acym_translation('ACYM_DATE_FORMAT_LC1'));
+ } elseif ($jevCustomFields[$oneCustom]->type == 'jevruser') {//we do not want the user id but its name
+ $user = acym_loadResultArray('SELECT name FROM #__users WHERE id = '.intval($customValues[$oneCustom]));
+ $customValues[$oneCustom] = (empty($user[0])) ? $customValues[$oneCustom] : $user[0];
+ } elseif ($jevCustomFields[$oneCustom]->type == 'jevcfboolean') {
+ $customValues[$oneCustom] = empty($customValues[$oneCustom]) ? acym_translation('ACYM_NO') : acym_translation('ACYM_YES');
+ }
+
+ if (empty($customValues[$oneCustom]) && in_array($jevCustomFields[$oneCustom]->type, ['jevcfuser', 'jevcfyoutube', 'jevcfupdatable', 'jevcfdblist', 'jevcftext', 'jevcfimage', 'jevcffile', 'jevcfhtml', 'jevcfeventflag', 'jevcfnotes'])) {
+ unset($customValues[$oneCustom]);
+ }
+
+ if (isset($customValues[$oneCustom])) $customFields[] = [$customValues[$oneCustom], $label];
+ }
+ }
+ }
+
+ if (!empty($element->contact)) {
+ $value = $element->contact;
+
+ if (acym_isValidEmail($value)) $value = ''.$value.' ';
+
+ $customFields[] = [$value, acym_translation('JEV_EVENT_CONTACT')];
+ }
+ if (!empty($element->extra_info)) $customFields[] = [$element->extra_info];
+ }
+
+ if (file_exists(JPATH_SITE.DS.'plugins'.DS.'jevents'.DS.'jevfiles'.DS.'jevfiles.php')) {
+
+ if (in_array(acym_getPrefix().'jev_files_combined', acym_getTableList())) {
+ $filesRow = acym_loadObject(
+ 'SELECT files.*
+ FROM `#__jev_files_combined` AS files
+ JOIN #__jevents_repetition AS rpt ON files.ev_id = rpt.eventid
+ WHERE rpt.rp_id = '.intval($tag->id)
+ );
+
+ if (!empty($filesRow)) {
+ for ($i = 1 ; $i < 30 ; $i++) {
+ if (!empty($filesRow->{'imagename'.$i})) {
+ $varFields['{imgpath'.$i.'}'] = $this->imgFolder.$filesRow->{'imagename'.$i};
+ if (empty($imagePath)) {
+ $imagePath = $varFields['{imgpath'.$i.'}'];
+ continue;
+ }
+ $afterArticle .= ' ';
+ }
+
+ if (!empty($filesRow->{'filename'.$i})) {
+ $varFields['{filepath'.$i.'}'] = $this->imgFolder.$filesRow->{'filename'.$i};
+ if (!empty($tag->pluginFields)) $files[] = ''.(empty($filesRow->{'filename'.$i}) ? : $filesRow->{'filetitle'.$i}).' ';
+ }
+ }
+ if (!empty($files)) $afterArticle .= implode(' ', $files);
+ }
+ } else {
+ $files = acym_loadObjectList(
+ 'SELECT files.*
+ FROM `#__jev_files` AS files
+ JOIN #__jevents_repetition AS rpt ON files.ev_id = rpt.eventid
+ WHERE rpt.rp_id = '.intval($tag->id).'
+ ORDER BY filetype DESC'
+ );
+
+ if (!empty($files)) {
+ foreach ($files as $i => $oneFile) {
+ if (empty($oneFile->filename)) continue;
+
+ $varFields['{imgpath'.$i.'}'] = $this->imgFolder.$oneFile->filename;
+ if ($oneFile->filetype == 'file') {
+ if (!empty($tag->pluginFields)) $afterArticle .= ''.$oneFile->filetitle.' ';
+ } else {
+ if (empty($imagePath)) {
+ $imagePath = $varFields['{imgpath'.$i.'}'];
+ continue;
+ }
+ $afterArticle .= ' ';
+ }
+ }
+ }
+ }
+ }
+
+ $varFields['{readmore}'] = ''.acym_translation('ACYM_READ_MORE').' ';
+ if (!empty($tag->readmore)) {
+ $afterArticle .= $varFields['{readmore}'];
+ }
+
+ $format = new stdClass();
+ $format->tag = $tag;
+ $format->title = $title;
+ $format->afterTitle = $afterTitle;
+ $format->afterArticle = $afterArticle;
+ $format->imagePath = $imagePath;
+ $format->description = $contentText;
+ $format->link = empty($tag->clickable) ? '' : $link;
+ $format->cols = empty($tag->nbcols) ? 1 : intval($tag->nbcols);
+ $format->customFields = $customFields;
+ $result = ''.$this->acympluginHelper->getStandardDisplay($format).'
';
+
+ return $this->finalizeElementFormat($this->name, $result, $tag, $varFields);
+ }
+
+ public function onAcymDeclareTriggers(&$triggers, &$defaultValues)
+ {
+
+ $every = [
+ '3600' => acym_translation('ACYM_HOURS'),
+ '86400' => acym_translation('ACYM_DAYS'),
+ ];
+
+ $when = [
+ 'before' => acym_translation('ACYM_BEFORE'),
+ 'after' => acym_translation('ACYM_AFTER'),
+ ];
+
+ $categories = acym_loadObjectList('SELECT `id`, `title` FROM #__categories WHERE `extension` = "com_jevents"', 'id');
+
+ foreach ($categories as $key => $category) {
+ $categories[$key] = $category->title;
+ }
+
+ $categories = ['' => acym_translation('ACYM_ANY_CATEGORY')] + $categories;
+
+ $triggers['classic']['jevents_reminder'] = new stdClass();
+ $triggers['classic']['jevents_reminder']->name = acym_translation_sprintf('ACYM_COMBINED_TRANSLATIONS', 'JEvents', acym_translation('ACYM_REMINDER'));
+ $triggers['classic']['jevents_reminder']->option = '';
+ $triggers['classic']['jevents_reminder']->option .= '
+
+
';
+ $triggers['classic']['jevents_reminder']->option .= '
'.acym_select(
+ $every,
+ '[triggers][classic][jevents_reminder][time]',
+ empty($defaultValues['jevents_reminder']) ? '86400' : $defaultValues['jevents_reminder']['time'],
+ 'data-class="intext_select acym__select"'
+ ).'
';
+ $triggers['classic']['jevents_reminder']->option .= '
'.acym_select(
+ $when,
+ '[triggers][classic][jevents_reminder][when]',
+ empty($defaultValues['jevents_reminder']) ? 'before' : $defaultValues['jevents_reminder']['when'],
+ 'data-class="intext_select acym__select"'
+ ).'
';
+ $triggers['classic']['jevents_reminder']->option .= '
'.acym_translation('ACYM_AN_EVENT_IN').'
';
+ $triggers['classic']['jevents_reminder']->option .= '
'.acym_select(
+ $categories,
+ '[triggers][classic][jevents_reminder][cat]',
+ empty($defaultValues['jevents_reminder']) ? '' : $defaultValues['jevents_reminder']['cat'],
+ 'data-class="intext_select_larger intext_select acym__select"'
+ ).'
';
+ $triggers['classic']['jevents_reminder']->option .= '
';
+ }
+
+ public function onAcymExecuteTrigger(&$step, &$execute, $data)
+ {
+ $time = $data['time'];
+ $triggers = json_decode($step->triggers, true);
+
+ if (!empty($triggers['jevents_reminder']['number'])) {
+ $config = acym_config();
+ $triggerReminder = $triggers['jevents_reminder'];
+
+ $timestamp = ($triggerReminder['number'] * $triggerReminder['time']);
+
+ if ($triggerReminder['when'] == 'before') {
+ $timestamp += $time;
+ } else {
+ $timestamp -= $time;
+ }
+
+
+ $join = [];
+ $where = [];
+
+ if (!empty($triggerReminder['cat'])) {
+ $multicat = JComponentHelper::getParams('com_jevents')->get('multicategory', 0);
+ if ($multicat == 1) {
+ $join[] = 'JOIN #__jevents_catmap AS cats ON rpt.eventid = cats.evid ';
+ $where[] = 'cats.catid = '.intval($triggerReminder['cat']);
+ } else {
+ $join[] = 'LEFT JOIN #__jevents_vevent AS event ON `rpt`.`eventid` = `event`.`ev_id`';
+ $where[] = '`event`.`catid` = '.intval($triggerReminder['cat']);
+ }
+ }
+ $join[] = 'LEFT JOIN #__jevents_vevdetail AS eventd ON `rpt`.`eventdetail_id` = `eventd`.`evdet_id`';
+
+ $where[] = '`rpt`.`startrepeat` >= '.acym_escapeDB(acym_date($timestamp, 'Y-m-d H:i:s'));
+ $where[] = '`rpt`.`startrepeat` <= '.acym_escapeDB(acym_date($timestamp + $config->get('cron_frequency', '900'), 'Y-m-d H:i:s'));
+ $where[] = '`eventd`.`state` = 1';
+
+ $events = acym_loadObjectList('SELECT * FROM `#__jevents_repetition` AS rpt '.implode(' ', $join).' WHERE '.implode(' AND ', $where));
+ if (!empty($events)) $execute = true;
+ }
+ }
+
+ public function onAcymDeclareSummary_triggers(&$automation)
+ {
+ if (!empty($automation->triggers['jevents_reminder'])) {
+ $every = [
+ '3600' => acym_translation('ACYM_HOURS'),
+ '86400' => acym_translation('ACYM_DAYS'),
+ ];
+
+ $when = [
+ 'before' => acym_translation('ACYM_BEFORE'),
+ 'after' => acym_translation('ACYM_AFTER'),
+ ];
+ $categories = acym_loadObjectList('SELECT `id`, `title` FROM #__categories WHERE `extension` = "com_jevents"', 'id');
+
+ foreach ($categories as $key => $category) {
+ $categories[$key] = $category->title;
+ }
+
+ $categories = ['' => acym_translation('ACYM_ANY_CATEGORY')] + $categories;
+
+ $final = '';
+
+ $final = $automation->triggers['jevents_reminder']['number'].' ';
+ $final .= $every[$automation->triggers['jevents_reminder']['time']].' ';
+ $final .= $when[$automation->triggers['jevents_reminder']['when']].' ';
+ $final .= acym_translation('ACYM_AN_EVENT_IN').' '.strtolower($categories[$automation->triggers['jevents_reminder']['cat']]);
+
+ $automation->triggers['jevents_reminder'] = $final;
+ }
+ }
+}
+
diff --git a/deployed/acym/administrator/components/com_acym/dynamics/jomsocial/icon.ico b/deployed/acym/administrator/components/com_acym/dynamics/jomsocial/icon.ico
new file mode 100644
index 00000000..b489216a
Binary files /dev/null and b/deployed/acym/administrator/components/com_acym/dynamics/jomsocial/icon.ico differ
diff --git a/deployed/acym/administrator/components/com_acym/dynamics/jomsocial/index.html b/deployed/acym/administrator/components/com_acym/dynamics/jomsocial/index.html
new file mode 100644
index 00000000..fa6d84e8
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/dynamics/jomsocial/index.html
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/deployed/acym/administrator/components/com_acym/dynamics/jomsocial/plugin.php b/deployed/acym/administrator/components/com_acym/dynamics/jomsocial/plugin.php
new file mode 100644
index 00000000..248f9ed9
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/dynamics/jomsocial/plugin.php
@@ -0,0 +1,288 @@
+cms = 'Joomla';
+ if (true || !defined('JPATH_ADMINISTRATOR') || !file_exists(rtrim(JPATH_ADMINISTRATOR, DS).DS.'components'.DS.'com_community'.DS)) {
+ $this->installed = false;
+ }
+ }
+
+ function dynamicText()
+ {
+ $onePlugin = new stdClass();
+ $onePlugin->name = 'JomSocial';
+ $onePlugin->plugin = __CLASS__;
+ $onePlugin->type = 'joomla';
+ $onePlugin->help = 'plugin-jomsocial';
+
+ return $onePlugin;
+ }
+
+ function insertOptions()
+ {
+ $plugin = new stdClass();
+ $plugin->name = 'JomSocial';
+ $plugin->icon = ACYM_DYNAMICS_URL.basename(__DIR__).'/icon.ico';
+ $plugin->plugin = __CLASS__;
+
+ return $plugin;
+ }
+
+ function textPopup()
+ {
+ ?>
+
+
+
+ ';
+
+
+ $otherFields = acym_loadObjectList("SELECT `name`, `id` FROM `#__community_fields` WHERE `type` != 'group' ORDER BY `ordering` ASC");
+ foreach ($otherFields as $oneField) {
+ $text .= '';
+ }
+
+ $fields = acym_getColumns('community_users', false);
+ foreach ($fields as $fieldname) {
+ $type = '';
+ if (strpos(strtolower($fieldname), 'date') !== false) {
+ $type = '|type:date';
+ }
+ if (!empty($fieldType[$fieldname]) && $fieldType[$fieldname]->type == 'image') {
+ $type = '|type:image';
+ }
+ $text .= '';
+ }
+
+ $text .= '';
+
+ echo $text;
+ }
+
+ function replaceUserInformation(&$email, &$user, $send = true)
+ {
+ $extractedTags = $this->acympluginHelper->extractTags($email, 'jomsocialfield');
+ if (empty($extractedTags)) {
+ return;
+ }
+
+ $tags = [];
+ foreach ($extractedTags as $i => $oneTag) {
+ if (isset($tags[$i])) {
+ continue;
+ }
+
+ if (empty ($user->cms_id)) {
+ $tags[$i] = '';
+ continue;
+ }
+
+ if ($user->cms_id != $this->lastuserid) {
+ $this->lastuserid = $user->cms_id;
+ $this->valuesNum = null;
+ $this->valuesString = null;
+ }
+
+
+ $field = $oneTag->id;
+
+ if (is_numeric($field)) {
+ if ($this->valuesNum === null) {
+ $this->valuesNum = acym_loadObjectList('SELECT `field_id`,`value` FROM #__community_fields_values WHERE user_id = '.intval($user->cms_id), 'field_id');
+ }
+ if (isset($this->valuesNum[$field]->value)) {
+ $tags[$i] = $this->valuesNum[$field]->value;
+ }
+ } else {
+ if ($this->valuesString === null) {
+ $this->valuesString = acym_loadObject('SELECT * FROM #__community_users WHERE userid = '.intval($user->cms_id));
+ }
+
+ if (isset($this->valuesString->$field)) {
+ $tags[$i] = $this->valuesString->$field;
+ }
+
+ if (in_array($field, ['avatar', 'thumb']) && !empty($this->valuesString->$field)) {
+ $tags[$i] = ' ';
+ if (!empty($oneTag->maxheight) || !empty($oneTag->maxwidth)) {
+ $tags[$i] = $this->acympluginHelper->managePicts($oneTag, $tags[$i]);
+ }
+ }
+ }
+ }
+
+ $this->acympluginHelper->replaceTags($email, $tags);
+ }
+
+ function contentPopup()
+ {
+ acym_loadLanguageFile('com_community', JPATH_SITE);
+ $tabHelper = acym_get('helper.tab');
+
+ $tabHelper->startTab(acym_translation('ACYM_USERS'));
+
+ $attributes = [
+ 'title' => 'ACYM_TITLE',
+ 'karma' => 'COM_COMMUNITY_KARMA',
+ 'email' => 'COM_COMMUNITY_EMAIL',
+ 'registerdate' => 'COM_COMMUNITY_MEMBER_SINCE',
+ 'lastvisitdate' => 'COM_COMMUNITY_LAST_LOGIN',
+ 'views' => 'COM_COMMUNITY_PROFILE_VIEW',
+ 'friends' => 'COM_COMMUNITY_PROFILE_FRIENDS',
+ ];
+
+ $extraFields = acym_loadObjectList(
+ "SELECT `name`, `fieldcode`
+ FROM `#__community_fields`
+ WHERE `type` != 'group'
+ ORDER BY `ordering` ASC"
+ );
+
+ $extra = [];
+ foreach ($extraFields as $field) {
+ $extra[strtolower($field->fieldcode)] = $field->name;
+ }
+
+ $attributes = array_merge($attributes, $extra);
+
+ $displayOptions = [
+ [
+ 'title' => 'ACYM_DISPLAY',
+ 'type' => 'checkbox',
+ 'name' => 'fields',
+ 'options' => $attributes,
+ 'default' => 'full',
+ ],
+ [
+ 'title' => 'ACYM_DISPLAY_PICTURES',
+ 'type' => 'pictures',
+ 'name' => 'pictures',
+ ],
+ [
+ 'title' => 'ACYM_IMAGE_REQUIRED',
+ 'type' => 'boolean',
+ 'name' => 'required',
+ 'default' => false,
+ ],
+ [
+ 'title' => 'ACYM_ORDER_BY',
+ 'type' => 'select',
+ 'name' => 'order',
+ 'options' => [
+ 'u.registerDate' => 'ACYM_DATE_CREATED',
+ 'u.lastvisitDate' => 'COM_COMMUNITY_LAST_LOGIN',
+ 'c.view' => 'COM_COMMUNITY_PROFILE_VIEW',
+ 'c.points' => 'COM_COMMUNITY_KARMA',
+ 'rand()' => 'ACYM_RANDOM',
+ ],
+ ],
+ [
+ 'title' => 'Number of characters ("About me" field)',
+ 'type' => 'text',
+ 'name' => 'chars',
+ 'default' => 150,
+ ],
+ [
+ 'title' => 'ACYM_COLUMNS',
+ 'type' => 'text',
+ 'name' => 'cols',
+ 'default' => 1,
+ ],
+ [
+ 'title' => 'ACYM_MAX_NB_ELEMENTS',
+ 'type' => 'text',
+ 'name' => 'max',
+ 'default' => 20,
+ ],
+ ];
+
+ echo $this->acympluginHelper->displayOptions($displayOptions, 'jomsocialusers', 'simple');
+
+ $tabHelper->endTab();
+ $tabHelper->startTab(acym_translation('COM_COMMUNITY_VIDEOS'));
+
+
+ $attributes = [
+ 'description' => acym_translation('COM_COMMUNITY_VIDEOS_DESCRIPTION'),
+ 'duration' => trim(acymailing_translation('COM_COMMUNITY_VIDEOS_DURATION'), ': '),
+ 'uploadedby' => acymailing_translation_sprintf('COM_COMMUNITY_PHOTOS_UPLOADED_BY', ''),
+ 'uploadedon' => trim(acymailing_translation('COM_COMMUNITY_VIDEOS_CREATED'), ': '),
+ 'views' => ucfirst(trim(acymailing_translation_sprintf('COM_COMMUNITY_VIDEOS_HITS_COUNT', ''))),
+ 'category' => acymailing_translation('COM_COMMUNITY_VIDEOS_CATEGORY'),
+ ];
+
+
+ $displayOptions = [
+ [
+ 'title' => 'ACYM_DISPLAY',
+ 'type' => 'checkbox',
+ 'name' => 'fields',
+ 'options' => $attributes,
+ 'default' => 'full',
+ ],
+ [
+ 'title' => 'ACYM_DISPLAY_PICTURES',
+ 'type' => 'pictures',
+ 'name' => 'pictures',
+ ],
+ [
+ 'title' => 'ACYM_ORDER_BY',
+ 'type' => 'select',
+ 'name' => 'order',
+ 'options' => [
+ 'v.created' => 'COM_COMMUNITY_VIDEOS_SORT_LATEST',
+ 'v.hits' => 'COM_COMMUNITY_VIDEOS_SORT_POPULAR',
+ 'rand()' => 'ACYM_RANDOM',
+ ],
+ ],
+ [
+ 'title' => 'Number of characters ("Description" field)',
+ 'type' => 'text',
+ 'name' => 'chars',
+ 'default' => 150,
+ ],
+ [
+ 'title' => 'ACYM_COLUMNS',
+ 'type' => 'text',
+ 'name' => 'cols',
+ 'default' => 1,
+ ],
+ [
+ 'title' => 'ACYM_MAX_NB_ELEMENTS',
+ 'type' => 'text',
+ 'name' => 'max',
+ 'default' => 20,
+ ],
+ ];
+
+ echo $this->acympluginHelper->displayOptions($displayOptions, 'jomsocialusers', 'simple');
+
+ $tabHelper->endTab();
+
+ $tabHelper->display('plugin');
+ }
+}
+
diff --git a/deployed/acym/administrator/components/com_acym/dynamics/managetext/index.html b/deployed/acym/administrator/components/com_acym/dynamics/managetext/index.html
new file mode 100644
index 00000000..fa6d84e8
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/dynamics/managetext/index.html
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/deployed/acym/administrator/components/com_acym/dynamics/managetext/plugin.php b/deployed/acym/administrator/components/com_acym/dynamics/managetext/plugin.php
new file mode 100644
index 00000000..3db968a0
--- /dev/null
+++ b/deployed/acym/administrator/components/com_acym/dynamics/managetext/plugin.php
@@ -0,0 +1,289 @@
+_replaceConstant($email);
+ $this->_replaceRandom($email);
+ $this->_addAlignmentCss($email);
+ $this->_handleAnchors($email);
+ }
+
+ public function replaceUserInformation(&$email, &$user, $send = true)
+ {
+ $this->acympluginHelper->cleanHtml($email->body);
+ $this->acympluginHelper->replaceVideos($email->body);
+
+ $this->_removetext($email);
+ $this->_ifstatement($email, $user);
+ }
+
+ private function _replaceConstant(&$email)
+ {
+ $tags = $this->acympluginHelper->extractTags($email, '(?:const|trans|config)');
+ if (empty($tags)) {
+ return;
+ }
+
+ $tagsReplaced = [];
+ foreach ($tags as $i => $oneTag) {
+ $val = '';
+ $arrayVal = [];
+ foreach ($oneTag as $valname => $oneValue) {
+ if ($valname == 'id') {
+ $val = trim(strip_tags($oneValue));
+ } elseif ($valname != 'default') {
+ $arrayVal[] = '{'.$valname.'}';
+ }
+ }
+
+ if (empty($val)) {
+ continue;
+ }
+ $tagValues = explode(':', $i);
+ $type = ltrim($tagValues[0], '{');
+ if ($type == 'const') {
+ $tagsReplaced[$i] = defined($val) ? constant($val) : 'Constant not defined : '.$val;
+ } elseif ($type == 'config') {
+ if ($val == 'sitename') {
+ $tagsReplaced[$i] = acym_getCMSConfig($val);
+ }
+ } else {
+ static $done = false;
+ if (!$done && strpos($val, 'COM_USERS') !== false) {
+ $done = true;
+
+ acym_loadLanguageFile('com_users');
+ }
+ if (!empty($arrayVal)) {
+ $tagsReplaced[$i] = nl2br(vsprintf(acym_translation($val), $arrayVal));
+ } else {
+ $tagsReplaced[$i] = acym_translation($val);
+ }
+ }
+ }
+
+ $this->acympluginHelper->replaceTags($email, $tagsReplaced, true);
+ }
+
+ private function _replaceRandom(&$email)
+ {
+ $randTag = $this->acympluginHelper->extractTags($email, "rand");
+ if (empty($randTag)) {
+ return;
+ }
+ foreach ($randTag as $oneRandTag) {
+ $results[$oneRandTag->id] = explode(';', $oneRandTag->id);
+ $randNumber = rand(0, count($results[$oneRandTag->id]) - 1);
+ $results[$oneRandTag->id][count($results[$oneRandTag->id])] = $results[$oneRandTag->id][$randNumber];
+ }
+
+ $tags = [];
+ foreach (array_keys($results) as $oneResult) {
+ $tags['{rand:'.$oneResult.'}'] = end($results[$oneResult]);
+ }
+
+ if (empty($tags)) {
+ return;
+ }
+ $this->acympluginHelper->replaceTags($email, $tags, true);
+ }
+
+
+ private function _ifstatement(&$email, $user, $loop = 1)
+ {
+ if (isset($this->noIfStatementTags[$email->id])) {
+ return;
+ }
+
+ $isAdmin = acym_isAdmin();
+
+ if ($loop > 3) {
+ if ($isAdmin) {
+ acym_display('You cannot have more than 3 nested {if} tags.', 'warning');
+ }
+
+ return;
+ }
+
+ $match = '#{if:(((?!{if).)*)}(((?!{if).)*){/if}#Uis';
+ $variables = ['subject', 'body', 'altbody', 'From', 'FromName', 'ReplyTo'];
+ $found = false;
+ foreach ($variables as $var) {
+ if (empty($email->$var)) {
+ continue;
+ }
+ if (is_array($email->$var)) {
+ foreach ($email->$var as $i => &$arrayField) {
+ if (empty($arrayField) || !is_array($arrayField)) {
+ continue;
+ }
+ foreach ($arrayField as $key => &$oneval) {
+ $found = preg_match_all($match, $oneval, $results[$var.$i.'-'.$key]) || $found;
+ if (empty($results[$var.$i.'-'.$key][0])) {
+ unset($results[$var.$i.'-'.$key]);
+ }
+ }
+ }
+ } else {
+ $found = preg_match_all($match, $email->$var, $results[$var]) || $found;
+ if (empty($results[$var][0])) {
+ unset($results[$var]);
+ }
+ }
+ }
+
+ if (!$found) {
+ if ($loop == 1) {
+ $this->noIfStatementTags[$email->id] = true;
+ }
+
+ return;
+ }
+
+ static $a = false;
+
+ $tags = [];
+ foreach ($results as $var => $allresults) {
+ foreach ($allresults[0] as $i => $oneTag) {
+ if (isset($tags[$oneTag])) {
+ continue;
+ }
+ $allresults[1][$i] = html_entity_decode($allresults[1][$i]);
+ if (!preg_match('#^(.+)(!=|<|>|>|<|!~)([^=!<>~]+)$#is', $allresults[1][$i], $operators) && !preg_match('#^(.+)(=|~)([^=!<>~]+)$#is', $allresults[1][$i], $operators)) {
+ if ($isAdmin) {
+ acym_display('Operation not found : '.$allresults[1][$i], 'error');
+ }
+ $tags[$oneTag] = $allresults[3][$i];
+ continue;
+ };
+ $field = trim($operators[1]);
+ $prop = '';
+
+ $operatorsParts = explode('.', $operators[1]);
+ $operatorComp = 'acym';
+ if (count($operatorsParts) > 1 && in_array($operatorsParts[0], ['acym', 'joomla', 'var'])) {
+ $operatorComp = $operatorsParts[0];
+ unset($operatorsParts[0]);
+ $field = implode('.', $operatorsParts);
+ }
+
+ if ($operatorComp == 'joomla') {
+ if (!empty($user->userid)) {
+ if ($field == 'gid') {
+ $prop = implode(';', acym_loadResultArray('SELECT group_id FROM #__user_usergroup_map WHERE user_id = '.intval($user->userid)));
+ } else {
+ $juser = acym_loadObject('SELECT * FROM #__users WHERE id = '.intval($user->userid));
+ if (isset($juser->{$field})) {
+ $prop = strtolower($juser->{$field});
+ } else {
+ if ($isAdmin && !$a) {
+ acym_display('User variable not set : '.$field.' in '.$allresults[1][$i], 'error');
+ }
+ $a = true;
+ }
+ }
+ }
+ } elseif ($operatorComp == 'var') {
+ $prop = strtolower($field);
+ } else {
+ if (!isset($user->{$field})) {
+ if ($isAdmin && !$a) {
+ acym_display('User variable not set : '.$field.' in '.$allresults[1][$i], 'error');
+ }
+ $a = true;
+ } else {
+ $prop = strtolower($user->{$field});
+ }
+ }
+
+ $tags[$oneTag] = '';
+ $val = trim(strtolower($operators[3]));
+ if ($operators[2] == '=' && ($prop == $val || in_array($prop, explode(';', $val)) || in_array($val, explode(';', $prop)))) {
+ $tags[$oneTag] = $allresults[3][$i];
+ } elseif ($operators[2] == '!=' && $prop != $val) {
+ $tags[$oneTag] = $allresults[3][$i];
+ } elseif (($operators[2] == '>' || $operators[2] == '>') && $prop > $val) {
+ $tags[$oneTag] = $allresults[3][$i];
+ } elseif (($operators[2] == '<' || $operators[2] == '<') && $prop < $val) {
+ $tags[$oneTag] = $allresults[3][$i];
+ } elseif ($operators[2] == '~' && strpos($prop, $val) !== false) {
+ $tags[$oneTag] = $allresults[3][$i];
+ } elseif ($operators[2] == '!~' && strpos($prop, $val) === false) {
+ $tags[$oneTag] = $allresults[3][$i];
+ }
+ }
+ }
+
+ $this->acympluginHelper->replaceTags($email, $tags, true);
+
+ $this->_ifstatement($email, $user, $loop + 1);
+ }
+
+ private function _removetext(&$email)
+ {
+ $removetext = '{reg},{/reg},{pub},{/pub}';
+ if (!empty($removetext)) {
+ $removeArray = explode(',', trim($removetext, ' ,'));
+ if (!empty($email->body)) {
+ $email->body = str_replace($removeArray, '', $email->body);
+ }
+ }
+
+
+ $removetags = 'youtube';
+ if (!empty($removetags)) {
+ $regex = [];
+ $removeArray = explode(',', trim($removetags, ' ,'));
+ foreach ($removeArray as $oneTag) {
+ if (empty($oneTag)) {
+ continue;
+ }
+ $regex[] = '#(?:{|%7B)'.preg_quote($oneTag, '#').'(?:}|%7D).*(?:{|%7B)/'.preg_quote($oneTag, '#').'(?:}|%7D)#Uis';
+ $regex[] = '#(?:{|%7B)'.preg_quote($oneTag, '#').'[^}]*(?:}|%7D)#Uis';
+ }
+
+ if (!empty($email->body)) {
+ $email->body = preg_replace($regex, '', $email->body);
+ }
+ }
+ }
+
+ private function _addAlignmentCss(&$email)
+ {
+ $imageAlignment = '';
+
+ if (strpos($email->body, '