PluginProbe
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress / 10.10.2
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress v10.10.2
11.1.1 11.1.0 11.0.5 11.0.4 11.0.3 11.0.2 11.0.1 11.0.0 10.11.1 10.11.0 10.10.2 10.10.1 10.10.0 10.9.1 trunk 10.0.0 10.0.1 10.1.0 10.1.1 10.1.2 10.1.3 10.1.4 10.2.0 10.2.1 10.2.2 All 62 releases
acymailing / back / Helpers / ImportHelper.php

ImportHelper.php in AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress 10.10.2, at back/Helpers/ImportHelper.php

1,233 lines 48.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace AcyMailing\Helpers;
4
5 use AcyMailing\Classes\ListClass;
6 use AcyMailing\Classes\UserClass;
7 use AcyMailing\Core\AcymObject;
8
9 class ImportHelper extends AcymObject
10 {
11 private array $subscribedUsers = [];
12 private array $importUserInLists = [];
13 private array $allUserIds = [];
14 private array $columns = [];
15 private int $totalTry = 0;
16 private int $totalValid = 0;
17 private int $separatorsToRemove = 0;
18 private bool $forceConfirm = false;
19 private bool $generateName = true;
20 private bool $overwrite = false;
21 private string $header = '';
22 private string $separator = ',';
23
24 public string $tableName = '';
25 public array $dbWhere = [];
26 public array $fieldsMap = [];
27 public array $subscriptionHistory = [];
28 public array $importedUsersByEmail = [];
29
30 public function __construct()
31 {
32 parent::__construct();
33 acym_increasePerf();
34 }
35
36 public function file(): bool
37 {
38 $importFile = acym_getVar('array', 'import_file', [], 'files');
39
40 if (empty($importFile['name'])) {
41 acym_enqueueMessage(acym_translation('ACYM_PLEASE_BROWSE_FILE_IMPORT'), 'error');
42
43 return false;
44 }
45
46 $extension = strtolower(acym_fileGetExt($importFile['name']));
47
48 if (!preg_match('#^(csv)$#Ui', $extension) || preg_match('#\.(php.?|.?htm.?|pl|py|jsp|asp|sh|cgi)$#Ui', $importFile['name'])) {
49 acym_enqueueMessage(acym_translationSprintf('ACYM_ACCEPTED_TYPE', acym_escape($extension), $this->config->get('allowed_files')), 'error');
50
51 return false;
52 }
53
54 $fileError = $importFile['error'];
55 if ($fileError > 0) {
56 switch ($fileError) {
57 case 1:
58 case 2:
59 acym_enqueueMessage(acym_translation('ACYM_UPLOADED_FILE_EXCEED_MAX_FILESIZE_PHP'), 'error');
60
61 return false;
62 case 3:
63 acym_enqueueMessage(acym_translation('ACYM_FILE_UPLOADED_PARTIALLY'), 'error');
64
65 return false;
66 case 4:
67 acym_enqueueMessage(acym_translation('ACYM_NO_FILE_WAS_UPLOADED'), 'error');
68
69 return false;
70 default:
71 acym_enqueueMessage(acym_translationSprintf('ACYM_UNKNOWN_ERROR_UPLOADING_FILE', $fileError), 'error');
72
73 return false;
74 }
75 }
76
77 $uploadPath = $this->createUploadFolder();
78
79 $filename = uniqid('import_').'.csv';
80 acym_setVar('acym_import_filename', $filename);
81
82 if (!acym_uploadFile($importFile['tmp_name'], $uploadPath.$filename)) {
83 if (!move_uploaded_file($importFile['tmp_name'], $uploadPath.$filename)) {
84 acym_enqueueMessage(
85 acym_translationSprintf(
86 'ACYM_FAIL_UPLOAD',
87 '<b><i>'.acym_escape($importFile['tmp_name']).'</i></b>',
88 '<b><i>'.acym_escape($uploadPath.$filename).'</i></b>'
89 ),
90 'error'
91 );
92 }
93 }
94
95 return true;
96 }
97
98 public function textarea(): bool
99 {
100 $content = acym_getVar('string', 'acym__users__import__from_text__textarea');
101 $path = $this->createUploadFolder();
102 $filename = uniqid('import_').'.csv';
103
104 acym_writeFile($path.$filename, $content);
105 acym_setVar('acym_import_filename', $filename);
106
107 return true;
108 }
109
110 public function cms(): bool
111 {
112 global $acymCmsUserVars;
113
114 $query = 'UPDATE IGNORE '.$acymCmsUserVars->table.' as b, #__acym_user as a SET a.email = b.'.$acymCmsUserVars->email.', a.name = b.'.$acymCmsUserVars->name.', a.active = 1 - b.'.$acymCmsUserVars->blocked.' WHERE a.cms_id = b.'.$acymCmsUserVars->id.' AND a.cms_id IS NOT NULL';
115 $nbUpdated = acym_query($query);
116
117 $query = 'UPDATE IGNORE '.$acymCmsUserVars->table.' as b, #__acym_user as a SET a.cms_id = b.'.$acymCmsUserVars->id.' WHERE a.email = b.'.$acymCmsUserVars->email;
118 $affected = acym_query($query);
119 $nbUpdated += intval($affected);
120
121 acym_enqueueMessage(acym_translationSprintf('ACYM_IMPORT_UPDATE', $nbUpdated), 'success');
122
123 $query = 'SELECT a.id FROM #__acym_user as a LEFT JOIN '.$acymCmsUserVars->table.' as b on a.cms_id = b.'.$acymCmsUserVars->id.' WHERE b.'.$acymCmsUserVars->id.' IS NULL AND a.cms_id > 0';
124 $deletedSubid = acym_loadResultArray($query);
125
126 $query = 'SELECT a.id FROM #__acym_user as a LEFT JOIN '.$acymCmsUserVars->table.' as b on a.email = b.'.$acymCmsUserVars->email.' WHERE b.'.$acymCmsUserVars->id.' IS NULL AND a.cms_id > 0';
127 $deletedSubid = array_merge(acym_loadResultArray($query), $deletedSubid);
128
129 if (!empty($deletedSubid)) {
130 $userClass = new UserClass();
131 $deletedUsers = $userClass->delete($deletedSubid);
132 acym_enqueueMessage(acym_translationSprintf('ACYM_IMPORT_DELETE', $deletedUsers));
133 }
134
135 $time = time();
136 $formattedTime = acym_date($time, 'Y-m-d H:i:s');
137 $sourceImport = 'Import on '.$formattedTime;
138 $query = 'INSERT IGNORE INTO #__acym_user (`name`,`email`,`creation_date`,`active`,`cms_id`, `source`) SELECT `user`.`'.$acymCmsUserVars->name.'`,`user`.`'.$acymCmsUserVars->email.'`,`user`.`'.$acymCmsUserVars->registered.'`,1 - `user`.'.$acymCmsUserVars->blocked.',`user`.`'.$acymCmsUserVars->id.'`,\''.$sourceImport.'\' FROM '.$acymCmsUserVars->table.' AS `user` ';
139
140 $queryJoin = [];
141 $queryWhere = [];
142 if (ACYM_CMS === 'wordpress' && is_multisite()) {
143 $queryJoin[] = 'JOIN #__usermeta AS `meta` ON `user`.'.$acymCmsUserVars->id.'=`meta`.`user_id`';
144 $queryWhere[] = '`meta`.`meta_key`=\'#__capabilities\'';
145 }
146 $groups = acym_getVar('array', 'groups', []);
147 $this->config->saveConfig(['import_groups' => implode(',', $groups)]);
148 if (!empty($groups)) {
149 if (ACYM_CMS === 'joomla') {
150 acym_arrayToInteger($groups);
151 $queryJoin[] = ' JOIN #__user_usergroup_map AS `map` ON map.user_id = `user`.`'.$acymCmsUserVars->id.'`';
152 $queryWhere[] = '`map`.`group_id` IN ('.implode(', ', $groups).')';
153 } else {
154 if (!is_multisite()) {
155 $queryJoin[] = 'JOIN #__usermeta AS `meta` ON meta.user_id = `user`.`'.$acymCmsUserVars->id.'` AND `meta`.`meta_key` = "#__capabilities"';
156 }
157
158 foreach ($groups as $i => $oneGroup) {
159 $groups[$i] = acym_escapeDB('%'.strlen($oneGroup).':"'.$oneGroup.'"%');
160 }
161 $queryWhere[] = '`meta`.`meta_value` LIKE '.implode(' OR `meta`.`meta_value` LIKE ', $groups);
162 }
163 }
164
165 $query .= implode(' ', $queryJoin);
166 if (!empty($queryWhere)) {
167 $query .= ' WHERE ('.implode(') AND (', $queryWhere).')';
168 }
169
170 $insertedUsers = acym_query($query);
171
172 acym_query('UPDATE #__acym_configuration SET `value` = '.intval($time).' WHERE `name` = \'last_import\'');
173
174 acym_trigger('onAcymAfterCMSUserImport', [$sourceImport]);
175
176 acym_enqueueMessage(acym_translationSprintf('ACYM_IMPORT_NEW_SUBS', $insertedUsers), 'info');
177
178 $lists = $this->getImportedLists();
179 $listsSubscribe = [];
180 if (!empty($lists)) {
181 foreach ($lists as $listid => $val) {
182 if (!empty($val)) {
183 $listsSubscribe[] = intval($listid);
184 }
185 }
186 }
187
188 if (empty($listsSubscribe)) {
189 return true;
190 }
191
192 $query = 'INSERT IGNORE INTO #__acym_user_has_list (`user_id`,`list_id`,`status`,`subscription_date`) ';
193 $query .= 'SELECT user.`id`, list.`id`, 1, '.acym_escapeDB(date('Y-m-d H:i:s', time() - date('Z'))).'
194 FROM #__acym_list AS list, #__acym_user AS user ';
195 $conditions = [];
196 $conditions[] = 'list.`id` IN ('.implode(',', $listsSubscribe).')';
197 $conditions[] = 'user.`cms_id` > 0';
198
199 if (!empty($groups)) {
200 if (ACYM_CMS === 'joomla') {
201 $query .= ' JOIN #__user_usergroup_map AS `map` ON map.user_id = `user`.`cms_id`';
202 $conditions[] = '`map`.`group_id` IN ('.implode(', ', $groups).')';
203 } else {
204 $query .= ' JOIN #__usermeta AS `meta` ON meta.user_id = `user`.`cms_id` AND `meta`.`meta_key` = "#__capabilities"';
205 $conditions[] = '`meta`.`meta_value` LIKE ('.implode(' OR `meta`.`meta_value` LIKE ', $groups).')';
206 }
207 }
208
209 $query .= ' WHERE '.implode(' AND ', $conditions);
210 $nbsubscribed = acym_query($query);
211 acym_enqueueMessage(acym_translationSprintf('ACYM_IMPORT_SUBSCRIPTION', $nbsubscribed));
212
213 return true;
214 }
215
216
217 public function database(bool $onlyImport = false): bool
218 {
219 $this->forceConfirm = acym_getVar('bool', 'import_confirmed_database', true);
220
221 $table = empty($this->tableName) ? trim(acym_getVar('string', 'tablename')) : $this->tableName;
222 $time = time();
223 $formattedTime = acym_date($time, 'Y-m-d H:i:s');
224
225 if (empty($table)) {
226 acym_enqueueMessage(acym_translation('ACYM_SPECIFYTABLE'), 'warning');
227
228 return false;
229 }
230
231 $fields = acym_getColumns($table, false, false);
232 if (empty($fields)) {
233 acym_enqueueMessage(acym_translation('ACYM_SPECIFYTABLE'), 'warning');
234
235 return false;
236 }
237
238 $equivalentFields = empty($this->fieldsMap) ? acym_getVar('array', 'fields', []) : $this->fieldsMap;
239
240 if (empty($equivalentFields['email'])) {
241 acym_enqueueMessage(acym_translation('ACYM_SPECIFYFIELDEMAIL'), 'warning');
242
243 return false;
244 }
245
246 $select = [];
247 foreach ($equivalentFields as $acyField => $tableField) {
248 $tableField = trim($tableField);
249 if (empty($tableField)) {
250 continue;
251 }
252 if (!in_array($tableField, $fields)) {
253 acym_enqueueMessage(acym_translationSprintf('ACYM_SPECIFYFIELD', $tableField, implode(' <br> ', $fields)), 'warning');
254
255 return false;
256 }
257 $select['`'.acym_secureDBColumn($acyField).'`'] = acym_secureDBColumn($tableField);
258 }
259
260 if (empty($select['`creation_date`'])) {
261 $select['`creation_date`'] = acym_escapeDB(acym_date('now', 'Y-m-d H:i:s'));
262 }
263
264 if ($this->forceConfirm && empty($select['`confirmed`'])) {
265 $select['`confirmed`'] = 1;
266 }
267
268 $sourceTxt = 'Import on '.$formattedTime;
269 $select['`source`'] = acym_escapeDB($sourceTxt);
270
271 $query = 'INSERT IGNORE INTO #__acym_user ('.implode(' , ', array_keys($select)).') SELECT '.implode(' , ', $select);
272 $query .= ' FROM '.acym_secureDBColumn($table).' WHERE '.acym_secureDBColumn($select['`email`']).' LIKE "%@%"';
273 if (!empty($this->dbWhere)) {
274 $query .= ' AND ( '.implode(' ) AND (', $this->dbWhere).' )';
275 }
276
277 $affectedRows = acym_query($query);
278
279 acym_query('UPDATE #__acym_configuration SET `value` = '.intval($time).' WHERE `name` = "last_import"');
280
281 acym_trigger('onAcymAfterDatabaseUserImport', [$sourceTxt]);
282
283 if ($onlyImport) {
284 return true;
285 }
286
287 acym_enqueueMessage(acym_translationSprintf('ACYM_IMPORT_NEW_SUBS', $affectedRows), 'info');
288
289
290 $lists = $this->getImportedLists();
291 $listsSubscribe = [];
292 if (!empty($lists)) {
293 foreach ($lists as $listid => $val) {
294 if (!empty($val)) {
295 $listsSubscribe[] = intval($listid);
296 }
297 }
298 }
299
300 if (empty($listsSubscribe)) {
301 return true;
302 }
303
304 $query = 'INSERT IGNORE INTO #__acym_user_has_list (`user_id`,`list_id`,`status`,`subscription_date`) ';
305 $query .= 'SELECT user.`id`, list.`id`, 1, '.acym_escapeDB(date('Y-m-d H:i:s', time() - date('Z'))).'
306 FROM #__acym_list AS list, #__acym_user AS user
307 WHERE list.`id` IN ('.implode(',', $listsSubscribe).')
308 AND user.`email` IN (SELECT '.acym_secureDBColumn($select['`email`']).' FROM '.acym_secureDBColumn($table).')';
309
310 $nbsubscribed = acym_query($query);
311 acym_enqueueMessage(acym_translationSprintf('ACYM_IMPORT_SUBSCRIPTION', $nbsubscribed));
312
313 return true;
314 }
315
316 public function mailpoet(): bool
317 {
318 $time = time();
319 $formattedTime = acym_date($time, 'Y-m-d H:i:s');
320 $sourceImport = 'import_on_'.$formattedTime.'_mailpoet';
321
322 $query = 'INSERT IGNORE INTO #__acym_user (`name`,`email`,`creation_date`,`active`, `confirmed`,`cms_id`, `source`)
323 SELECT CONCAT(`subscriber`.`first_name`, `subscriber`.`last_name`),
324 `subscriber`.`email`,
325 `subscriber`.`created_at`,
326 IF(`subscriber`.`status` = "inactive", 0, 1),
327 IF(`subscriber`.`status` = "subscribed", 1, 0),
328 `subscriber`.`wp_user_id`,
329 \''.$sourceImport.'\'
330 FROM #__mailpoet_subscribers AS `subscriber` ';
331 $listsMailpoet = acym_getVar('array', 'mailpoet_lists', []);
332 if (!empty($listsMailpoet)) {
333 acym_arrayToInteger($listsMailpoet);
334 $query .= ' JOIN #__mailpoet_subscriber_segment AS sub_segment ON `subscriber`.`id` = `sub_segment`.`subscriber_id` AND `sub_segment`.`segment_id` IN ('.implode(
335 ',',
336 $listsMailpoet
337 ).')';
338 }
339 $query .= ' WHERE `subscriber`.`deleted_at` IS NULL ON DUPLICATE KEY UPDATE `source`='.acym_escapeDB($sourceImport);
340
341 $insertedUsers = acym_query($query);
342
343 acym_query('UPDATE #__acym_configuration SET `value` = '.intval($time).' WHERE `name` = \'last_import\'');
344
345 acym_enqueueMessage(acym_translationSprintf('ACYM_IMPORT_NEW_SUBS', $insertedUsers), 'info');
346
347 $lists = $this->getImportedLists();
348 $listsSubscribe = [];
349 if (!empty($lists)) {
350 foreach ($lists as $listid => $val) {
351 if (!empty($val)) {
352 $listsSubscribe[] = intval($listid);
353 }
354 }
355 }
356
357 if (empty($listsSubscribe)) {
358 return true;
359 }
360
361 $query = 'INSERT IGNORE INTO #__acym_user_has_list (`user_id`,`list_id`,`status`,`subscription_date`) ';
362 $query .= 'SELECT user.`id`, list.`id`, 1, '.acym_escapeDB(date('Y-m-d H:i:s', time() - date('Z'))).'
363 FROM #__acym_list AS list, #__acym_user AS user ';
364 $conditions = [];
365 $conditions[] = 'list.`id` IN ('.implode(',', $listsSubscribe).')';
366 $conditions[] = 'user.`source` = '.acym_escapeDB($sourceImport);
367
368 if (!empty($listsMailpoet)) {
369 $query .= ' JOIN #__mailpoet_subscribers AS subscriber ON subscriber.email = user.email';
370 $query .= ' JOIN #__mailpoet_subscriber_segment AS subscriber_segment ON subscriber.id = subscriber_segment.subscriber_id AND subscriber_segment.segment_id IN ('.implode(
371 ',',
372 $listsMailpoet
373 ).')';
374 }
375
376 $query .= ' WHERE '.implode(' AND ', $conditions);
377 $nbsubscribed = acym_query($query);
378 acym_enqueueMessage(acym_translationSprintf('ACYM_IMPORT_SUBSCRIPTION', $nbsubscribed));
379
380 return true;
381 }
382
383 public function finalizeImport(): bool
384 {
385 $filename = strtolower(acym_getVar('cmd', 'acym_import_filename'));
386 $extension = '.'.acym_fileGetExt($filename);
387 $this->forceConfirm = acym_getVar('bool', 'import_confirmed_generic', true);
388 $this->generateName = acym_getVar('bool', 'import_generate_generic', true);
389 $this->overwrite = acym_getVar('bool', 'import_overwrite_generic', true);
390
391 $this->config->saveConfig(
392 [
393 'import_confirmed' => $this->forceConfirm,
394 'import_generate' => $this->generateName,
395 'import_overwrite' => $this->overwrite,
396 ]
397 );
398
399 $filename = str_replace(['.', ' '], '_', substr($filename, 0, strpos($filename, $extension))).$extension;
400 $uploadPath = ACYM_MEDIA.'import'.DS.$filename;
401
402 if (!file_exists($uploadPath) || !is_file($uploadPath)) {
403 acym_enqueueMessage(acym_translation('ACYM_UPLOADED_FILE_NOT_FOUND').' '.$uploadPath, 'error');
404
405 return false;
406 }
407
408 $importColumns = acym_getVar('string', 'import_columns');
409 if (empty($importColumns)) {
410 acym_enqueueMessage(acym_translation('ACYM_COLUMNS_NOT_FOUND'), 'error');
411
412 return false;
413 }
414
415 $contentFile = file_get_contents($uploadPath);
416
417 if (acym_getVar('cmd', 'acyencoding', '') != '') {
418 $encodingHelper = new EncodingHelper();
419 $contentFile = $encodingHelper->change($contentFile, acym_getVar('cmd', 'acyencoding'), 'UTF-8');
420 }
421
422 $cutContent = str_replace(["\r\n", "\r"], "\n", $contentFile);
423 $allLines = explode("\n", $cutContent);
424
425 $listSeparators = ["\t", ';', ','];
426 $separator = ',';
427 foreach ($listSeparators as $sep) {
428 if (strpos($allLines[0], $sep) !== false) {
429 $separator = $sep;
430 break;
431 }
432 }
433
434 if (!empty($listsId)) {
435 $allLines[0] .= $sep;
436 }
437
438 $importColumns = str_replace(',', $separator, $importColumns);
439
440 if (strpos($allLines[0], '@')) {
441 $contentFile = $importColumns."\n".$contentFile;
442 } else {
443 $allLines[0] = $importColumns;
444 $contentFile = implode("\n", $allLines);
445 }
446
447 $this->handleContent($contentFile);
448
449 unlink($uploadPath);
450 $this->cleanImportFolder();
451
452 return true;
453 }
454
455 public function getImportedLists(): array
456 {
457 $listClass = new ListClass();
458 $listsId = json_decode(acym_getVar('string', 'acym__entity_select__selected'), true);
459 $newListName = acym_getVar('string', 'new_list');
460
461 if (empty($listsId) && empty($newListName)) {
462 return [];
463 }
464
465 $lists = [];
466
467 if (!empty($newListName)) {
468 $newList = new \stdClass();
469 $newList->name = $newListName;
470 $newList->active = 1;
471 $colors = '#'.substr(str_shuffle('ABCDEF0123456789'), 0, 6);
472 $newList->color = $colors;
473 $listid = $listClass->save($newList);
474 $lists[$listid] = 1;
475 }
476
477 if (!empty($listsId)) {
478 foreach ($listsId as $id) {
479 $lists[$id] = 1;
480 }
481 }
482
483 return $lists;
484 }
485
486 public function additionalDataUsersImport(bool $isGeneric): string
487 {
488 $buttonAddListId = $isGeneric ? 'acym__users__generic__import__create-list__button' : 'acym__users__import__create-list__button';
489 $buttonImportClass = $isGeneric ? 'acym__users__import__generic__import__button' : 'acym__users__import__button';
490 $buttonSkipId = $isGeneric ? 'acym__users__generic__import__skip__button' : 'acym__users__import__skip__button';
491 $buttonImportDataTask = $isGeneric ? 'listing' : '';
492
493 return '<div class="cell align-right grid-x margin-bottom-2">
494 <div id="acym__users__import__create-list" class="grid-x" style="display: none;">
495 <label for="acym__users__import__create-list__field" class="margin-right-1 acym_vcenter">'.acym_translation('ACYM_LIST_NAME').' : </label>
496 <div>
497 <input id="acym__users__import__create-list__field" type="text">
498 </div>
499 </div>
500 <button type="button" class="button button-secondary margin-left-1 acym_vcenter margin-right-2" id="'.$buttonAddListId.'">'.acym_translation(
501 'ACYM_CREATE_NEW_LIST'
502 ).'</button>
503 <i style="display: none;" class="acym_vcenter acymicon-circle-o-notch acymicon-spin" id="acym__users__import__create-list__loading-logo"></i>
504 </div>
505 <div class="cell align-right grid-x">
506 <button type="button" class="button-secondary button cell shrink margin-right-1" id="'.$buttonSkipId.'">'.acym_translation('ACYM_SKIP').'</button>
507 <button
508 type="button"
509 class="button-primary button acy_button_submit cell shrink margin-right-2 '.$buttonImportClass.'"
510 id="acym__entity_select__button__submit" data-task="'.$buttonImportDataTask.'">'.acym_translation('ACYM_SUBSCRIBE_USERS_TO_THESE_LISTS').'</button>
511 </div>';
512 }
513
514 private function createUploadFolder(): string
515 {
516 $folderPath = acym_cleanPath(ACYM_ROOT.trim(html_entity_decode(ACYM_MEDIA_FOLDER.'import'))).DS;
517 if ('wordpress' === ACYM_CMS) {
518 $folderPath = acym_cleanPath(WP_PLUGIN_DIR.DS.ACYM_COMPONENT.DS.'media'.DS.'import').DS;
519 }
520 if (!is_dir($folderPath)) {
521 acym_createDir($folderPath, true, true);
522 }
523
524 if (!is_writable($folderPath)) {
525 @chmod($folderPath, '0755');
526 if (!is_writable($folderPath)) {
527 acym_enqueueMessage(acym_translationSprintf('ACYM_WRITABLE_FOLDER', $folderPath), 'warning');
528 }
529 }
530
531 return $folderPath;
532 }
533
534 private function handleContent(string $contentFile): void
535 {
536 $timestamp = time();
537
538 $contentFile = str_replace(["\r\n", "\r"], "\n", $contentFile);
539 $importLines = explode("\n", $contentFile);
540
541 $i = 0;
542 $this->header = '';
543 $this->allUserIds = [];
544 while (empty($this->header) && $i < 10) {
545 $this->header = trim($importLines[$i]);
546 $i++;
547 }
548
549 if (strpos($this->header, '@') && !strpos($this->header, ',') && !strpos($this->header, ';') && !strpos($this->header, "\t")) {
550 $this->header = 'email';
551 $i--;
552 }
553
554 if (!$this->autoDetectHeader()) {
555 acym_enqueueMessage(acym_translationSprintf('ACYM_IMPORT_HEADER', acym_escape($this->header)), 'error');
556 acym_enqueueMessage(acym_translation('ACYM_IMPORT_EMAIL'), 'error');
557
558 return;
559 }
560
561 $encodingHelper = new EncodingHelper();
562 $userClass = new UserClass();
563 $listClass = new ListClass();
564
565 $allLists = $listClass->getAll('name');
566 $numberColumns = count($this->columns);
567 $countUsersBeforeImport = $userClass->getCountTotalUsers();
568 $importUsers = [];
569 $errorLines = [];
570
571 while (isset($importLines[$i])) {
572 if (strpos($importLines[$i], '"') !== false) {
573 $data = [];
574 $j = $i + 1;
575 $position = -1;
576
577 while ($j < ($i + 30)) {
578 $quoteOpened = substr($importLines[$i], $position + 1, 1) == '"';
579
580 if ($quoteOpened) {
581 $nextQuotePosition = strpos($importLines[$i], '"', $position + 2);
582 while (
583 $nextQuotePosition !== false
584 && $nextQuotePosition + 1 != strlen($importLines[$i])
585 && substr($importLines[$i], $nextQuotePosition + 1, 1) != $this->separator
586 ) {
587 $nextQuotePosition = strpos($importLines[$i], '"', $nextQuotePosition + 1);
588 }
589
590 if ($nextQuotePosition === false) {
591 if (!isset($importLines[$j])) {
592 break;
593 }
594
595 $importLines[$i] .= "\n".$importLines[$j];
596 $importLines[$i] = rtrim($importLines[$i], $this->separator);
597 unset($importLines[$j]);
598 $j++;
599 } else {
600
601 if (strlen($importLines[$i]) - 1 == $nextQuotePosition) {
602 $data[] = substr($importLines[$i], $position + 1);
603 break;
604 }
605 $data[] = substr($importLines[$i], $position + 1, $nextQuotePosition + 1 - ($position + 1));
606 $position = $nextQuotePosition + 1;
607 }
608 } else {
609 $nextSeparatorPosition = strpos($importLines[$i], $this->separator, $position + 1);
610 if ($nextSeparatorPosition === false) {
611 $data[] = substr($importLines[$i], $position + 1);
612 break;
613 } else { // If found the next separator, add the value in $data and change the position
614 $data[] = substr($importLines[$i], $position + 1, $nextSeparatorPosition - ($position + 1));
615 $position = $nextSeparatorPosition;
616 }
617 }
618 }
619
620 $importLines = array_merge($importLines);
621 } else {
622 $data = explode($this->separator, rtrim(trim($importLines[$i]), $this->separator));
623 }
624
625 if (!empty($this->separatorsToRemove)) {
626 for ($b = $numberColumns + $this->separatorsToRemove - 1; $b >= $numberColumns; $b--) {
627 if (isset($data[$b]) && (strlen($data[$b]) == 0 || $data[$b] == ' ')) {
628 unset($data[$b]);
629 }
630 }
631 }
632
633 $i++;
634 if (empty($importLines[$i - 1])) {
635 continue;
636 }
637
638 $this->totalTry++;
639 if (count($data) > $numberColumns) {
640 $copy = $data;
641 foreach ($copy as $oneelem => $oneval) {
642 if (
643 !empty($oneval[0])
644 && $oneval[0] === '"'
645 && $oneval[strlen($oneval) - 1] !== '"'
646 && isset($copy[$oneelem + 1])
647 && $copy[$oneelem + 1][strlen($copy[$oneelem + 1]) - 1] == '"'
648 ) {
649 $data[$oneelem] = $copy[$oneelem].$this->separator.$copy[$oneelem + 1];
650 unset($data[$oneelem + 1]);
651 }
652 }
653
654 $data = array_values($data);
655 }
656
657 if (count($data) < $numberColumns) {
658 for ($a = count($data); $a < $numberColumns; $a++) {
659 $data[$a] = '';
660 }
661 }
662
663 if (count($data) != $numberColumns) {
664 static $errorcount = 0;
665 if (empty($errorcount)) {
666 acym_enqueueMessage(acym_translationSprintf('ACYM_IMPORT_ARGUMENTS', $numberColumns), 'warning');
667 }
668 $errorcount++;
669
670 if ($this->totalTry == 1) {
671 return;
672 }
673 if (empty($errorLines)) {
674 $errorLines[] = 'error,'.$importLines[0];
675 }
676 $errorLines[] = acym_translation('ACYM_IMPORT_ERROR_WRONG_NUMBER_ARGUMENTS').','.$importLines[$i - 1];
677 continue;
678 }
679
680 $newUser = new \stdClass();
681 $newUser->customfields = [];
682
683 $emailKey = array_search('email', $this->columns);
684 $newUser->email = trim(strip_tags($data[$emailKey]), '\'" ');
685 $newUser->email = preg_replace("/\s+/u", '', $newUser->email);
686 if (!empty($newUser->email)) {
687 $newUser->email = acym_punycode($newUser->email);
688 }
689 $newUser->email = trim(str_replace([' ', "\t"], '', $encodingHelper->change($newUser->email, 'UTF-8', 'ISO-8859-1')));
690
691
692 if (!acym_isValidEmail($newUser->email)) {
693 static $errorcountfail = 0;
694 if ($errorcountfail == 0) {
695 acym_enqueueMessage(acym_translation('ACYM_ADDRESSES_INVALID'), 'warning');
696 }
697 $errorcountfail++;
698 if (empty($errorLines)) {
699 $errorLines[] = 'error,'.$importLines[0];
700 }
701 $errorLines[] = acym_translation('ACYM_INVALID_EMAIL_ADDRESS').','.$importLines[$i - 1];
702 continue;
703 }
704
705 foreach ($data as $num => $value) {
706 if ($num == $emailKey) continue;
707
708 $field = $this->columns[$num];
709
710 if ($field == 1) continue;
711
712 if ($field === 'listids') {
713 $liststosub = explode('-', trim($value, '\'" '));
714 foreach ($liststosub as $onelistid) {
715 $this->importUserInLists[intval(trim($onelistid))][] = acym_escapeDB($newUser->email);
716 }
717 continue;
718 }
719
720 if ($field === 'listname') {
721 $liststosub = explode('-', trim($value, '\'" '));
722 foreach ($liststosub as $onelistName) {
723 if (empty($onelistName)) {
724 continue;
725 }
726 $onelistName = trim($onelistName);
727 if (empty($allLists[$onelistName])) {
728 $newList = new \stdClass();
729 $newList->name = $onelistName;
730 $newList->active = 1;
731 $colors = ['#3366ff', '#7240A4', '#7A157D', '#157D69', '#ECE649'];
732 $newList->color = $colors[rand(0, count($colors) - 1)];
733 $listid = $listClass->save($newList);
734 $newList->id = $listid;
735 $allLists[$onelistName] = $newList;
736 }
737 $this->importUserInLists[intval($allLists[$onelistName]->id)][] = acym_escapeDB($newUser->email);
738 }
739 continue;
740 }
741
742 if (strpos($field, 'subscription_date_') === 0 || strpos($field, 'unsubscription_date_') === 0) {
743 $value = trim($value, '"');
744 if (strpos($field, 'subscription_date_') === 0) {
745 $listId = (int)str_replace('subscription_date_', '', $field);
746 $dateType = 'subscribed_date';
747 } else {
748 $listId = (int)str_replace('unsubscription_date_', '', $field);
749 $dateType = 'unsubscribed_date';
750 }
751
752 if (!isset($this->subscriptionHistory[$listId])) {
753 $this->subscriptionHistory[$listId] = [];
754 }
755
756 $email = $newUser->email;
757 $userFound = false;
758
759 foreach ($this->subscriptionHistory[$listId] as &$entry) {
760 if ($entry['email'] === $email) {
761 $entry[$dateType] = $value;
762 $userFound = true;
763 break;
764 }
765 }
766 unset($entry);
767
768 if (!$userFound) {
769 $this->subscriptionHistory[$listId][] = [
770 'email' => $email,
771 $dateType => $value,
772 ];
773 }
774
775 continue;
776 }
777
778
779 if (strpos($field, 'cf_') === 0) {
780 $newUser->customfields[substr($field, 3)] = trim(strip_tags($value), '\'" ');
781 continue;
782 }
783
784 if ($value === 'null') {
785 $newUser->$field = '';
786 } else {
787 $newUser->$field = trim(strip_tags($value), '\'" ');
788 }
789 }
790
791 if (acym_isMultilingual() && empty($newUser->language)) {
792 $newUser->language = $this->config->get('multilingual_default', '');
793 }
794
795 $importUsers[] = $newUser;
796 $this->totalValid++;
797
798 if ($this->totalValid % 50 == 0) {
799 $this->insertUsers($importUsers, $timestamp);
800 $importUsers = [];
801 }
802 }
803
804 if (!empty($errorLines)) {
805 $filename = strtolower(acym_getVar('cmd', 'acym_import_filename', ''));
806 if (!empty($filename)) {
807 $extension = '.'.acym_fileGetExt($filename);
808 $filename = str_replace(['.', ' '], '_', substr($filename, 0, strpos($filename, $extension))).$extension;
809 $errorFile = implode("\n", $errorLines);
810 acym_writeFile(ACYM_MEDIA.'import'.DS.'error_'.$filename, $errorFile);
811 acym_enqueueMessage(
812 '<a target="_blank" href="'.acym_prepareAjaxURL((acym_isAdmin() ? '' : 'front').'users&task=downloadImport').'&filename=error_'.preg_replace(
813 '#\.[^.]*$#',
814 '',
815 $filename
816 ).'&'.acym_noTemplate().'" >'.acym_translation('ACYM_DOWNLOAD_IMPORT_ERRORS').'</a>',
817 'notice'
818 );
819 }
820 }
821
822 $this->insertUsers($importUsers, $timestamp);
823
824 acym_query('UPDATE #__acym_configuration SET `value` = '.intval($timestamp).' WHERE `name` = \'last_import\'');
825
826 acym_query('DELETE FROM #__acym_user_has_field WHERE `value` = ""');
827
828 $countUsersAfterImport = $userClass->getCountTotalUsers();
829 $totalInserted = $countUsersAfterImport - $countUsersBeforeImport;
830
831 $maybeUpdated = acym_translation('ACYM_NOT_UPDATED');
832 if ($this->overwrite) {
833 $maybeUpdated = acym_translation('ACYM_UPDATED');
834 }
835 $reportMsg = acym_translationSprintf(
836 'ACYM_IMPORT_REPORTING_UPDATED',
837 $this->totalTry,
838 $totalInserted,
839 $this->totalTry - $this->totalValid,
840 $this->totalValid - $totalInserted,
841 $maybeUpdated
842 );
843 acym_enqueueMessage($reportMsg, 'info');
844
845 $this->insertSubscriptionHistory();
846
847 $this->subscribeUsers();
848 }
849
850 private function insertUsers(array $users, int $timestamp): void
851 {
852 if (empty($users)) {
853 return;
854 }
855
856 $importedCols = array_keys(get_object_vars($users[0]));
857 unset($importedCols[array_search('customfields', $importedCols)]);
858 if ($this->forceConfirm) $importedCols[] = 'confirmed';
859
860 foreach ($users as $a => $oneUser) {
861 $this->checkData($users[$a], $timestamp);
862 }
863
864 $columns = reset($users);
865 $colNames = array_keys(get_object_vars($columns));
866 unset($colNames[array_search('customfields', $colNames)]);
867
868 if (!in_array('key', $colNames)) $colNames[] = 'key';
869
870 foreach ($colNames as $oneColumn) {
871 acym_secureDBColumn($oneColumn);
872 }
873
874 $queryInsertUsers = 'INSERT'.($this->overwrite ? '' : ' IGNORE').' INTO #__acym_user (`'.implode('`,`', $colNames).'`) VALUES (';
875 $values = [];
876 $customFieldsvalues = [];
877 $allemails = [];
878 foreach ($users as $oneUser) {
879 $value = [];
880 acym_trigger('onAcymBeforeUserImport', [&$oneUser]);
881
882 foreach ($oneUser as $map => $oneValue) {
883 if ($map === 'customfields') continue;
884
885 $oneValue = htmlspecialchars_decode($oneValue, ENT_QUOTES);
886
887 if ($map !== 'id') {
888 $oneValue = acym_escapeDB($oneValue);
889 if ($map === 'email') {
890 $allemails[] = $oneValue;
891 }
892 } else {
893 $oneValue = intval($oneValue);
894 }
895
896 $value[] = $oneValue;
897 }
898
899 if (!isset($oneUser->key)) $value[] = acym_escapeDB(acym_generateKey(14));
900 $values[] = implode(',', $value);
901
902 if (!empty($oneUser->customfields)) $customFieldsvalues[$oneUser->email] = $oneUser->customfields;
903 }
904 acym_trigger('onAcymUserImport', [&$users]);
905
906 $queryInsertUsers .= implode('),(', $values).')';
907
908 if ($this->overwrite) {
909 $queryInsertUsers .= ' ON DUPLICATE KEY UPDATE ';
910 foreach ($importedCols as &$oneColumn) {
911 acym_secureDBColumn($oneColumn);
912 if ($oneColumn == 'key') {
913 $oneColumn = '`'.$oneColumn.'` = `'.$oneColumn.'`';
914 } else {
915 $oneColumn = '`'.$oneColumn.'` = VALUES(`'.$oneColumn.'`)';
916 }
917 }
918 $queryInsertUsers .= implode(',', $importedCols);
919 }
920
921 acym_query($queryInsertUsers);
922
923 $importedUsers = acym_loadObjectList('SELECT id, email FROM #__acym_user WHERE email IN ('.implode(',', $allemails).')', 'id');
924
925 $this->importedUsersByEmail = array_combine(array_column($importedUsers, 'email'), array_column($importedUsers, 'id'));
926
927 if (!empty($customFieldsvalues)) {
928 $insertValues = [];
929 foreach ($importedUsers as $one) {
930 if (empty($customFieldsvalues[$one->email])) continue;
931
932 foreach ($customFieldsvalues[$one->email] as $fieldId => $value) {
933 $value = htmlspecialchars_decode($value, ENT_QUOTES);
934 $insertValues[] = '('.intval($one->id).','.intval($fieldId).','.acym_escapeDB($value).')';
935 }
936 }
937
938 if (!empty($insertValues)) {
939 $queryInsertCustomFields = 'INSERT'.($this->overwrite ? '' : ' IGNORE').' INTO #__acym_user_has_field (`user_id`, `field_id`, `value`) VALUES '.implode(
940 ',',
941 $insertValues
942 );
943 if ($this->overwrite) {
944 $queryInsertCustomFields .= ' ON DUPLICATE KEY UPDATE `value` = VALUES(`value`)';
945 }
946 acym_query($queryInsertCustomFields);
947 }
948 }
949
950
951 $this->allUserIds = array_merge($this->allUserIds, array_keys($importedUsers));
952 }
953
954 private function checkData(object &$user, int $timestamp)
955 {
956 if (empty($user->creation_date)) {
957 $user->creation_date = time();
958 }
959
960 if (is_numeric($user->creation_date)) {
961 $user->creation_date = date('Y-m-d H:i:s', $user->creation_date);
962 }
963
964 if (!isset($user->active) || strlen($user->active) == 0) {
965 $user->active = 1;
966 }
967
968 if ((!isset($user->confirmed) || strlen($user->confirmed) == 0) && $this->forceConfirm) {
969 $user->confirmed = 1;
970 }
971
972 if (empty($user->source)) {
973 $user->source = 'Import on '.acym_date($timestamp, 'Y-m-d H:i:s');
974 }
975
976 if (empty($user->name) && $this->generateName) {
977 $user->name = ucwords(trim(str_replace(['.', '_', '-', 1, 2, 3, 4, 5, 6, 7, 8, 9, 0], ' ', substr($user->email, 0, strpos($user->email, '@')))));
978 }
979 }
980
981 private function autoDetectHeader(): bool
982 {
983 $this->separator = ',';
984
985 $this->header = str_replace("\xEF\xBB\xBF", '', $this->header);
986
987 $listSeparators = ["\t", ';', ','];
988 foreach ($listSeparators as $sep) {
989 if (strpos($this->header, $sep) !== false) {
990 $this->separator = $sep;
991 break;
992 }
993 }
994
995 $this->columns = explode($this->separator, $this->header);
996
997 for ($i = count($this->columns) - 1; $i >= 0; $i--) {
998 if (strlen($this->columns[$i]) == 0) {
999 unset($this->columns[$i]);
1000 $this->separatorsToRemove++;
1001 }
1002 }
1003
1004 $columns = acym_getColumns('user');
1005 foreach ($columns as $i => $oneColumn) {
1006 $columns[$i] = strtolower($oneColumn);
1007 }
1008
1009 foreach ($this->columns as $i => $oneColumn) {
1010 $this->columns[$i] = strtolower(trim($oneColumn, '\'" '));
1011 if (in_array($this->columns[$i], ['listids', 'listname'])) continue;
1012 if (strpos($this->columns[$i], 'cf_') === 0) continue;
1013 if (strpos($this->columns[$i], 'subscription_date_') === 0) continue;
1014 if (strpos($this->columns[$i], 'unsubscription_date_') === 0) continue;
1015
1016 if (!in_array($this->columns[$i], $columns) && $this->columns[$i] != 1) {
1017 acym_enqueueMessage(
1018 acym_translationSprintf(
1019 'ACYM_IMPORT_ERROR_FIELD',
1020 '<b>'.acym_escape($this->columns[$i]).'</b>',
1021 '<b>'.implode('</b> | <b>', array_diff($columns, ['id', 'cms_id'])).'</b>'
1022 ),
1023 'error'
1024 );
1025
1026 return false;
1027 }
1028 }
1029
1030 if (!in_array('email', $this->columns)) {
1031 return false;
1032 }
1033
1034 return true;
1035 }
1036
1037 private function cleanImportFolder(): void
1038 {
1039 $files = acym_getFiles(ACYM_MEDIA.'import', '.', false, true, []);
1040 foreach ($files as $oneFile) {
1041 if (acym_fileGetExt($oneFile) != 'csv') {
1042 continue;
1043 }
1044 if (filectime($oneFile) < time() - 86400) {
1045 unlink($oneFile);
1046 }
1047 }
1048 }
1049
1050 private function subscribeUsers(): void
1051 {
1052 if (empty($this->allUserIds)) {
1053 return;
1054 }
1055
1056 $subdate = date('Y-m-d H:i:s', time() - date('Z'));
1057
1058 $listClass = new ListClass();
1059 $lists = $this->getImportedLists();
1060
1061 if (!acym_isAdmin() && 'joomla' === ACYM_CMS) {
1062 $listClass = new ListClass();
1063 $listManagementId = $listClass->getfrontManagementList();
1064 if (empty($listManagementId)) {
1065 acym_redirect(acym_rootURI(), 'ACYM_UNABLE_TO_CREATE_MANAGEMENT_LIST', 'error');
1066 }
1067
1068 if (empty($lists)) {
1069 $lists = [$listManagementId => 1];
1070 } else {
1071 $lists[$listManagementId] = 1;
1072 }
1073 }
1074
1075 if (!empty($this->importUserInLists)) {
1076 foreach ($this->importUserInLists as $listid => $arrayEmails) {
1077 if (empty($listid)) continue;
1078
1079 $listid = (int)$listid;
1080 $query = 'INSERT IGNORE INTO #__acym_user_has_list (`list_id`,`user_id`,`subscription_date`,`status`) ';
1081 $query .= 'SELECT '.intval($listid).',`id`,'.acym_escapeDB($subdate).',1 FROM #__acym_user WHERE `email` IN (';
1082 $query .= implode(',', $arrayEmails).')';
1083 $nbsubscribed = acym_query($query);
1084 $nbsubscribed = intval($nbsubscribed);
1085
1086 if (isset($this->subscribedUsers[$listid])) {
1087 $this->subscribedUsers[$listid]->nbusers += $nbsubscribed;
1088 } else {
1089 $myList = $listClass->getOneById($listid);
1090 $this->subscribedUsers[$listid] = $myList;
1091 $this->subscribedUsers[$listid]->nbusers = $nbsubscribed;
1092 }
1093 }
1094 }
1095
1096 if (!empty($lists)) {
1097 foreach ($lists as $listid => $val) {
1098 if (empty($val)) {
1099 continue;
1100 }
1101
1102 if ($val == -1) {
1103 $dateColumn = 'unsubscribe_date';
1104 $status = -1;
1105 } else {
1106 $dateColumn = 'subscription_date';
1107 $status = 1;
1108 }
1109
1110 $nbsubscribed = 0;
1111 $listid = intval($listid);
1112 $query = 'INSERT IGNORE INTO #__acym_user_has_list (`list_id`,`user_id`,`'.$dateColumn.'`,`status`) VALUES ';
1113 $b = 0;
1114 $currentSubids = [];
1115 foreach ($this->allUserIds as $subid) {
1116 $subid = intval($subid);
1117 $currentSubids[] = $subid;
1118 $b++;
1119
1120 if ($b > 200) {
1121 $query = rtrim($query, ',');
1122 if ($val == -1) {
1123 $query .= ' ON DUPLICATE KEY UPDATE status = -1';
1124 $nbsubscribed = -acym_loadResult(
1125 'SELECT COUNT(*) FROM #__acym_listsub WHERE `list_id` = '.intval($listid).' AND status != -1 AND `user_id` IN ('.implode(',', $currentSubids).')'
1126 );
1127 }
1128 $affected = acym_query($query);
1129 $nbsubscribed += intval($affected);
1130 $b = 0;
1131 $currentSubids = [];
1132 $query = 'INSERT IGNORE INTO #__acym_user_has_list (`list_id`,`user_id`,`'.$dateColumn.'`,`status`) VALUES ';
1133 }
1134
1135 $query .= '('.intval($listid).','.intval($subid).','.acym_escapeDB($subdate).','.$status.'),';
1136 }
1137 $query = rtrim($query, ',');
1138 if ($val == -1) {
1139 $query .= ' ON DUPLICATE KEY UPDATE status = -1';
1140 if (!empty($currentSubids)) {
1141 $nbsubscribed = -acym_loadResult(
1142 'SELECT COUNT(*) FROM #__acym_listsub WHERE `list_id` = '.intval($listid).' AND status != -1 AND `user_id` IN ('.implode(',', $currentSubids).')'
1143 );
1144 }
1145 }
1146
1147 $affected = acym_query($query);
1148 $nbsubscribed += intval($affected);
1149
1150 if (isset($this->subscribedUsers[$listid])) {
1151 $this->subscribedUsers[$listid]->nbusers += $nbsubscribed;
1152 } else {
1153 $myList = $listClass->getOneById($listid);
1154 $myList->status = $val;
1155 $this->subscribedUsers[$listid] = $myList;
1156 $this->subscribedUsers[$listid]->nbusers = $nbsubscribed;
1157 }
1158 }
1159 }
1160 }
1161
1162 public function insertSubscriptionHistory(): void
1163 {
1164 if (empty($this->subscriptionHistory)) {
1165 return;
1166 }
1167
1168 $listClass = new ListClass();
1169
1170 $userIds = array_values($this->importedUsersByEmail);
1171 $listIds = array_keys($this->subscriptionHistory);
1172
1173 $existingEntries = $listClass->getUserListEntries($userIds, $listIds);
1174
1175 foreach ($this->subscriptionHistory as $listId => $entries) {
1176 foreach ($entries as $entry) {
1177 if (empty($entry['subscribed_date']) && empty($entry['unsubscribed_date'])) {
1178 continue;
1179 }
1180
1181 $userId = $this->importedUsersByEmail[$entry['email']] ?? null;
1182 if (empty($userId)) {
1183 continue;
1184 }
1185
1186 $key = $userId.'_'.$listId;
1187 $existing = $existingEntries[$key] ?? null;
1188
1189 $subscriptionDate = !empty($entry['subscribed_date']) ? acym_escapeDB($entry['subscribed_date']) : 'NULL';
1190 $unsubscribeDate = !empty($entry['unsubscribed_date']) ? acym_escapeDB($entry['unsubscribed_date']) : 'NULL';
1191
1192 if (!empty($existing)) {
1193 if ($existing->status === 0) {
1194 continue;
1195 }
1196
1197 $fieldsToUpdate = [];
1198
1199 if (empty($existing->subscription_date)) {
1200 if ($unsubscribeDate != 'NULL' && ($subscriptionDate != 'NULL' && $unsubscribeDate > $subscriptionDate)) {
1201 $fieldsToUpdate[] = 'status ='. 0;
1202 $fieldsToUpdate[] = 'unsubscribe_date ='.$unsubscribeDate;
1203 }
1204
1205 $fieldsToUpdate[] = 'subscription_date ='.$subscriptionDate;
1206 } else {
1207 if ($unsubscribeDate != 'NULL' && ($existing->subscription_date != 'NULL' && $unsubscribeDate > $existing->subscription_date)) {
1208 $fieldsToUpdate[] = 'status ='. 0;
1209 $fieldsToUpdate[] = 'unsubscribe_date ='.$unsubscribeDate;
1210 }
1211 }
1212
1213 if (!empty($fieldsToUpdate)) {
1214 $query = 'UPDATE #__acym_user_has_list SET '.implode(', ', $fieldsToUpdate)
1215 .' WHERE user_id = '.$userId.' AND list_id = '.$listId;
1216 acym_query($query);
1217 }
1218 } else {
1219 if ($subscriptionDate === 'NULL' && $unsubscribeDate !== 'NULL') {
1220 $subscriptionDate = $unsubscribeDate;
1221 }
1222
1223 $status = ($unsubscribeDate !== 'NULL') ? 0 : 1;
1224
1225 $insertQuery = 'INSERT INTO #__acym_user_has_list (`list_id`, `user_id`, `subscription_date`, `status`, `unsubscribe_date`) VALUES '
1226 .'('.$listId.','.$userId.','.$subscriptionDate.','.$status.','.$unsubscribeDate.')';
1227 acym_query($insertQuery);
1228 }
1229 }
1230 }
1231 }
1232 }
1233