| 1 |
<?php |
| 2 |
|
| 3 |
namespace AcyMailing\Classes; |
| 4 |
|
| 5 |
use AcyMailing\Helpers\MailerHelper; |
| 6 |
use AcyMailing\Helpers\PaginationHelper; |
| 7 |
use AcyMailing\Core\AcymClass; |
| 8 |
|
| 9 |
class ListClass extends AcymClass |
| 10 |
{ |
| 11 |
const LIST_TYPE_STANDARD = 'standard'; |
| 12 |
const LIST_TYPE_FRONT = 'front'; |
| 13 |
const LIST_TYPE_FOLLOWUP = 'followup'; |
| 14 |
const COLOR_PARTS = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f']; |
| 15 |
|
| 16 |
public function __construct() |
| 17 |
{ |
| 18 |
parent::__construct(); |
| 19 |
|
| 20 |
$this->table = 'list'; |
| 21 |
$this->pkey = 'id'; |
| 22 |
} |
| 23 |
|
| 24 |
public function getMatchingElements(array $settings = []): array |
| 25 |
{ |
| 26 |
$columns = 'list.*'; |
| 27 |
if (!empty($settings['columns'])) { |
| 28 |
foreach ($settings['columns'] as $key => $value) { |
| 29 |
if ($value == 'lists.list_id') { |
| 30 |
unset($settings['columns'][$key]); |
| 31 |
continue; |
| 32 |
} |
| 33 |
$settings['columns'][$key] = $key === 'join' ? $value : 'list.'.$value; |
| 34 |
} |
| 35 |
$columns = implode(', ', $settings['columns']); |
| 36 |
} |
| 37 |
|
| 38 |
$query = 'SELECT '.$columns.' FROM #__acym_list AS list'; |
| 39 |
$queryCount = 'SELECT COUNT(list.id) AS total FROM #__acym_list AS list'; |
| 40 |
if (!empty($settings['join'])) $query .= $this->getJoinForQuery($settings['join']); |
| 41 |
$queryStatus = 'SELECT COUNT(id) AS number, active + (visible*2) AS score FROM #__acym_list AS list'; |
| 42 |
$filters = []; |
| 43 |
$listsId = []; |
| 44 |
|
| 45 |
if (!empty($settings['tag'])) { |
| 46 |
$tagJoin = ' JOIN #__acym_tag AS tag ON list.id = tag.id_element'; |
| 47 |
$query .= $tagJoin; |
| 48 |
$queryCount .= $tagJoin; |
| 49 |
$queryStatus .= $tagJoin; |
| 50 |
$filters[] = 'tag.name = '.acym_escapeDB($settings['tag']); |
| 51 |
$filters[] = 'tag.type = "list"'; |
| 52 |
} |
| 53 |
|
| 54 |
if (!empty($settings['search'])) { |
| 55 |
$filters[] = 'list.name LIKE '.acym_escapeDB('%'.$settings['search'].'%'); |
| 56 |
} |
| 57 |
|
| 58 |
if (!empty($settings['creator_id']) && !acym_isAdmin()) { |
| 59 |
$userGroups = acym_getGroupsByUser($settings['creator_id']); |
| 60 |
$groupCondition = '(list.access LIKE "%,'.implode(',%" OR list.access LIKE "%,', $userGroups).',%")'; |
| 61 |
|
| 62 |
$filters[] = 'list.cms_user_id = '.intval($settings['creator_id']).' OR '.$groupCondition.''; |
| 63 |
} |
| 64 |
|
| 65 |
$filters[] = 'list.type = '.acym_escapeDB(self::LIST_TYPE_STANDARD); |
| 66 |
|
| 67 |
if (!empty($filters)) { |
| 68 |
$queryStatus .= ' WHERE ('.implode(') AND (', $filters).')'; |
| 69 |
} |
| 70 |
|
| 71 |
if (!empty($settings['status'])) { |
| 72 |
$allowedStatus = [ |
| 73 |
'active' => 'active = 1', |
| 74 |
'inactive' => 'active = 0', |
| 75 |
'visible' => 'visible = 1', |
| 76 |
'invisible' => 'visible = 0', |
| 77 |
]; |
| 78 |
if (empty($allowedStatus[$settings['status']])) { |
| 79 |
die('Injection denied'); |
| 80 |
} |
| 81 |
$filters[] = 'list.'.$allowedStatus[$settings['status']]; |
| 82 |
} |
| 83 |
|
| 84 |
if (!empty($settings['where'])) { |
| 85 |
$filters[] = $settings['where']; |
| 86 |
} |
| 87 |
|
| 88 |
|
| 89 |
if (!empty($filters)) { |
| 90 |
$query .= ' WHERE ('.implode(') AND (', $filters).')'; |
| 91 |
$queryCount .= ' WHERE ('.implode(') AND (', $filters).')'; |
| 92 |
} |
| 93 |
|
| 94 |
if (!empty($settings['ordering']) && !empty($settings['ordering_sort_order'])) { |
| 95 |
$query .= ' ORDER BY list.'.acym_secureDBColumn($settings['ordering']).' '.acym_secureDBColumn(strtoupper($settings['ordering_sort_order'])); |
| 96 |
} |
| 97 |
|
| 98 |
if (empty($settings['offset']) || $settings['offset'] < 0) { |
| 99 |
$settings['offset'] = 0; |
| 100 |
} |
| 101 |
|
| 102 |
if (empty($settings['elementsPerPage']) || $settings['elementsPerPage'] < 1) { |
| 103 |
$pagination = new PaginationHelper(); |
| 104 |
$settings['elementsPerPage'] = $pagination->getListLimit(); |
| 105 |
} |
| 106 |
|
| 107 |
$results['elements'] = acym_loadObjectList($query, '', $settings['offset'], $settings['elementsPerPage']); |
| 108 |
if (!empty($settings['join'])) { |
| 109 |
$this->setSelectedList($results['elements'], $settings['join']); |
| 110 |
} |
| 111 |
foreach ($results['elements'] as $i => $oneList) { |
| 112 |
$listsId[] = $oneList->id; |
| 113 |
$results['elements'][$i]->sendable_users = 0; |
| 114 |
$results['elements'][$i]->unconfirmed_users = 0; |
| 115 |
$results['elements'][$i]->unsubscribed_users = 0; |
| 116 |
$results['elements'][$i]->inactive_users = 0; |
| 117 |
$results['elements'][$i]->newSub = 0; |
| 118 |
$results['elements'][$i]->newUnsub = 0; |
| 119 |
} |
| 120 |
|
| 121 |
$countUserByList = []; |
| 122 |
$countEvolByList = []; |
| 123 |
if (!empty($listsId) && empty($settings['entitySelect'])) { |
| 124 |
$countUserByList = $this->getSubscribersCountPerStatusByListIds($listsId); |
| 125 |
$countEvolByList = $this->getSubscribersEvolutionByListIds($listsId); |
| 126 |
} |
| 127 |
|
| 128 |
foreach ($results['elements'] as $i => $list) { |
| 129 |
$results['elements'][$i]->tags = []; |
| 130 |
foreach ($countUserByList as $userList) { |
| 131 |
if ($list->id == $userList->list_id) { |
| 132 |
$results['elements'][$i]->sendable_users = $userList->sendable_users; |
| 133 |
$results['elements'][$i]->unconfirmed_users = $userList->unconfirmed_users; |
| 134 |
$results['elements'][$i]->unsubscribed_users = $userList->unsubscribed_users; |
| 135 |
$results['elements'][$i]->inactive_users = $userList->inactive_users; |
| 136 |
} |
| 137 |
} |
| 138 |
if (isset($countEvolByList[$list->id]->newSub)) $results['elements'][$i]->newSub = $countEvolByList[$list->id]->newSub; |
| 139 |
if (isset($countEvolByList[$list->id]->newUnsub)) $results['elements'][$i]->newUnsub = $countEvolByList[$list->id]->newUnsub; |
| 140 |
} |
| 141 |
|
| 142 |
$results['total'] = acym_loadObject($queryCount); |
| 143 |
|
| 144 |
$listsPerStatus = acym_loadObjectList($queryStatus.' GROUP BY score', 'score'); |
| 145 |
for ($i = 0; $i < 4; $i++) { |
| 146 |
$listsPerStatus[$i] = empty($listsPerStatus[$i]) ? 0 : $listsPerStatus[$i]->number; |
| 147 |
} |
| 148 |
|
| 149 |
$results['status'] = [ |
| 150 |
'all' => array_sum($listsPerStatus), |
| 151 |
'active' => $listsPerStatus[1] + $listsPerStatus[3], |
| 152 |
'inactive' => $listsPerStatus[0] + $listsPerStatus[2], |
| 153 |
'visible' => $listsPerStatus[2] + $listsPerStatus[3], |
| 154 |
'invisible' => $listsPerStatus[0] + $listsPerStatus[1], |
| 155 |
]; |
| 156 |
|
| 157 |
return $results; |
| 158 |
} |
| 159 |
|
| 160 |
public function getOneById(int $id): ?object |
| 161 |
{ |
| 162 |
$list = parent::getOneById($id); |
| 163 |
|
| 164 |
if (!empty($list)) { |
| 165 |
$list->translation = empty($list->translation) ? [] : json_decode($list->translation, true); |
| 166 |
} |
| 167 |
|
| 168 |
return $list; |
| 169 |
} |
| 170 |
|
| 171 |
private function setSelectedList(array $elements, string $join): void |
| 172 |
{ |
| 173 |
if (strpos($join, 'join_list') === false) { |
| 174 |
return; |
| 175 |
} |
| 176 |
|
| 177 |
$listsIds = explode('-', $join); |
| 178 |
$listsIds = $listsIds[1]; |
| 179 |
$listsIds = explode(',', $listsIds); |
| 180 |
foreach ($elements as $element) { |
| 181 |
$element->list_id = in_array($element->id, $listsIds) ? $element->id : null; |
| 182 |
} |
| 183 |
} |
| 184 |
|
| 185 |
private function getJoinForQuery(string $joinType): string |
| 186 |
{ |
| 187 |
if (strpos($joinType, 'join_mail') !== false) { |
| 188 |
$mailId = explode('-', $joinType); |
| 189 |
|
| 190 |
return ' LEFT JOIN #__acym_mail_has_list as maillist ON list.id = maillist.list_id AND maillist.mail_id = '.intval($mailId[1]); |
| 191 |
} |
| 192 |
if (strpos($joinType, 'join_user') !== false) { |
| 193 |
$userId = explode('-', $joinType); |
| 194 |
|
| 195 |
return ' LEFT JOIN #__acym_user_has_list as userlist ON list.id = userlist.list_id AND userlist.status = 1 AND userlist.user_id = '.intval($userId[1]); |
| 196 |
} |
| 197 |
|
| 198 |
return ''; |
| 199 |
} |
| 200 |
|
| 201 |
public function getListsWithIdNameCount(array $settings): array |
| 202 |
{ |
| 203 |
$filters = []; |
| 204 |
|
| 205 |
if (isset($settings['ids'])) { |
| 206 |
if (empty($settings['ids'])) { |
| 207 |
return ['lists' => [], 'total' => 0]; |
| 208 |
} else { |
| 209 |
acym_arrayToInteger($settings['ids']); |
| 210 |
$filters[] = 'list.id IN ('.implode(',', $settings['ids']).')'; |
| 211 |
} |
| 212 |
} |
| 213 |
|
| 214 |
$query = 'SELECT list.id, list.name, list.color, list.active, COUNT(user.id) AS subscribers |
| 215 |
FROM #__acym_list AS list |
| 216 |
LEFT JOIN #__acym_user_has_list AS userList |
| 217 |
ON list.id = userList.list_id |
| 218 |
AND userList.status = 1 |
| 219 |
LEFT JOIN #__acym_user AS user |
| 220 |
ON user.id = userList.user_id |
| 221 |
AND user.active = 1 '; |
| 222 |
|
| 223 |
if (intval($this->config->get('require_confirmation', 1)) === 1) { |
| 224 |
$query .= ' AND user.confirmed = 1 '; |
| 225 |
} |
| 226 |
|
| 227 |
$queryCount = 'SELECT COUNT(list.id) FROM #__acym_list AS list'; |
| 228 |
|
| 229 |
if (!acym_isAdmin()) { |
| 230 |
$currentUserId = acym_currentUserId(); |
| 231 |
if (empty($currentUserId)) { |
| 232 |
return [ |
| 233 |
'lists' => [], |
| 234 |
'total' => 0, |
| 235 |
]; |
| 236 |
} |
| 237 |
|
| 238 |
$userGroups = acym_getGroupsByUser($currentUserId); |
| 239 |
$groupCondition = '(list.access LIKE "%,'.implode(',%" OR list.access LIKE "%,', $userGroups).',%")'; |
| 240 |
|
| 241 |
$filters[] = 'list.cms_user_id = '.intval($currentUserId).' OR '.$groupCondition; |
| 242 |
} |
| 243 |
|
| 244 |
if (!empty($settings['search'])) { |
| 245 |
$filters[] = 'list.name LIKE '.acym_escapeDB('%'.$settings['search'].'%'); |
| 246 |
} |
| 247 |
|
| 248 |
if (!empty($settings['already'])) { |
| 249 |
acym_arrayToInteger($settings['already']); |
| 250 |
$filters[] = 'list.id NOT IN('.implode(',', $settings['already']).')'; |
| 251 |
} |
| 252 |
$filters[] = 'list.type = '.acym_escapeDB(self::LIST_TYPE_STANDARD); |
| 253 |
|
| 254 |
if (!empty($filters)) { |
| 255 |
$query .= ' WHERE ('.implode(') AND (', $filters).')'; |
| 256 |
$queryCount .= ' WHERE ('.implode(') AND (', $filters).')'; |
| 257 |
} |
| 258 |
|
| 259 |
$query .= ' GROUP BY list.id '; |
| 260 |
|
| 261 |
return [ |
| 262 |
'lists' => acym_loadObjectList($query, '', $settings['offset'], $settings['listsPerPage']), |
| 263 |
'total' => (int)acym_loadResult($queryCount), |
| 264 |
]; |
| 265 |
} |
| 266 |
|
| 267 |
public function getListsByIds(array $ids): array |
| 268 |
{ |
| 269 |
acym_arrayToInteger($ids); |
| 270 |
if (empty($ids)) { |
| 271 |
return []; |
| 272 |
} |
| 273 |
|
| 274 |
$query = 'SELECT * FROM #__acym_list WHERE id IN ('.implode(', ', $ids).')'; |
| 275 |
|
| 276 |
return acym_loadObjectList($query); |
| 277 |
} |
| 278 |
|
| 279 |
public function getSubscribersCount(array $listsIds): int |
| 280 |
{ |
| 281 |
acym_arrayToInteger($listsIds); |
| 282 |
if (empty($listsIds)) { |
| 283 |
return 0; |
| 284 |
} |
| 285 |
|
| 286 |
$query = 'SELECT COUNT(DISTINCT user.id) |
| 287 |
FROM #__acym_user AS user |
| 288 |
JOIN #__acym_user_has_list AS userList ON user.id = userList.user_id |
| 289 |
WHERE userList.list_id IN ('.implode(",", $listsIds).') AND userList.status = 1 AND user.active = 1'; |
| 290 |
|
| 291 |
if ($this->config->get('require_confirmation', 1) == 1) { |
| 292 |
$query .= ' AND user.confirmed = 1'; |
| 293 |
} |
| 294 |
|
| 295 |
return (int)acym_loadResult($query); |
| 296 |
} |
| 297 |
|
| 298 |
public function getSubscribersForList(array $options = []): array |
| 299 |
{ |
| 300 |
$listIds = $options['listIds'] ?? []; |
| 301 |
$offset = $options['offset'] ?? 0; |
| 302 |
$limit = $options['limit'] ?? 100; |
| 303 |
$status = $options['status'] ?? null; |
| 304 |
$orderBy = $options['orderBy'] ?? ''; |
| 305 |
$orderBySort = $options['orderBySort'] ?? ''; |
| 306 |
$subscribedAfter = $options['subscribed_after'] ?? null; |
| 307 |
$unsubscribedAfter = $options['unsubscribed_after'] ?? null; |
| 308 |
|
| 309 |
if (empty($listIds)) { |
| 310 |
return []; |
| 311 |
} |
| 312 |
|
| 313 |
acym_arrayToInteger($listIds); |
| 314 |
|
| 315 |
$statusCondition = ''; |
| 316 |
if (!is_null($status)) { |
| 317 |
$statusCondition .= ' AND user_list.status = '.intval($status); |
| 318 |
} |
| 319 |
|
| 320 |
if (!empty($subscribedAfter)) { |
| 321 |
$statusCondition .= ' AND user_list.subscription_date > '.acym_escapeDB($subscribedAfter); |
| 322 |
} |
| 323 |
|
| 324 |
if (!empty($unsubscribedAfter)) { |
| 325 |
$statusCondition .= ' AND user_list.unsubscribe_date > '.acym_escapeDB($unsubscribedAfter); |
| 326 |
} |
| 327 |
|
| 328 |
$requestSub = 'SELECT user.*, user_list.status, user_list.subscription_date, user_list.unsubscribe_date FROM #__acym_user AS user'; |
| 329 |
$requestSub .= ' LEFT JOIN #__acym_user_has_list AS user_list ON user.id = user_list.user_id'; |
| 330 |
$requestSub .= ' WHERE user.active = 1 AND user_list.list_id IN ('.implode(', ', $listIds).')'.$statusCondition; |
| 331 |
|
| 332 |
if (!empty($orderBy)) { |
| 333 |
if (empty($orderBySort)) $orderBySort = 'desc'; |
| 334 |
$requestSub .= ' ORDER BY '.acym_secureDBColumn($orderBy).' '.acym_secureDBColumn($orderBySort); |
| 335 |
} |
| 336 |
|
| 337 |
return acym_loadObjectList( |
| 338 |
$requestSub, |
| 339 |
'', |
| 340 |
$offset, |
| 341 |
$limit |
| 342 |
); |
| 343 |
} |
| 344 |
|
| 345 |
public function delete(array $elements, bool $force = false): int |
| 346 |
{ |
| 347 |
if (!$force) { |
| 348 |
$this->onlyManageableLists($elements); |
| 349 |
} |
| 350 |
|
| 351 |
if (empty($elements)) { |
| 352 |
return 0; |
| 353 |
} |
| 354 |
|
| 355 |
foreach ($elements as $id) { |
| 356 |
acym_query('DELETE FROM #__acym_mail_has_list WHERE list_id = '.intval($id)); |
| 357 |
acym_query('DELETE FROM #__acym_user_has_list WHERE list_id = '.intval($id)); |
| 358 |
acym_query('DELETE FROM #__acym_tag WHERE `id_element` = '.intval($id).' AND `type` = "list"'); |
| 359 |
} |
| 360 |
|
| 361 |
return parent::delete($elements); |
| 362 |
} |
| 363 |
|
| 364 |
public function synchDeleteCmsList(int $userId): void |
| 365 |
{ |
| 366 |
$query = 'SELECT * FROM #__acym_list WHERE type = "'.self::LIST_TYPE_FRONT.'" AND cms_user_id = '.intval($userId); |
| 367 |
$listFrontManagement = acym_loadObject($query); |
| 368 |
if (!empty($listFrontManagement)) { |
| 369 |
$this->delete([$listFrontManagement->id]); |
| 370 |
} |
| 371 |
} |
| 372 |
|
| 373 |
public function save(object $list): ?int |
| 374 |
{ |
| 375 |
if (isset($list->tags)) { |
| 376 |
$tags = $list->tags; |
| 377 |
unset($list->tags); |
| 378 |
} |
| 379 |
|
| 380 |
$oldList = null; |
| 381 |
|
| 382 |
if (empty($list->id)) { |
| 383 |
if (empty($list->cms_user_id)) { |
| 384 |
$list->cms_user_id = acym_currentUserId(); |
| 385 |
} |
| 386 |
|
| 387 |
$list->creation_date = acym_date('now', 'Y-m-d H:i:s', false); |
| 388 |
} else { |
| 389 |
$oldList = $this->getOneById($list->id); |
| 390 |
} |
| 391 |
|
| 392 |
if (!empty($list->translation)) { |
| 393 |
if (is_array($list->translation)) $list->translation = json_encode($list->translation); |
| 394 |
} else { |
| 395 |
$list->translation = ''; |
| 396 |
} |
| 397 |
|
| 398 |
foreach ($list as $oneAttribute => $value) { |
| 399 |
if (empty($value)) continue; |
| 400 |
|
| 401 |
$list->$oneAttribute = strip_tags($value); |
| 402 |
} |
| 403 |
|
| 404 |
if (empty($list->description)) { |
| 405 |
$list->description = ''; |
| 406 |
} |
| 407 |
|
| 408 |
if (!isset($list->access) && empty($list->id)) { |
| 409 |
$list->access = ''; |
| 410 |
} |
| 411 |
|
| 412 |
if (empty($list->id)) { |
| 413 |
acym_trigger('onAcymBeforeListCreate', [&$list]); |
| 414 |
} else { |
| 415 |
acym_trigger('onAcymBeforeListModify', [&$list]); |
| 416 |
} |
| 417 |
|
| 418 |
$listID = parent::save($list); |
| 419 |
|
| 420 |
if (empty($listID)) { |
| 421 |
return null; |
| 422 |
} |
| 423 |
|
| 424 |
if (isset($tags)) { |
| 425 |
$tagClass = new TagClass(); |
| 426 |
$tagClass->setTags(TagClass::TYPE_LIST, intval($listID), $tags); |
| 427 |
} |
| 428 |
|
| 429 |
$list->id = $listID; |
| 430 |
|
| 431 |
if (is_null($oldList)) { |
| 432 |
acym_trigger('onAcymAfterListCreate', [&$list]); |
| 433 |
} else { |
| 434 |
acym_trigger('onAcymAfterListModify', [&$list, &$oldList]); |
| 435 |
} |
| 436 |
|
| 437 |
return $listID; |
| 438 |
} |
| 439 |
|
| 440 |
public function getAllWithIdName(): array |
| 441 |
{ |
| 442 |
$endQuery = ''; |
| 443 |
if (!acym_isAdmin()) { |
| 444 |
$creatorId = acym_currentUserId(); |
| 445 |
|
| 446 |
$userGroups = acym_getGroupsByUser($creatorId); |
| 447 |
$groupCondition = '(access LIKE "%,'.implode(',%" OR access LIKE "%,', $userGroups).',%")'; |
| 448 |
|
| 449 |
$endQuery = ' AND (cms_user_id = '.intval($creatorId).' OR '.$groupCondition.')'; |
| 450 |
} |
| 451 |
$lists = acym_loadObjectList('SELECT id, name FROM #__acym_list WHERE type = '.acym_escapeDB(self::LIST_TYPE_STANDARD).$endQuery, 'id'); |
| 452 |
|
| 453 |
$listsToReturn = []; |
| 454 |
|
| 455 |
foreach ($lists as $key => $list) { |
| 456 |
$listsToReturn[$key] = $list->name; |
| 457 |
} |
| 458 |
|
| 459 |
return $listsToReturn; |
| 460 |
} |
| 461 |
|
| 462 |
public function getAllForSelect(bool $emptyFirst = true, int $userFrontID = 0, bool $needTranslation = false, bool $needFrontLabel = false): array |
| 463 |
{ |
| 464 |
$groupCondition = ''; |
| 465 |
if (!empty($userFrontID)) { |
| 466 |
$userGroups = acym_getGroupsByUser($userFrontID); |
| 467 |
$groupCondition = ' AND (cms_user_id = '.intval($userFrontID).' OR (access LIKE "%,'.implode(',%" OR access LIKE "%,', $userGroups).',%"))'; |
| 468 |
} |
| 469 |
|
| 470 |
$lists = acym_loadObjectList('SELECT * FROM #__acym_list WHERE type = '.acym_escapeDB(self::LIST_TYPE_STANDARD).$groupCondition, 'id'); |
| 471 |
|
| 472 |
if (acym_isMultilingual() && $needTranslation) { |
| 473 |
$lists = $this->getTranslatedNameDescription($lists); |
| 474 |
} |
| 475 |
|
| 476 |
$return = []; |
| 477 |
|
| 478 |
if ($emptyFirst) { |
| 479 |
$return[''] = acym_translation('ACYM_SELECT_A_LIST'); |
| 480 |
} |
| 481 |
|
| 482 |
foreach ($lists as $key => $list) { |
| 483 |
$return[$key] = $needFrontLabel && !empty($list->display_name) ? $list->display_name : $list->name; |
| 484 |
} |
| 485 |
|
| 486 |
return $return; |
| 487 |
} |
| 488 |
|
| 489 |
public function getAllWithoutManagement(bool $needTranslation = false): array |
| 490 |
{ |
| 491 |
$lists = acym_loadObjectList('SELECT * FROM #__acym_list WHERE `type` = '.acym_escapeDB(self::LIST_TYPE_STANDARD), 'id'); |
| 492 |
|
| 493 |
if (acym_isMultilingual() && $needTranslation) { |
| 494 |
$lists = $this->getTranslatedNameDescription($lists); |
| 495 |
} |
| 496 |
|
| 497 |
return $lists; |
| 498 |
} |
| 499 |
|
| 500 |
public function getTranslatedNameDescription(array $lists): array |
| 501 |
{ |
| 502 |
$currentLanguageTag = acym_getLanguageTag(); |
| 503 |
foreach ($lists as $id => $list) { |
| 504 |
if (empty($list->translation)) continue; |
| 505 |
|
| 506 |
$list->translation = json_decode($list->translation, true); |
| 507 |
if (!empty($list->translation[$currentLanguageTag])) { |
| 508 |
if (!empty($list->translation[$currentLanguageTag]['name'])) { |
| 509 |
$list->name = $list->translation[$currentLanguageTag]['name']; |
| 510 |
} |
| 511 |
|
| 512 |
if (!empty($list->translation[$currentLanguageTag]['display_name'])) { |
| 513 |
$list->display_name = $list->translation[$currentLanguageTag]['display_name']; |
| 514 |
} |
| 515 |
|
| 516 |
if (!empty($list->translation[$currentLanguageTag]['description'])) { |
| 517 |
$list->description = $list->translation[$currentLanguageTag]['description']; |
| 518 |
} |
| 519 |
} |
| 520 |
} |
| 521 |
|
| 522 |
return $lists; |
| 523 |
} |
| 524 |
|
| 525 |
public function sendWelcome(int $userID, array $listIDs, bool $forceFront = false): void |
| 526 |
{ |
| 527 |
if (!$forceFront && acym_isAdmin()) { |
| 528 |
return; |
| 529 |
} |
| 530 |
|
| 531 |
acym_arrayToInteger($listIDs); |
| 532 |
if (empty($listIDs)) { |
| 533 |
return; |
| 534 |
} |
| 535 |
|
| 536 |
$messages = acym_loadObjectList('SELECT `welcome_id` FROM #__acym_list WHERE `id` IN ('.implode(',', $listIDs).') AND `active` = 1'); |
| 537 |
|
| 538 |
if (empty($messages)) { |
| 539 |
return; |
| 540 |
} |
| 541 |
|
| 542 |
$alreadySent = []; |
| 543 |
$mailerHelper = new MailerHelper(); |
| 544 |
$mailerHelper->report = (bool)$this->config->get('welcome_message', 1); |
| 545 |
foreach ($messages as $oneMessage) { |
| 546 |
$mailid = $oneMessage->welcome_id; |
| 547 |
if (empty($mailid)) continue; |
| 548 |
|
| 549 |
if (isset($alreadySent[$mailid])) { |
| 550 |
continue; |
| 551 |
} |
| 552 |
|
| 553 |
$mailerHelper->trackEmail = true; |
| 554 |
$mailerHelper->sendOne($mailid, $userID); |
| 555 |
$alreadySent[$mailid] = true; |
| 556 |
} |
| 557 |
} |
| 558 |
|
| 559 |
public function sendUnsubscribe(int $userID, array $listIDs): void |
| 560 |
{ |
| 561 |
if (acym_isAdmin()) { |
| 562 |
return; |
| 563 |
} |
| 564 |
|
| 565 |
acym_arrayToInteger($listIDs); |
| 566 |
if (empty($listIDs)) { |
| 567 |
return; |
| 568 |
} |
| 569 |
|
| 570 |
$messages = acym_loadObjectList('SELECT `unsubscribe_id` FROM #__acym_list WHERE `id` IN ('.implode(',', $listIDs).') AND `active` = 1'); |
| 571 |
|
| 572 |
if (empty($messages)) { |
| 573 |
return; |
| 574 |
} |
| 575 |
|
| 576 |
$alreadySent = []; |
| 577 |
$mailerHelper = new MailerHelper(); |
| 578 |
$mailerHelper->report = (bool)$this->config->get('unsub_message', 1); |
| 579 |
foreach ($messages as $oneMessage) { |
| 580 |
if (!empty($oneMessage->unsubscribe_id)) { |
| 581 |
$mailid = $oneMessage->unsubscribe_id; |
| 582 |
|
| 583 |
if (isset($alreadySent[$mailid])) { |
| 584 |
continue; |
| 585 |
} |
| 586 |
|
| 587 |
$mailerHelper->trackEmail = true; |
| 588 |
$mailerHelper->sendOne($mailid, $userID); |
| 589 |
$alreadySent[$mailid] = true; |
| 590 |
} |
| 591 |
} |
| 592 |
} |
| 593 |
|
| 594 |
public function addDefaultList() |
| 595 |
{ |
| 596 |
$listId = acym_loadResult('SELECT `id` FROM #__acym_list LIMIT 1'); |
| 597 |
if (empty($listId)) { |
| 598 |
$defaultList = new \stdClass(); |
| 599 |
$defaultList->name = 'Newsletters'; |
| 600 |
$defaultList->color = '#3366ff'; |
| 601 |
$defaultList->description = ''; |
| 602 |
|
| 603 |
$this->save($defaultList); |
| 604 |
} |
| 605 |
} |
| 606 |
|
| 607 |
public function getTotalSubCount(array $ids): int |
| 608 |
{ |
| 609 |
if (empty($ids)) { |
| 610 |
return 0; |
| 611 |
} |
| 612 |
|
| 613 |
acym_arrayToInteger($ids); |
| 614 |
$this->onlyManageableLists($ids); |
| 615 |
$query = 'SELECT COUNT(DISTINCT hasList.user_id) |
| 616 |
FROM #__acym_user_has_list AS hasList |
| 617 |
JOIN #__acym_user AS user |
| 618 |
ON hasList.user_id = user.id |
| 619 |
WHERE hasList.status = 1 |
| 620 |
AND user.active = 1 |
| 621 |
AND hasList.list_id IN ('.implode(',', $ids).')'; |
| 622 |
|
| 623 |
|
| 624 |
if ($this->config->get('require_confirmation', 1) == 1) { |
| 625 |
$query .= ' AND user.confirmed = 1 '; |
| 626 |
} |
| 627 |
|
| 628 |
return intval(acym_loadResult($query)); |
| 629 |
} |
| 630 |
|
| 631 |
public function getMailsByListId(int $listId): array |
| 632 |
{ |
| 633 |
$mailIds = acym_loadResultArray('SELECT mail_id FROM #__acym_mail_has_list WHERE list_id = '.intval($listId)); |
| 634 |
|
| 635 |
return empty($mailIds) ? [] : $mailIds; |
| 636 |
} |
| 637 |
|
| 638 |
public function getSubscribersCountPerStatusByListIds(array $listIds = []): array |
| 639 |
{ |
| 640 |
$condList = ''; |
| 641 |
if (!empty($listIds)) { |
| 642 |
acym_arrayToInteger($listIds); |
| 643 |
$condList = 'AND userList.list_id IN ('.implode(',', $listIds).')'; |
| 644 |
} |
| 645 |
|
| 646 |
$query = 'SELECT userList.list_id, COUNT(userList.user_id) AS users, acyuser.confirmed + acyuser.active*2 AS score |
| 647 |
FROM #__acym_user_has_list AS userList |
| 648 |
JOIN #__acym_user AS acyuser |
| 649 |
ON acyuser.id = userList.user_id |
| 650 |
WHERE userList.status = 1 |
| 651 |
'.$condList.' |
| 652 |
GROUP BY score, userList.list_id'; |
| 653 |
$results = acym_loadObjectList($query); |
| 654 |
|
| 655 |
$confirmationRequired = $this->config->get('require_confirmation', 1); |
| 656 |
$listsUserStats = []; |
| 657 |
foreach ($results as $oneResult) { |
| 658 |
if (!isset($listsUserStats[$oneResult->list_id])) { |
| 659 |
$listsUserStats[$oneResult->list_id] = $this->initList($oneResult->list_id); |
| 660 |
} |
| 661 |
|
| 662 |
$oneResult->score = (string)$oneResult->score; |
| 663 |
|
| 664 |
if (in_array($oneResult->score, ['0', '1'])) { |
| 665 |
$listsUserStats[$oneResult->list_id]->inactive_users += $oneResult->users; |
| 666 |
} |
| 667 |
|
| 668 |
if (in_array($oneResult->score, ['0', '2'])) { |
| 669 |
$listsUserStats[$oneResult->list_id]->unconfirmed_users += $oneResult->users; |
| 670 |
} |
| 671 |
|
| 672 |
if ($oneResult->score === '3' || ($confirmationRequired != 1 && $oneResult->score == '2')) { |
| 673 |
$listsUserStats[$oneResult->list_id]->sendable_users += $oneResult->users; |
| 674 |
} |
| 675 |
} |
| 676 |
|
| 677 |
$query = 'SELECT userList.list_id, COUNT(userList.user_id) AS users |
| 678 |
FROM #__acym_user_has_list AS userList |
| 679 |
WHERE userList.status = 0 |
| 680 |
'.$condList.' |
| 681 |
GROUP BY userList.list_id'; |
| 682 |
$unsubscribed = acym_loadObjectList($query); |
| 683 |
|
| 684 |
foreach ($unsubscribed as $oneList) { |
| 685 |
if (!isset($listsUserStats[$oneList->list_id])) { |
| 686 |
$listsUserStats[$oneList->list_id] = $this->initList($oneList->list_id); |
| 687 |
} |
| 688 |
$listsUserStats[$oneList->list_id]->unsubscribed_users = $oneList->users; |
| 689 |
} |
| 690 |
|
| 691 |
return $listsUserStats; |
| 692 |
} |
| 693 |
|
| 694 |
public function getSubscribersEvolutionByListIds(array $listIds): array |
| 695 |
{ |
| 696 |
$condList = ''; |
| 697 |
if (!empty($listIds)) { |
| 698 |
acym_arrayToInteger($listIds); |
| 699 |
$condList = ' AND list_id IN ('.implode(',', $listIds).')'; |
| 700 |
} |
| 701 |
$dateNow = acym_loadResult('SELECT DATE_SUB(NOW(), INTERVAL 1 MONTH)'); |
| 702 |
$queryEvolSub = 'SELECT list_id, COUNT(*) AS newSub FROM #__acym_user_has_list'; |
| 703 |
$queryEvolSub .= ' WHERE subscription_date > '.acym_escapeDB($dateNow).' '.$condList; |
| 704 |
$queryEvolSub .= ' GROUP BY list_id'; |
| 705 |
$evolSubscibers = acym_loadObjectList($queryEvolSub, 'list_id'); |
| 706 |
|
| 707 |
$queryEvolUnsub = 'SELECT list_id, COUNT(*) AS newUnsub FROM #__acym_user_has_list'; |
| 708 |
$queryEvolUnsub .= ' WHERE unsubscribe_date > '.acym_escapeDB($dateNow).' '.$condList; |
| 709 |
$queryEvolUnsub .= ' GROUP BY list_id'; |
| 710 |
$newUnsubscribers = acym_loadObjectList($queryEvolUnsub, 'list_id'); |
| 711 |
|
| 712 |
foreach ($newUnsubscribers as $listId => $oneUnsub) { |
| 713 |
if (empty($evolSubscibers[$listId])) { |
| 714 |
$evolSubscibers[$listId] = new \stdClass(); |
| 715 |
} |
| 716 |
$evolSubscibers[$listId]->newUnsub = $oneUnsub->newUnsub; |
| 717 |
} |
| 718 |
|
| 719 |
return $evolSubscibers; |
| 720 |
} |
| 721 |
|
| 722 |
public function getYearSubEvolutionPerList(int $listId): array |
| 723 |
{ |
| 724 |
$month = date('n') + 1; |
| 725 |
$year = date('Y') - 1; |
| 726 |
$initDate = $year.'-'.$month.'-01'; |
| 727 |
if ($month == 13) { |
| 728 |
$initDate = date('Y').'-01-01'; |
| 729 |
} |
| 730 |
|
| 731 |
$queryEvolSub = 'SELECT MONTH(subscription_date) as monthSub, DATE_FORMAT(subscription_date,"%Y_%m") AS unit, COUNT(user_id) AS nbUser'; |
| 732 |
$queryEvolSub .= ' FROM `#__acym_user_has_list`'; |
| 733 |
$queryEvolSub .= ' WHERE subscription_date >= "'.$initDate.'" AND list_id = '.$listId; |
| 734 |
$queryEvolSub .= ' GROUP BY unit'; |
| 735 |
$evolSubscibers = acym_loadObjectList($queryEvolSub, 'unit'); |
| 736 |
|
| 737 |
$queryEvolUnsub = 'SELECT MONTH(unsubscribe_date) as monthUnsub, DATE_FORMAT(unsubscribe_date,"%Y_%m") AS unit, COUNT(user_id) AS nbUser'; |
| 738 |
$queryEvolUnsub .= ' FROM `#__acym_user_has_list`'; |
| 739 |
$queryEvolUnsub .= ' WHERE unsubscribe_date >= "'.$initDate.'" AND list_id = '.$listId; |
| 740 |
$queryEvolUnsub .= ' GROUP BY unit'; |
| 741 |
$evolUnsubscibers = acym_loadObjectList($queryEvolUnsub, 'unit'); |
| 742 |
|
| 743 |
return [ |
| 744 |
'subscribers' => $evolSubscibers, |
| 745 |
'unsubscribers' => $evolUnsubscibers, |
| 746 |
]; |
| 747 |
} |
| 748 |
|
| 749 |
private function initList(int $listId): object |
| 750 |
{ |
| 751 |
$list = new \stdClass(); |
| 752 |
$list->list_id = $listId; |
| 753 |
$list->sendable_users = 0; |
| 754 |
$list->unconfirmed_users = 0; |
| 755 |
$list->inactive_users = 0; |
| 756 |
$list->unsubscribed_users = 0; |
| 757 |
|
| 758 |
return $list; |
| 759 |
} |
| 760 |
|
| 761 |
public function getManageableLists(): array |
| 762 |
{ |
| 763 |
$idCurrentUser = acym_currentUserId(); |
| 764 |
if (empty($idCurrentUser)) { |
| 765 |
return []; |
| 766 |
} |
| 767 |
|
| 768 |
$userGroups = acym_getGroupsByUser($idCurrentUser); |
| 769 |
|
| 770 |
return acym_loadResultArray( |
| 771 |
'SELECT id |
| 772 |
FROM #__acym_list |
| 773 |
WHERE cms_user_id = '.intval($idCurrentUser).' |
| 774 |
OR (access LIKE "%,'.implode(',%" OR access LIKE "%,', $userGroups).',%")' |
| 775 |
); |
| 776 |
} |
| 777 |
|
| 778 |
public function onlyManageableLists(&$elements): void |
| 779 |
{ |
| 780 |
if (acym_isAdmin()) { |
| 781 |
return; |
| 782 |
} |
| 783 |
|
| 784 |
$manageableLists = $this->getManageableLists(); |
| 785 |
$elements = array_intersect($elements, $manageableLists); |
| 786 |
} |
| 787 |
|
| 788 |
public function hasUserAccess(int $listId): bool |
| 789 |
{ |
| 790 |
if (acym_isAdmin()) { |
| 791 |
return true; |
| 792 |
} |
| 793 |
|
| 794 |
return in_array($listId, $this->getManageableLists()); |
| 795 |
} |
| 796 |
|
| 797 |
public function getfrontManagementList(): int |
| 798 |
{ |
| 799 |
$idCurrentUser = acym_currentUserId(); |
| 800 |
if (empty($idCurrentUser)) { |
| 801 |
return 0; |
| 802 |
} |
| 803 |
|
| 804 |
$frontListId = acym_loadResult('SELECT id FROM #__acym_list WHERE type = '.acym_escapeDB(self::LIST_TYPE_FRONT).' AND cms_user_id = '.intval($idCurrentUser)); |
| 805 |
|
| 806 |
if (!empty($frontListId)) { |
| 807 |
return $frontListId; |
| 808 |
} |
| 809 |
|
| 810 |
$frontList = new \stdClass(); |
| 811 |
$frontList->name = 'frontlist_'.$idCurrentUser; |
| 812 |
$frontList->active = 1; |
| 813 |
$frontList->visible = 0; |
| 814 |
$frontList->cms_user_id = $idCurrentUser; |
| 815 |
$frontList->type = self::LIST_TYPE_FRONT; |
| 816 |
|
| 817 |
return (int)$this->save($frontList); |
| 818 |
} |
| 819 |
|
| 820 |
public function setWelcomeUnsubEmail(array $listIds, int $mailId, string $type): bool |
| 821 |
{ |
| 822 |
if (!in_array($type, [MailClass::TYPE_WELCOME, MailClass::TYPE_UNSUBSCRIBE]) || empty($mailId)) { |
| 823 |
return false; |
| 824 |
} |
| 825 |
|
| 826 |
$column = acym_escape($type).'_id'; |
| 827 |
$columnsList = acym_getColumns('list'); |
| 828 |
if (!in_array($column, $columnsList)) { |
| 829 |
return false; |
| 830 |
} |
| 831 |
|
| 832 |
if (!$this->removeWelcomeUnsubByMailId($mailId, $listIds, $column)) { |
| 833 |
return false; |
| 834 |
} |
| 835 |
|
| 836 |
foreach ($listIds as $listId) { |
| 837 |
$list = $this->getOneById($listId); |
| 838 |
if (empty($list)) { |
| 839 |
return false; |
| 840 |
} |
| 841 |
|
| 842 |
$list->{$column} = $mailId; |
| 843 |
|
| 844 |
$savedListId = $this->save($list); |
| 845 |
if (empty($savedListId)) { |
| 846 |
return false; |
| 847 |
} |
| 848 |
} |
| 849 |
|
| 850 |
return true; |
| 851 |
} |
| 852 |
|
| 853 |
private function removeWelcomeUnsubByMailId(int $mailId, array $listIds, string $column): bool |
| 854 |
{ |
| 855 |
if (empty($mailId)) { |
| 856 |
return false; |
| 857 |
} |
| 858 |
|
| 859 |
$query = 'SELECT * FROM #__acym_list WHERE '.acym_secureDBColumn($column).' = '.$mailId; |
| 860 |
|
| 861 |
if (!empty($listIds)) { |
| 862 |
acym_arrayToInteger($listIds); |
| 863 |
$query .= ' AND `id` NOT IN ('.implode(',', $listIds).')'; |
| 864 |
} |
| 865 |
|
| 866 |
$lists = acym_loadObjectList($query); |
| 867 |
if (empty($lists)) { |
| 868 |
return true; |
| 869 |
} |
| 870 |
|
| 871 |
foreach ($lists as $list) { |
| 872 |
$list->{$column} = null; |
| 873 |
|
| 874 |
$savedListId = $this->save($list); |
| 875 |
if (empty($savedListId)) { |
| 876 |
return false; |
| 877 |
} |
| 878 |
} |
| 879 |
|
| 880 |
return true; |
| 881 |
} |
| 882 |
|
| 883 |
public function getListIdsByWelcomeUnsub(int $mailId, bool $welcome = true): array |
| 884 |
{ |
| 885 |
$type = $welcome ? 'welcome_id' : 'unsubscribe_id'; |
| 886 |
|
| 887 |
$return = acym_loadResultArray('SELECT id FROM #__acym_list WHERE '.$type.' = '.intval($mailId)); |
| 888 |
|
| 889 |
return empty($return) ? [] : $return; |
| 890 |
} |
| 891 |
|
| 892 |
public function getUsersForSummaryModal(int $id, int $offset, int $limit, string $search): array |
| 893 |
{ |
| 894 |
$whereQuery = ' AND user_list.status = 1 AND user.active = 1'; |
| 895 |
|
| 896 |
if (!empty($search)) { |
| 897 |
$search = acym_escapeDB('%'.$search.'%'); |
| 898 |
$whereQuery .= ' AND (user.email LIKE '.$search.' OR user.name LIKE '.$search.' OR user.id LIKE '.$search.') '; |
| 899 |
} |
| 900 |
|
| 901 |
if ($this->config->get('require_confirmation', '1') === '1') { |
| 902 |
$whereQuery .= ' AND user.confirmed = 1'; |
| 903 |
} |
| 904 |
|
| 905 |
$query = 'SELECT user.email, user.name, user.id |
| 906 |
FROM #__acym_user as user |
| 907 |
JOIN #__acym_user_has_list as user_list ON user.id = user_list.user_id |
| 908 |
WHERE user_list.list_id = '.intval($id).$whereQuery.' LIMIT '.intval($offset).', '.intval($limit); |
| 909 |
|
| 910 |
|
| 911 |
return acym_loadObjectList($query, 'id'); |
| 912 |
} |
| 913 |
|
| 914 |
public function getXLists(array $options = []): array |
| 915 |
{ |
| 916 |
$limit = $options['limit'] ?? 10; |
| 917 |
$offset = $options['offset'] ?? 0; |
| 918 |
$filters = $options['filters'] ?? ['type' => self::LIST_TYPE_STANDARD]; |
| 919 |
|
| 920 |
$conditions = []; |
| 921 |
foreach ($filters as $column => $filter) { |
| 922 |
switch ($column) { |
| 923 |
case 'id': |
| 924 |
case 'active': |
| 925 |
case 'visible': |
| 926 |
case 'clean': |
| 927 |
case 'welcome_id': |
| 928 |
case 'unsubscribe_id': |
| 929 |
case 'cms_user_id': |
| 930 |
case 'tracking': |
| 931 |
$conditions[] = acym_secureDBColumn($column).' = '.intval($filter); |
| 932 |
break; |
| 933 |
default: |
| 934 |
$conditions[] = acym_secureDBColumn($column).' LIKE '.acym_escapeDB('%'.$filter.'%'); |
| 935 |
} |
| 936 |
} |
| 937 |
|
| 938 |
$query = 'SELECT * FROM #__acym_list'; |
| 939 |
if (!empty($conditions)) { |
| 940 |
$query .= ' WHERE '.implode(' AND ', $conditions); |
| 941 |
} |
| 942 |
|
| 943 |
return acym_loadObjectList($query, $this->pkey, $offset, $limit); |
| 944 |
} |
| 945 |
|
| 946 |
public function getOneList(): bool |
| 947 |
{ |
| 948 |
$firstList = acym_loadObject('SELECT * FROM #__acym_list WHERE `id` != 1'); |
| 949 |
|
| 950 |
return !empty($firstList); |
| 951 |
} |
| 952 |
|
| 953 |
public function getMostUsedLists(): array |
| 954 |
{ |
| 955 |
return acym_loadObjectList( |
| 956 |
'SELECT list_id |
| 957 |
FROM #__acym_mail_has_list |
| 958 |
GROUP BY list_id |
| 959 |
ORDER BY COUNT(*) DESC |
| 960 |
LIMIT 5' |
| 961 |
); |
| 962 |
} |
| 963 |
|
| 964 |
public function getListsSubscribersAndUnsubscribeUsersFromUserHasList(): array |
| 965 |
{ |
| 966 |
$query = 'SELECT list_id, |
| 967 |
SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) AS subscribers, |
| 968 |
SUM(CASE WHEN status = 0 THEN 1 ELSE 0 END) AS unsubscribed_users |
| 969 |
FROM `#__acym_user_has_list` |
| 970 |
GROUP BY list_id'; |
| 971 |
|
| 972 |
return acym_loadObjectList($query); |
| 973 |
} |
| 974 |
|
| 975 |
public function updateListsSubscribersAndUnsubscribeUsers(int $listId, int $subscribers, int $unsubscribeUsers, int $new_sub, int $new_unsub): void |
| 976 |
{ |
| 977 |
acym_query( |
| 978 |
'UPDATE `#__acym_list` |
| 979 |
SET `subscribers` = '.$subscribers.', `unsubscribed_users` = '.$unsubscribeUsers.', `new_sub` = '.$new_sub.', `new_unsub` = '.$new_unsub.' |
| 980 |
WHERE id = '.$listId |
| 981 |
); |
| 982 |
} |
| 983 |
|
| 984 |
public function getMostUsedListsByIdsWithSubscribersData(array $ids = []): array |
| 985 |
{ |
| 986 |
if (empty($ids)) { |
| 987 |
return []; |
| 988 |
} |
| 989 |
acym_arrayToInteger($ids); |
| 990 |
$query = 'SELECT name, subscribers, unsubscribed_users, new_sub, new_unsub FROM `#__acym_list` WHERE id IN ('.implode(', ', $ids).')'; |
| 991 |
|
| 992 |
return acym_loadObjectList($query); |
| 993 |
} |
| 994 |
|
| 995 |
public function getUserListEntries(array $userIds, array $listIds): array |
| 996 |
{ |
| 997 |
if (empty($userIds) || empty($listIds)) { |
| 998 |
return []; |
| 999 |
} |
| 1000 |
|
| 1001 |
$userIdsStr = implode(',', array_map('intval', $userIds)); |
| 1002 |
$listIdsStr = implode(',', array_map('intval', $listIds)); |
| 1003 |
|
| 1004 |
$query = 'SELECT * FROM `#__acym_user_has_list` |
| 1005 |
WHERE user_id IN ('.$userIdsStr.') AND list_id IN ('.$listIdsStr.')'; |
| 1006 |
|
| 1007 |
$results = acym_loadObjectList($query); |
| 1008 |
|
| 1009 |
$entries = []; |
| 1010 |
foreach ($results as $row) { |
| 1011 |
$key = $row->user_id.'_'.$row->list_id; |
| 1012 |
$entries[$key] = $row; |
| 1013 |
} |
| 1014 |
|
| 1015 |
return $entries; |
| 1016 |
} |
| 1017 |
} |
| 1018 |
|