PluginProbe
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress / 11.1.1
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress v11.1.1
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
← All changes | back/Core/AcymPlugin.php +0 -1608 10.11.1 → 11.1.1 View file →
@@ -1,1608 +1,0 @@
1 -<?php
2 -
3 -namespace AcyMailing\Core;
4 -
5 -use AcyMailing\Classes\CampaignClass;
6 -use AcyMailing\Classes\PluginClass;
7 -use AcyMailing\Helpers\PluginHelper;
8 -use Joomla\CMS\HTML\HTMLHelper;
9 -
10 -class AcymPlugin extends AcymObject
11 -{
12 - public string $cms = 'all';
13 - public string $name = '';
14 - public bool $installed = true;
15 -
16 - protected array $addonDefinition;
17 - protected PluginHelper $pluginHelper;
18 -
19 - protected int $rootCategoryId = 1;
20 - protected array $categories;
21 - protected array $catvalues = [];
22 - private array $cats = [];
23 - private array $subCategories = [];
24 -
25 - protected array $tagvalues = [];
26 -
27 - protected array $tags = [];
28 - protected object $pageInfo;
29 - protected array $searchFields = [];
30 - protected string $querySelect = '';
31 - protected string $query = '';
32 - protected array $filters = [];
33 - protected string $elementIdTable = '';
34 - protected string $elementIdColumn = '';
35 -
36 - public object $pluginDescription;
37 - public object $generateCampaignResult;
38 -
39 - protected ?object $defaultValues;
40 - protected string $emailLanguage = '';
41 - private int $campaignId;
42 - private string $campaignType;
43 -
44 - protected array $displayOptions = [];
45 - protected array $replaceOptions = [];
46 - protected array $elementOptions = [];
47 - protected array $customOptions = [];
48 -
49 - private array $sendingPlugins = [
50 - 'wp_mail_smtp' => 'WP Mail SMTP',
51 - ];
52 -
53 - public array $errors = [];
54 - public string $logFilename = '';
55 - protected int $responseCode;
56 -
57 - private bool $active;
58 - public array $settings = [];
59 - private array $savedSettings = [];
60 -
61 - public function __construct()
62 - {
63 - parent::__construct();
64 -
65 - $this->elementOptions = ['wrappedText' => [acym_translation('ACYM_WRAPPED_TEXT')]];
66 -
67 - $this->pluginHelper = new PluginHelper();
68 - $this->pageInfo = new \stdClass();
69 -
70 - $this->pluginDescription = new \stdClass();
71 - $this->pluginDescription->plugin = get_class($this);
72 -
73 - $this->name = strtolower(substr($this->pluginDescription->plugin, 7));
74 -
75 - $this->generateCampaignResult = new \stdClass();
76 - $this->generateCampaignResult->status = true;
77 - $this->generateCampaignResult->message = '';
78 -
79 - $this->campaignId = acym_getVar('int', 'campaignId', 0);
80 - $this->campaignType = acym_getVar('string', 'campaign_type', '');
81 -
82 - $pluginClass = new PluginClass();
83 - $currentAddon = $pluginClass->getOnePluginByFolderName($this->name);
84 - $this->active = empty($currentAddon) || $currentAddon->active;
85 -
86 - if (!empty($currentAddon->settings)) {
87 - if (is_string($currentAddon->settings)) {
88 - $this->savedSettings = json_decode($currentAddon->settings, true);
89 - } else {
90 - $this->savedSettings = $currentAddon->settings;
91 - }
92 - }
93 -
94 - $this->logFilename = acym_getErrorLogFilename(empty($this->name) ? get_class($this) : $this->name);
95 - }
96 -
97 - protected function displaySelectionZone(string $zoneContent): void
98 - {
99 - ?>
100 - <p class="acym__wysid__right__toolbar__p acym__wysid__right__toolbar__p__open acym__title">
101 - <?php echo acym_escape(acym_translation('ACYM_CONTENT_TO_INSERT')); ?><i class="acymicon-keyboard-arrow-up"></i>
102 - </p>
103 - <div class="acym__wysid__right__toolbar__design--show acym__wysid__right__toolbar__design acym__wysid__context__modal__container">
104 - <?php echo $zoneContent; ?>
105 - </div>
106 - <?php
107 - }
108 -
109 - public function displayListing(): void
110 - {
111 - echo $this->prepareListing();
112 - }
113 -
114 - public function prepareListing()
115 - {
116 - $this->pageInfo->limit = 10;
117 - $this->pageInfo->page = acym_getVar('int', 'pagination_page_ajax', 1);
118 - $this->pageInfo->start = ($this->pageInfo->page - 1) * $this->pageInfo->limit;
119 - $this->pageInfo->search = acym_getVar('string', 'plugin_search', '');
120 - $this->pageInfo->filter_cat = acym_getVar('int', 'plugin_category', 0);
121 - $this->pageInfo->orderdir = 'DESC';
122 - $this->pageInfo->loadMore = acym_getVar('boolean', 'loadMore', false);
123 -
124 - if (!empty($this->pageInfo->search) && !empty($this->searchFields)) {
125 - $searchVal = '%'.acym_getEscaped($this->pageInfo->search, true).'%';
126 - $this->filters[] = implode(' LIKE '.acym_escapeDB($searchVal).' OR ', $this->searchFields).' LIKE '.acym_escapeDB($searchVal);
127 - }
128 -
129 - return '';
130 - }
131 -
132 - public function getElements(): array
133 - {
134 - $conditions = '';
135 - if (!empty($this->filters)) {
136 - $conditions = ' WHERE ('.implode(') AND (', $this->filters).')';
137 - }
138 -
139 - $ordering = '';
140 - if (!empty($this->pageInfo->order)) {
141 - $ordering = ' ORDER BY '.acym_secureDBColumn($this->pageInfo->order).' '.acym_secureDBColumn($this->pageInfo->orderdir);
142 - }
143 -
144 - $rows = acym_loadObjectList($this->querySelect.$this->query.$conditions.$ordering, '', $this->pageInfo->start, $this->pageInfo->limit);
145 - $this->pageInfo->total = acym_loadResult('SELECT COUNT(*) '.$this->query.$conditions.$ordering);
146 -
147 - if (!empty($this->defaultValues->id) && $this->defaultValues->defaultPluginTab === $this->name) {
148 - $found = false;
149 - foreach ($rows as $oneRow) {
150 - if (intval($oneRow->{$this->elementIdColumn}) === intval($this->defaultValues->id)) {
151 - $found = true;
152 - }
153 - }
154 -
155 - if (!$found) {
156 - $conditions = ' WHERE '.$this->elementIdTable.'.'.$this->elementIdColumn.' = '.intval($this->defaultValues->id);
157 - $row = acym_loadObject($this->querySelect.$this->query.$conditions);
158 - if (!empty($row)) {
159 - $rows[] = $row;
160 - }
161 - }
162 - }
163 -
164 - return $rows;
165 - }
166 -
167 - protected function getFilteringZone(bool $categoryFilter = true): string
168 - {
169 - $result = '<div class="grid-x" id="plugin_listing_filters">
170 - <div class="cell medium-6">
171 - <input type="text" name="plugin_search" placeholder="'.acym_escape(acym_translation('ACYM_SEARCH')).'"/>
172 - </div>
173 - <div class="cell medium-6 grid-x">
174 - <div class="cell hide-for-small-only medium-auto"></div>
175 - <div class="cell medium-shrink">';
176 -
177 - if ($categoryFilter) {
178 - $result .= $this->getCategoryFilter();
179 - }
180 -
181 - $result .= '</div>
182 - </div>
183 - </div>';
184 -
185 - return $result;
186 - }
187 -
188 - public function prepareWPCategories(string $type): void
189 - {
190 - $this->categories = acym_loadObjectList(
191 - 'SELECT cat.term_taxonomy_id AS id, parent.term_taxonomy_id AS parent_id, catdetails.name AS title
192 - FROM `#__term_taxonomy` AS cat
193 - JOIN `#__terms` AS catdetails ON cat.term_id = catdetails.term_id
194 - LEFT JOIN `#__term_taxonomy` AS parent ON cat.parent = parent.term_id
195 - WHERE cat.taxonomy = '.acym_escapeDB($type)
196 - );
197 - foreach ($this->categories as $i => $oneCat) {
198 - if (empty($oneCat->parent_id)) {
199 - $this->categories[$i]->parent_id = $this->rootCategoryId;
200 - }
201 - }
202 - }
203 -
204 - protected function getCategoryFilter()
205 - {
206 - $filter_cat = acym_getVar('int', 'plugin_category', 0);
207 - $this->catvalues = [];
208 - $this->catvalues[] = acym_selectOption(0, 'ACYM_ALL');
209 -
210 - $this->cats = [];
211 - $this->subCategories = [];
212 - if (!empty($this->categories)) {
213 - foreach ($this->categories as $oneCat) {
214 - $this->cats[$oneCat->parent_id][] = $oneCat;
215 - }
216 - $this->handleChildrenCategories($this->rootCategoryId);
217 - foreach ($this->categories as $oneCat) {
218 - $this->subCategories[$oneCat->id] = $this->getSubCats($oneCat->id);
219 - }
220 - }
221 -
222 - return acym_select(
223 - $this->catvalues,
224 - 'plugin_category',
225 - intval($filter_cat),
226 - ['class' => 'plugin_category_select']
227 - );
228 - }
229 -
230 - private function getSubCats(int $categoryId): array
231 - {
232 - $result = [$categoryId];
233 - if (empty($this->cats[$categoryId])) {
234 - return $result;
235 - }
236 -
237 - foreach ($this->cats[$categoryId] as $oneSubCategory) {
238 - $result = array_merge($result, $this->getSubCats($oneSubCategory->id));
239 - }
240 -
241 - return $result;
242 - }
243 -
244 - protected function handleChildrenCategories(int $parent_id, int $level = 0): void
245 - {
246 - if (empty($this->cats[$parent_id])) return;
247 -
248 - foreach ($this->cats[$parent_id] as $cat) {
249 - $this->catvalues[] = acym_selectOption($cat->id, str_repeat(' - - ', $level).$cat->title);
250 - $this->handleChildrenCategories($cat->id, $level + 1);
251 - }
252 - }
253 -
254 - protected function getSubCategories(int $categoryId): array
255 - {
256 - $this->getCategoryFilter();
257 -
258 - return $this->subCategories[$categoryId];
259 - }
260 -
261 - protected function autoContentOptions(array &$options, ?string $type = null): void
262 - {
263 - if ($type === 'event') {
264 - $options[] = [
265 - 'title' => 'ACYM_FROM',
266 - 'type' => 'date',
267 - 'name' => 'from',
268 - 'default' => time(),
269 - 'relativeDate' => '+',
270 - ];
271 -
272 - $options[] = [
273 - 'title' => 'ACYM_TO',
274 - 'type' => 'date',
275 - 'name' => 'to',
276 - 'default' => '',
277 - 'relativeDate' => '+',
278 - ];
279 - } elseif ($type !== 'simple') {
280 - $options[] = [
281 - 'title' => 'ACYM_MIN_PUBLISH_DATE',
282 - 'tooltip' => 'ACYM_MIN_PUBLISH_DATE_DESC',
283 - 'type' => 'date',
284 - 'name' => 'min_publish',
285 - 'default' => '',
286 - 'relativeDate' => '-',
287 - ];
288 - }
289 -
290 - $options[] = [
291 - 'title' => 'ACYM_COLUMNS',
292 - 'type' => 'number',
293 - 'name' => 'cols',
294 - 'default' => 1,
295 - ];
296 -
297 - $options[] = [
298 - 'title' => 'ACYM_COLUMN_HORIZONTAL_PADDING',
299 - 'type' => 'number',
300 - 'name' => 'hpadding',
301 - 'default' => 10,
302 - ];
303 -
304 - $options[] = [
305 - 'title' => 'ACYM_COLUMN_VERTICAL_PADDING',
306 - 'type' => 'number',
307 - 'name' => 'vpadding',
308 - 'default' => 10,
309 - ];
310 -
311 - $options[] = [
312 - 'title' => 'ACYM_MAX_NB_ELEMENTS',
313 - 'type' => 'number',
314 - 'name' => 'max',
315 - 'default' => 20,
316 - ];
317 - }
318 -
319 - protected function autoCampaignOptions(array &$options, bool $modified = false): void
320 - {
321 - if (empty($this->campaignId) && empty($this->campaignType)) {
322 - return;
323 - } elseif (!empty($this->campaignId) && (empty($this->campaignType) || $this->campaignType !== 'auto')) {
324 - $campaignClass = new CampaignClass();
325 - $campaign = $campaignClass->getOneById($this->campaignId);
326 - if ($campaign->sending_type !== 'auto') return;
327 - } elseif (empty($this->campaignId) && !empty($this->campaignType) && $this->campaignType !== 'auto') {
328 - return;
329 - }
330 -
331 - $options[] = [
332 - 'title' => 'ACYM_DOCUMENTATION',
333 - 'type' => 'custom',
334 - 'name' => 'documentation',
335 - 'output' => '<a target="_blank" href="'.ACYM_DOCUMENTATION.'main-pages/campaigns/automatic-campaigns#dont-send-twice-the-same-content"><i class="acymicon-book"></i></a>',
336 - 'js' => '',
337 - 'section' => 'ACYM_AUTO_CAMPAIGNS_OPTIONS',
338 - ];
339 -
340 - if ($modified) {
341 - $options[] = [
342 - 'title' => 'ACYM_DATE',
343 - 'type' => 'select',
344 - 'name' => 'datefilter',
345 - 'default' => 'onlynew',
346 - 'tooltip' => 'ACYM_ONLY_NEWLY_CREATED_DESC',
347 - 'options' => [
348 - '' => 'ACYM_NO_FILTER',
349 - 'onlynew' => 'ACYM_ONLY_NEWLY_CREATED',
350 - 'onlymodified' => 'ACYM_ONLY_NEWLY_MODIFIED',
351 - ],
352 - 'section' => 'ACYM_AUTO_CAMPAIGNS_OPTIONS',
353 - ];
354 - } else {
355 - $options[] = [
356 - 'title' => 'ACYM_ONLY_NEWLY_CREATED',
357 - 'type' => 'boolean',
358 - 'name' => 'onlynew',
359 - 'default' => true,
360 - 'tooltip' => 'ACYM_ONLY_NEWLY_CREATED_DESC',
361 - 'section' => 'ACYM_AUTO_CAMPAIGNS_OPTIONS',
362 - ];
363 - }
364 -
365 - $options[] = [
366 - 'title' => 'ACYM_MIN_NB_ELEMENTS',
367 - 'type' => 'number',
368 - 'name' => 'min',
369 - 'default' => 0,
370 - 'tooltip' => 'ACYM_MIN_NB_ELEMENTS_DESC',
371 - 'section' => 'ACYM_AUTO_CAMPAIGNS_OPTIONS',
372 - ];
373 - }
374 -
375 - protected function getElementsListing(array $options): string
376 - {
377 - if ($this->pageInfo->loadMore) {
378 - return $this->getInnerListing($options);
379 - }
380 - $listing = '<div id="plugin_listing" class="acym__popup__listing">';
381 - $listing .= '<input type="hidden" name="plugin" value="'.acym_escape(get_class($this)).'" />';
382 -
383 - $listing .= '<div class="cell grid-x hide-for-small-only plugin_listing_headers">';
384 - foreach ($options['header'] as $oneColumn) {
385 - $class = empty($oneColumn['class']) ? '' : ' '.$oneColumn['class'];
386 - $listing .= '<div class="cell plugin_listing_headers__title medium-'.$oneColumn['size'].$class.'">'.acym_translation($oneColumn['label']).'</div>';
387 - }
388 - $listing .= '</div>';
389 -
390 - $listing .= $this->getInnerListing($options);
391 -
392 - $listing .= '<input type="hidden" value="1" id="acym_pagination__ajax__load-more" name="acym_pagination__ajax__load-more">';
393 - $listing .= '</div>';
394 -
395 - return $listing;
396 - }
397 -
398 - private function getInnerListing(array $options): string
399 - {
400 - if (empty($options['rows']) && $this->pageInfo->loadMore) {
401 - $listing = '<h3 class="cell acym__listing__empty__load-more text-center">'.acym_translation('ACYM_NO_MORE_RESULTS').'</h3>';
402 - } elseif (empty($options['rows'])) {
403 - $listing = '<h1 class="cell acym__listing__empty__search__modal text-center">'.acym_translation('ACYM_NO_RESULTS_FOUND').'</h1>';
404 - } else {
405 - $selected = explode(',', acym_getVar('string', 'selected', ''));
406 - if (!empty($this->defaultValues->id)) {
407 - $selected = [$this->defaultValues->id];
408 - }
409 -
410 - $listing = '';
411 - foreach ($options['rows'] as $row) {
412 - $class = 'cell grid-x acym__row__no-listing acym__listing__row__popup';
413 - if (in_array($row->{$options['id']}, $selected)) {
414 - $class .= ' selected_row';
415 - }
416 -
417 - $listing .= '<div
418 - class="'.$class.'"
419 - data-id="'.acym_escape($row->{$options['id']}).'"
420 - onclick="applyContent'.acym_escape($this->name).'(\''.acym_escape($row->{$options['id']}).'\', this);">';
421 -
422 - foreach ($options['header'] as $column => $oneColumn) {
423 - $value = $row->$column;
424 -
425 - if (!empty($oneColumn['type'])) {
426 - if ($oneColumn['type'] === 'date') {
427 - if (empty($value)) {
428 - $value = '-';
429 - } else {
430 - if (!is_numeric($value) && $value != '0000-00-00 00:00:00') {
431 - $value = strtotime($value);
432 - }
433 - $tooltip = acym_date($value, acym_translation('ACYM_DATE_FORMAT_LC2'));
434 - $value = acym_tooltip(
435 - [
436 - 'hoveredText' => acym_date($value, acym_translation('ACYM_DATE_FORMAT_LC5')),
437 - 'textShownInTooltip' => $tooltip,
438 - ]
439 - );
440 - }
441 - } elseif ($oneColumn['type'] === 'int') {
442 - $value = intval($value);
443 - }
444 - }
445 -
446 - $class = empty($oneColumn['class']) ? '' : ' '.$oneColumn['class'];
447 - $listing .= '<div class="cell medium-'.$oneColumn['size'].$class.'">'.$value.'</div>';
448 - }
449 -
450 - $listing .= '</div>';
451 - }
452 - }
453 -
454 - return $listing;
455 - }
456 -
457 - protected function getCategoryListing(): string
458 - {
459 - $listing = '';
460 - if (empty($this->catvalues)) {
461 - $listing .= '<h1 class="cell acym__listing__empty__search__modal text-center">'.acym_translation('ACYM_NO_RESULTS_FOUND').'</h1>';
462 -
463 - return $listing;
464 - }
465 -
466 - $listing .= '<div class="acym__popup__listing padding-0">';
467 - $selected = [];
468 - if (!empty($this->defaultValues->id) && strpos($this->defaultValues->id, '-')) {
469 - $selected = explode('-', $this->defaultValues->id);
470 - }
471 - foreach ($this->catvalues as $oneCat) {
472 - if (empty($oneCat->value)) continue;
473 -
474 - $classes = 'cell grid-x acym__row__no-listing acym__listing__row__popup';
475 - if (in_array($oneCat->value, $selected)) {
476 - $classes .= ' selected_row';
477 - }
478 - $listing .= '<div class="'.$classes.'" data-id="'.intval($oneCat->value).'" onclick="applyContentauto'.acym_escape($this->name).'('.intval($oneCat->value).', this);">
479 - <div class="cell medium-5">'.acym_escape($oneCat->text).'</div>
480 - </div>';
481 - }
482 - $listing .= '</div>';
483 -
484 - return $listing;
485 - }
486 -
487 - protected function getTagListing(): string
488 - {
489 - $listing = '';
490 - if (empty($this->tagvalues)) {
491 - $listing .= '<h1 class="cell acym__listing__empty__search__modal text-center">'.acym_translation('ACYM_NO_RESULTS_FOUND').'</h1>';
492 -
493 - return $listing;
494 - }
495 -
496 - $listing .= '<div class="acym__popup__listing padding-0">';
497 - $selected = [];
498 - if (!empty($this->defaultValues->id) && strpos($this->defaultValues->id, '-')) {
499 - $selected = explode('-', $this->defaultValues->id);
500 - }
501 - $termIdName = 'term_id';
502 - if ('wordpress' === ACYM_CMS) {
503 - $termIdName = 'term_taxonomy_id';
504 - }
505 - foreach ($this->tagvalues as $oneTag) {
506 - if (empty($oneTag->$termIdName)) continue;
507 -
508 - $class = 'cell grid-x acym__row__no-listing acym__listing__row__popup';
509 - if (in_array($oneTag->$termIdName, $selected)) $class .= ' selected_row';
510 - $listing .= '<div class="'.$class.'" data-id="'.intval($oneTag->$termIdName).'" onclick="applyContent'.acym_escape($this->name).'_tags('.intval($oneTag->$termIdName).', this);">
511 - <div class="cell medium-5">'.acym_escape($oneTag->name).'</div>
512 - </div>';
513 - }
514 - $listing .= '</div>';
515 -
516 - return $listing;
517 - }
518 -
519 - protected function replaceMultiple(object &$email)
520 - {
521 - $this->generateByCategory($email);
522 - if (empty($this->tags)) return;
523 -
524 - $this->pluginHelper->replaceTags($email, $this->tags, true);
525 - }
526 -
527 - protected function handleOrderBy(string &$query, object $parameter, ?string $table = null)
528 - {
529 - if (empty($parameter->order)) return;
530 -
531 - $ordering = explode(',', $parameter->order);
532 - if ($ordering[0] === 'rand') {
533 - $query .= ' ORDER BY rand()';
534 - } else {
535 - $table = null === $table ? '' : $table.'.';
536 - $column = $ordering[0];
537 -
538 - if (strpos($column, '.') !== false) {
539 - $parts = explode('.', $column, 2);
540 - $table = acym_secureDBColumn($parts[0]).'.';
541 - $column = $parts[1];
542 - }
543 -
544 - $query .= ' ORDER BY '.$table.'`'.acym_secureDBColumn(trim($column)).'` '.acym_secureDBColumn(trim($ordering[1]));
545 - }
546 - }
547 -
548 - protected function handleMax(string &$query, object $parameter): void
549 - {
550 - if (empty($parameter->max)) {
551 - $parameter->max = 20;
552 - }
553 - $query .= ' LIMIT '.intval($parameter->max);
554 - }
555 -
556 - protected function handleMin(array $elements, object $parameter): void
557 - {
558 - if (!empty($parameter->min) && count($elements) < $parameter->min) {
559 - $this->generateCampaignResult->status = false;
560 - $this->generateCampaignResult->message = acym_translationSprintf(
561 - 'ACYM_GENERATE_CAMPAIGN_NOT_ENOUGH_CONTENT',
562 - $this->pluginDescription->name,
563 - count($elements),
564 - $parameter->min
565 - );
566 - }
567 - }
568 -
569 - protected function getLastGenerated(int $mailId): int
570 - {
571 - $campaignClass = new CampaignClass();
572 -
573 - return $campaignClass->getLastGenerated($mailId);
574 - }
575 -
576 - protected function finalizeCategoryFormat(string $query, object $parameter, ?string $table = null): string
577 - {
578 - $this->handleOrderBy($query, $parameter, $table);
579 - $this->handleMax($query, $parameter);
580 -
581 - $elements = acym_loadResultArray($query);
582 -
583 - return $this->formatIndividualTags($elements, $parameter);
584 - }
585 -
586 - protected function formatIndividualTags(array $elements, object $parameter): string
587 - {
588 - $this->handleMin($elements, $parameter);
589 -
590 - if (empty($elements)) return '';
591 -
592 - $elements = $this->groupByCategory($elements);
593 -
594 - $customLayout = ACYM_CUSTOM_PLUGIN_LAYOUT.$this->name.'_auto.php';
595 - if (file_exists($customLayout)) {
596 - ob_start();
597 - require $customLayout;
598 -
599 - return ob_get_clean();
600 - }
601 -
602 - $arrayElements = $this->buildIndividualTags($elements, $parameter);
603 -
604 - return $this->pluginHelper->getFormattedResult($arrayElements, $parameter);
605 - }
606 -
607 - protected function buildIndividualTags(array $elements, object $parameter): array
608 - {
609 - $arrayElements = [];
610 - unset($parameter->id);
611 -
612 - $i = 0;
613 - foreach ($elements as $oneElementId) {
614 - $args = [];
615 - $args[] = $this->name.':'.$oneElementId;
616 -
617 - foreach ($parameter as $oneParam => $val) {
618 - if (is_bool($val)) {
619 - $args[] = $oneParam;
620 - } else {
621 - $args[] = $oneParam.':'.$val;
622 - }
623 - }
624 -
625 - if ($i % 2 === 1 && !empty($parameter->alternate)) {
626 - $args[] = 'invert';
627 - }
628 -
629 - $arrayElements[] = '{'.implode('| ', $args).'}';
630 -
631 - $i++;
632 - }
633 -
634 - return $arrayElements;
635 - }
636 -
637 - protected function groupByCategory(array $elements)
638 - {
639 - return $elements;
640 - }
641 -
642 - protected function getSelectedArea(object $parameter): array
643 - {
644 - $allcats = explode('-', $parameter->id);
645 - $selectedArea = [];
646 - foreach ($allcats as $oneCat) {
647 - if (empty($oneCat)) continue;
648 - $selectedArea[] = intval($oneCat);
649 - }
650 -
651 - return $selectedArea;
652 - }
653 -
654 - protected function replaceOne(object &$email): void
655 - {
656 - $tags = $this->pluginHelper->extractTags($email, $this->name);
657 - if (empty($tags)) return;
658 -
659 - $newConfiguration = [
660 - 'dcontent_default_'.get_class($this) => json_encode(end($tags)),
661 - ];
662 - $this->config->saveConfig($newConfiguration);
663 -
664 - if (method_exists($this, 'loadLibraries') && !$this->loadLibraries($email)) {
665 - return;
666 - }
667 -
668 - $this->emailLanguage = $email->links_language;
669 - $translationTool = $this->config->get('translate_content', 'no');
670 -
671 - $tagsReplaced = [];
672 - foreach ($tags as $i => $oneTag) {
673 - if (isset($tagsReplaced[$i])) continue;
674 -
675 - if (!empty($this->emailLanguage) && $translationTool !== 'no' && acym_isMultilingual()) {
676 - $oneTag->id = $this->getTranslationId($oneTag->id, $translationTool);
677 - }
678 - $tagsReplaced[$i] = $this->replaceIndividualContent($oneTag);
679 - }
680 -
681 - $email->custom_view = file_exists(ACYM_CUSTOM_PLUGIN_LAYOUT.$this->name.'.html');
682 -
683 - $this->pluginHelper->replaceTags($email, $tagsReplaced, true);
684 - }
685 -
686 - protected function initIndividualContent(object &$tag, string $query)
687 - {
688 - $element = acym_loadObject($query);
689 -
690 - if (empty($element)) {
691 - if (acym_isAdmin()) {
692 - acym_enqueueMessage(acym_translationSprintf('ACYM_CONTENT_NOT_FOUND', $tag->id), 'notice');
693 - }
694 -
695 - return null;
696 - }
697 -
698 - if (empty($tag->display)) {
699 - $tag->display = [];
700 - } else {
701 - $tag->display = explode(',', $tag->display);
702 - }
703 -
704 - return $element;
705 - }
706 -
707 - protected function getCustomLayoutVars(object $element): array
708 - {
709 - $varFields = [];
710 - $varFields['{picthtml}'] = '';
711 - foreach ($element as $fieldName => $oneField) {
712 - if (is_object($oneField) || is_array($oneField)) {
713 - $varFields['{'.$fieldName.'}'] = json_encode($oneField);
714 - } else {
715 - $varFields['{'.$fieldName.'}'] = $oneField;
716 - }
717 - }
718 -
719 - return $varFields;
720 - }
721 -
722 - protected function finalizeElementFormat(string $htmlResult, object $insertionOptions, array $dataShortcodes): string
723 - {
724 - $fullCustomLayoutPath = ACYM_CUSTOM_PLUGIN_LAYOUT.$this->name.'.php';
725 - if ($this->config->get('php_overrides', 0) == 1 && file_exists($fullCustomLayoutPath)) {
726 - ob_start();
727 - require $fullCustomLayoutPath;
728 - $viewContent = ob_get_clean();
729 - $htmlResult = str_replace(array_keys($dataShortcodes), $dataShortcodes, $viewContent);
730 - } else {
731 - $customLayoutPath = ACYM_CUSTOM_PLUGIN_LAYOUT.$this->name.'.html';
732 - if (file_exists($customLayoutPath)) {
733 - $dataShortcodes['{wrappedText}'] = $this->pluginHelper->wrappedText;
734 - $viewContent = acym_fileGetContent($customLayoutPath);
735 - $viewContentReplace = str_replace(array_keys($dataShortcodes), $dataShortcodes, $viewContent);
736 - if ($viewContent !== $viewContentReplace) {
737 - $htmlResult = $viewContentReplace;
738 - }
739 - }
740 - }
741 -
742 - $allShortcodesList = '<table><tr><th>Shortcode</th><th>Value</th></tr>';
743 - foreach ($dataShortcodes as $name => $value) {
744 - if (!is_string($value)) {
745 - continue;
746 - }
747 -
748 - $allShortcodesList .= '<tr><td>'.trim($name, '{}').'</td><td>'.$value.'</td></tr>';
749 - }
750 - $allShortcodesList .= '</table>';
751 - $htmlResult = str_replace('{allshortcodes}', $allShortcodesList, $htmlResult);
752 -
753 - return $this->pluginHelper->managePicts($insertionOptions, $htmlResult);
754 - }
755 -
756 - protected function filtersFromConditions(array &$filters): void
757 - {
758 - $newFilters = [];
759 -
760 - $this->onAcymDeclareConditions($newFilters);
761 - foreach ($newFilters as $oneType) {
762 - foreach ($oneType as $oneFilterName => $oneFilter) {
763 - if (!empty($oneFilter->option)) $oneFilter->option = str_replace(['acym_condition', '[conditions]'], ['acym_action', '[filters]'], $oneFilter->option);
764 - $filters[$oneFilterName] = $oneFilter;
765 - }
766 - }
767 - }
768 -
769 - protected function getElementTags(string $type, int $id): array
770 - {
771 - $tags = acym_loadObjectList(
772 - 'SELECT tags.`title`, tags.`alias`, tags.`id`
773 - FROM #__tags AS tags
774 - JOIN #__contentitem_tag_map AS map ON tags.`id` = map.`tag_id`
775 - WHERE map.`type_alias` = '.acym_escapeDB($type).'
776 - AND map.`content_item_id` = '.intval($id)
777 - );
778 -
779 - if (empty($tags)) return [];
780 -
781 - $displayTags = [];
782 - foreach ($tags as $oneTag) {
783 - $displayTags[] = '<a href="index.php?option=com_tags&view=tag&id='.$oneTag->id.':'.$oneTag->alias.'" target="_blank">'.$oneTag->title.'</a>';
784 - }
785 -
786 - return $displayTags;
787 - }
788 -
789 - protected function getFormattedValue(array $fieldValues)
790 - {
791 - $field = $fieldValues[0];
792 -
793 - if (!empty($field->fieldparams) && !is_array($field->fieldparams)) {
794 - $field->fieldparams = json_decode($field->fieldparams, true);
795 - }
796 -
797 - switch ($field->type) {
798 - case 'calendar':
799 - $format = acym_translation($field->fieldparams['showtime'] == '1' ? 'ACYM_DATE_FORMAT_LC2' : 'ACYM_DATE_FORMAT_LC1');
800 - $field->value = HTMLHelper::_('date', $field->value, $format);
801 - break;
802 -
803 - case 'checkboxes':
804 - case 'list':
805 - case 'radio':
806 - $values = [];
807 - foreach ($fieldValues as $oneValue) {
808 - foreach ($field->fieldparams['options'] as $oneOPT) {
809 - if ($oneOPT['value'] == $oneValue->value) {
810 - $values[] = $oneOPT['name'];
811 - break;
812 - }
813 - }
814 - }
815 -
816 - $field->value = implode(', ', $values);
817 - break;
818 -
819 - case 'dpcalendar':
820 - if (empty($field->value)) {
821 - $field->value = '';
822 - break;
823 - }
824 -
825 - $title = acym_loadResult('SELECT `title` FROM #__categories WHERE `id` = '.intval($field->value));
826 - if (empty($title)) {
827 - $field->value = '';
828 - } else {
829 - $date = '#year='.acym_date('now', 'Y').'&month='.acym_date('now', 'm').'&day='.acym_date('now', 'd').'&view=month';
830 - $field->value = '<a target="_blank" href="index.php?option=com_dpcalendar&view=calendar&id='.intval($field->value).$date.'">'.$title.'</a>';
831 - }
832 - break;
833 -
834 - case 'imagelist':
835 - if (!empty($field->fieldparams['directory']) && strlen($field->fieldparams['directory']) > 1) {
836 - $field->value = '/'.$field->value;
837 - } else {
838 - $field->fieldparams['directory'] = '';
839 - }
840 - $field->value = '<img src="images/'.$field->fieldparams['directory'].$field->value.'" />';
841 - break;
842 -
843 - case 'media':
844 - $value = '';
845 - if (!empty($field->value)) {
846 - if (substr($field->value, 0, 1) === '{') {
847 - $value = json_decode($field->value, true);
848 - if (!empty($value['imagefile'])) {
849 - $alt = empty($value['alt_text']) ? '' : ' alt="'.acym_escape($value['alt_text']).'"';
850 - $value = '<img src="'.$value['imagefile'].'"'.$alt.' />';
851 - }
852 - } else {
853 - $value = '<img src="'.$field->value.'" alt="" />';
854 - }
855 - }
856 -
857 - $field->value = $value;
858 - break;
859 -
860 - case 'repeatable':
861 - if (!empty($field->value)) {
862 - $values = is_string($field->value) ? json_decode($field->value) : $field->value;
863 - $formattedValues = [];
864 - foreach ($values as $oneSetOfValues) {
865 - $formattedSet = [];
866 - foreach ($oneSetOfValues as $oneLabel => $oneValue) {
867 - if (empty($oneValue)) continue;
868 -
869 - foreach ($field->fieldparams['fields'] as $oneField) {
870 - if ($oneField['fieldname'] !== $oneLabel) continue;
871 -
872 - if ($oneField['fieldtype'] === 'media') {
873 - $oneValue = '<img src="'.$oneValue.'" alt="" />';
874 - }
875 -
876 - $formattedSet[] = $oneValue;
877 - break;
878 - }
879 - }
880 -
881 - if (empty($formattedSet)) continue;
882 - $formattedValues[] = implode(', ', $formattedSet);
883 - }
884 -
885 - $field->value = empty($formattedSet) ? '' : '<ul><li>'.implode('</li><li>', $formattedValues).'</li></ul>';
886 - }
887 - break;
888 -
889 - case 'sql':
890 - if (empty($field->options)) {
891 - $field->options = acym_loadObjectList($field->fieldparams['query'], 'value');
892 - }
893 -
894 - $field->value = $field->options[$field->value]->text;
895 - break;
896 -
897 - case 'url':
898 - $field->value = '<a target="_blank" href="'.$field->value.'">'.$field->value.'</a>';
899 - break;
900 -
901 - case 'user':
902 - $field->value = acym_currentUserName($field->value);
903 - break;
904 -
905 - case 'usergrouplist':
906 - if (empty($field->usergroups)) {
907 - $field->usergroups = acym_loadObjectList('SELECT id, title FROM #__usergroups', 'id');
908 - }
909 -
910 - if (empty($field->usergroups[$field->value])) {
911 - $field->value = '';
912 - break;
913 - }
914 - $field->value = $field->usergroups[$field->value]->title;
915 - break;
916 - case 'subform':
917 - if (!empty($field->value)) {
918 - $rows = is_string($field->value) ? json_decode($field->value, true) : $field->value;
919 -
920 - $formattedValues = [];
921 - foreach ($rows as $values) {
922 - $fieldValues = [];
923 - foreach ($values as $fieldIdentifier => $fieldValue) {
924 - $fieldId = str_replace('field', '', $fieldIdentifier);
925 - $oneFieldDefinition = acym_loadObject(
926 - 'SELECT `field`.*
927 - FROM #__fields AS `field`
928 - WHERE `field`.`id` = '.intval($fieldId)
929 - );
930 -
931 - if (empty($oneFieldDefinition)) {
932 - break 3;
933 - }
934 -
935 - $multiCompatibleValues = [];
936 - if (is_array($fieldValue)) {
937 - foreach ($fieldValue as $oneFieldValue) {
938 - $oneValue = clone $oneFieldDefinition;
939 - $oneValue->value = $oneFieldValue;
940 - $multiCompatibleValues[] = $oneValue;
941 - }
942 - } else {
943 - $oneFieldDefinition->value = $fieldValue;
944 - $multiCompatibleValues[] = $oneFieldDefinition;
945 - }
946 -
947 - $fieldValues[] = $oneFieldDefinition->label.': '.$this->getFormattedValue($multiCompatibleValues);
948 - }
949 - $formattedValues[] = implode(', ', $fieldValues);
950 - }
951 -
952 - $field->value = empty($formattedValues) ? '' : '<ul><li>'.implode('</li><li>', $formattedValues).'</li></ul>';
953 - }
954 - }
955 -
956 - return $field->value;
957 - }
958 -
959 - protected function getLanguage(?string $elementLanguage = null, bool $onlyValue = false): string
960 - {
961 - $value = $this->emailLanguage;
962 - if (!empty($elementLanguage) && $elementLanguage !== '*') {
963 - $value = $elementLanguage;
964 - }
965 -
966 - if (empty($value)) {
967 - return '';
968 - }
969 -
970 - if (ACYM_CMS === 'joomla' && acym_isPluginActive('languagefilter')) {
971 - $languages = acym_loadObjectList('SELECT * FROM #__languages', 'lang_code');
972 - if (isset($languages[$value])) {
973 - $value = $languages[$value]->sef;
974 - } else {
975 - $value = substr($value, 0, strpos($value, '-'));
976 - }
977 -
978 - if ($onlyValue) {
979 - return $value;
980 - }
981 -
982 - return '&lang='.$value;
983 - } else {
984 - if ($onlyValue) {
985 - return $value;
986 - }
987 -
988 - return '&language='.$value;
989 - }
990 - }
991 -
992 - protected function finalizeLink(string $link, $tag = null, $sef = true): string
993 - {
994 - if (acym_isPluginActive('languagefilter')) {
995 - if (strpos($link, 'lang=') === false && !empty($this->emailLanguage)) {
996 - $link .= strpos($link, '?') === false ? '?' : '&';
997 - $link .= 'lang='.substr($this->emailLanguage, 0, strpos($this->emailLanguage, '-'));
998 - }
999 - } else {
1000 - if (strpos($link, 'language=') === false && !empty($this->emailLanguage)) {
1001 - $link .= strpos($link, '?') === false ? '?' : '&';
1002 - $link .= 'language='.$this->emailLanguage;
1003 - }
1004 - }
1005 -
1006 - if (!empty($tag->autologin)) {
1007 - $link .= (strpos($link, '?') ? '&' : '?').'autoSubId={subscriber:id}&subKey={subscriber:autologin_token|urlencode}';
1008 - }
1009 -
1010 - if (is_bool($tag)) {
1011 - $sef = $tag;
1012 - }
1013 -
1014 - return acym_frontendLink($link, false, $sef);
1015 - }
1016 -
1017 - protected function handleCustomFields(object $tag, array &$customFields): void
1018 - {
1019 - if (empty($tag->custom)) {
1020 - return;
1021 - }
1022 -
1023 - $tag->custom = explode(',', $tag->custom);
1024 - acym_arrayToInteger($tag->custom);
1025 -
1026 - $rawfields = acym_loadObjectList(
1027 - 'SELECT `field`.*, `values`.`value`
1028 - FROM #__fields_values AS `values`
1029 - JOIN #__fields AS `field` ON `values`.`field_id` = `field`.`id`
1030 - WHERE `values`.`item_id` = '.intval($tag->id).' AND `field`.`id` IN ('.implode(', ', $tag->custom).')'
1031 - );
1032 -
1033 - $fields = [];
1034 - foreach ($rawfields as $field) {
1035 - $fields[$field->id][] = $field;
1036 - }
1037 -
1038 - usort($fields, function ($a, $b) {
1039 - return $a[0]->ordering <=> $b[0]->ordering;
1040 - });
1041 -
1042 - foreach ($fields as $fieldValues) {
1043 - $value = $this->getFormattedValue($fieldValues);
1044 -
1045 - if (empty($value)) continue;
1046 -
1047 - $customFields[] = [
1048 - $value,
1049 - $fieldValues[0]->label,
1050 - ];
1051 - }
1052 - }
1053 -
1054 - protected function getIntro(string $text): string
1055 - {
1056 - $pageBreak = null;
1057 - $possibleBreaks = [
1058 - '<!--more-->',
1059 - '<hr id="system-readmore" />',
1060 - '<!--nextpage-->',
1061 - ];
1062 -
1063 - foreach ($possibleBreaks as $oneBreak) {
1064 - if (strpos($text, $oneBreak) !== false) {
1065 - $pageBreak = $oneBreak;
1066 - break;
1067 - }
1068 - }
1069 -
1070 - if (empty($pageBreak)) {
1071 - return $text;
1072 - }
1073 -
1074 - $split = explode($pageBreak, $text, 2);
1075 -
1076 - return array_shift($split);
1077 - }
1078 -
1079 - public function displayCustomViewEditor(string &$output): void
1080 - {
1081 - $plugin = new \stdClass();
1082 - $plugin->folder_name = $this->name;
1083 - $plugin->settings = $this->settings;
1084 - $this->generateSettings($plugin);
1085 -
1086 - if (empty($plugin->settings['custom_view'])) {
1087 - return;
1088 - }
1089 -
1090 - $output .= '<p class="acym__wysid__right__toolbar__p acym__wysid__right__toolbar__p__open acym__title">';
1091 - $output .= acym_translation('ACYM_ADDON_SETTINGS');
1092 - $output .= '<i class="acymicon-keyboard-arrow-up"></i></p>';
1093 - $output .= '<div class="acym__wysid__right__toolbar__design--show acym__wysid__right__toolbar__design acym__wysid__context__modal__container">';
1094 - $output .= $plugin->settings['custom_view'];
1095 - $output .= '</div>';
1096 - }
1097 -
1098 - public function generateSettings(object $plugin): bool
1099 - {
1100 - if (empty($plugin->settings)) return false;
1101 -
1102 - if (array_key_exists('not_installed', $plugin->settings)) {
1103 - $plugin->settings = 'not_installed';
1104 -
1105 - return true;
1106 - }
1107 -
1108 - foreach ($plugin->settings as $key => $field) {
1109 - $text = '';
1110 - if (empty($field['type'])) {
1111 - $plugin->settings[$key] = $text;
1112 - continue;
1113 - }
1114 -
1115 - $id = $plugin->folder_name.'_'.$key;
1116 - $name = $plugin->folder_name.'['.$key.']';
1117 - if (!empty($field['label'])) {
1118 - $field['label'] = acym_translation($field['label']);
1119 - }
1120 -
1121 - if (!empty($field['info'])) {
1122 - $field['label'] .= acym_info(
1123 - [
1124 - 'textShownInTooltip' => acym_translation($field['info']),
1125 - 'classText' => 'wysid_tooltip',
1126 - 'isWarning' => !empty($field['info_warning']),
1127 - ]
1128 - );
1129 - }
1130 -
1131 - if ($field['type'] === 'checkbox') {
1132 - $classLabel = 'shrink';
1133 - $text .= '<label for="'.acym_escape($id).'" class="cell '.acym_escape($classLabel).'">'.acym_escape($field['label']).'</label>';
1134 - $text .= '<input id="'.acym_escape($id).'" class="cell shrink" type="checkbox" name="'.acym_escape($name).'" '.(empty($field['value']) ? '' : 'checked').'>';
1135 - } elseif ($field['type'] === 'switch') {
1136 - $text .= acym_switch(
1137 - $name,
1138 - $field['value'],
1139 - $field['label'],
1140 - [],
1141 - 'large-7'
1142 - );
1143 - } elseif ($field['type'] === 'select') {
1144 - $text .= '<label class="cell shrink">'.$field['label'].'</label>';
1145 - $text .= acym_select(
1146 - $field['data'],
1147 - $name,
1148 - $field['value'],
1149 - ['class' => 'acym__select'],
1150 - 'value',
1151 - 'text',
1152 - false,
1153 - true
1154 - );
1155 - } elseif ($field['type'] === 'multiple_select') {
1156 - $text .= '<label class="cell shrink">'.$field['label'].'</label>';
1157 - $text .= acym_selectMultiple(
1158 - $field['data'],
1159 - $name,
1160 - empty($field['value']) ? [] : $field['value'],
1161 - ['class' => 'acym__select']
1162 - );
1163 - } elseif ($field['type'] === 'text') {
1164 - $text .= '<label class="cell shrink">'.$field['label'].'</label>';
1165 - $text .= '<input type="text" name="'.$name.'" value="'.acym_escape($field['value']).'" class="cell shrink">';
1166 - } elseif ($field['type'] === 'number') {
1167 - $text .= '<label class="cell shrink">'.$field['label'].'</label>';
1168 - $text .= '<input type="number" name="'.$name.'" value="'.acym_escape($field['value']).'" class="cell large-2 medium-5">';
1169 - if (!empty($field['post_text'])) $text .= '<span class="cell shrink">'.strtolower($field['post_text']).'</span>';
1170 - } elseif ($field['type'] === 'radio') {
1171 - $text .= '<p class="cell">'.$field['label'].'</p>';
1172 - $text .= acym_radio(
1173 - $field['data'],
1174 - $name,
1175 - $field['value']
1176 - );
1177 - } elseif ($field['type'] === 'date') {
1178 - $text .= '<label class="cell shrink">'.$field['label'].'</label>';
1179 - $text .= acym_dateField(
1180 - $name,
1181 - $field['value'],
1182 - 'cell shrink'
1183 - );
1184 - } elseif ($field['type'] === 'custom_view' && acym_isAdmin()) {
1185 - $idCustomView = 'acym__plugins__installed__custom-view__'.$this->name;
1186 - $ctrl = acym_getVar('string', 'ctrl', '');
1187 - $classTooltip = $ctrl === 'dynamics' ? '' : 'wysid_tooltip';
1188 - $text .= '<label class="cell">';
1189 - $text .= acym_translation('ACYM_CUSTOM_VIEW');
1190 - $text .= acym_info(
1191 - [
1192 - 'textShownInTooltip' => 'ACYM_CUSTOM_VIEW_DESC',
1193 - 'classText' => $classTooltip,
1194 - ]
1195 - );
1196 - $text .= '</label>';
1197 -
1198 - if (empty($field['tags'])) {
1199 - $field['tags'] = [];
1200 - }
1201 -
1202 - $modalContent = '<div id="'.acym_escape($idCustomView).'" class="cell grid-x acym__plugins__installed__custom-view" acym-data-tags="'.acym_escape(
1203 - json_encode($field['tags'])
1204 - ).'">
1205 - <h2 class="cell text-center acym__title__primary__color">'.acym_translationSprintf('ACYM_CUSTOM_VIEW_FOR_X', $this->pluginDescription->name).'</h2>
1206 - <div class="cell grid-x acym__plugins__installed__custom-view__edit-container">
1207 - <div class="acym__plugins__installed__custom-view__editor-loader grid-x cell align-center acym_vcenter" v-if="loading">'.acym_loaderLogo().'</div>
1208 - <vue-prism-editor :emitEvents="true" class="cell acym__plugins__installed__custom-view__code cell auto" v-model="code" :language="language" lineNumbers="true"></vue-prism-editor>
1209 - <div class="cell grid-x medium-3 margin-left-1 acym__plugins__installed__custom-view__tags">
1210 - <h3 class="acym__title acym__title__secondary cell text-center">'.acym_translation('ACYM_DYNAMIC_CONTENT').acym_info(
1211 - [
1212 - 'textShownInTooltip' => acym_translation('ACYM_DYNAMIC_CONTENT_DESC'),
1213 - ]
1214 - ).'</h3>
1215 - <div class="cell acym__plugins__installed__custom-view__tag" v-for="(trad, tag) in tags" :key="tag" @click.prevent="insertTag(tag)">{{ trad }}</div>
1216 - </div>
1217 - </div>
1218 - <div class="cell grid-x acym__plugins__installed__custom-view__actions acym_vcenter margin-top-1 padding-bottom-1">
1219 - <div class="cell auto grid-x">
1220 - <button type="button" class="cell shrink button-secondary button" @click="resetView">'.acym_translation('ACYM_RESET_VIEW').'</button>
1221 - <div class="cell shrink margin-right-2 acym_vcenter margin-left-1">
1222 - <i v-if="deleting" class="acymicon-spin acymicon-circle-o-notch" style="margin-bottom: 0; line-height: 26px;"></i>
1223 - <span v-if="deleted">{{ messageDeleted }}</span>
1224 - </div>
1225 - </div>
1226 - <div class="cell auto align-right grid-x">
1227 - <div class="cell shrink margin-right-2 acym_vcenter">
1228 - <i v-if="saving" class="acymicon-spin acymicon-circle-o-notch" style="margin-bottom: 0; line-height: 26px;"></i>
1229 - <span v-if="saved">{{ messageSaved }}</span>
1230 - </div>
1231 - <button @click="save()" class="cell shrink button" type="button">'.acym_translation('ACYM_SAVE_NEW_CUSTOM_VIEW_VERSION').'</button>
1232 - </div>
1233 - </div>
1234 - </div>';
1235 - $text .= acym_modal(
1236 - acym_translation('ACYM_EDIT_CUSTOM_VIEW'),
1237 - $modalContent,
1238 - null,
1239 - [
1240 - 'acym-data-plugins-id' => $idCustomView,
1241 - 'acym-data-plugin-class' => get_class($this),
1242 - 'acym-data-plugin-folder' => $this->name,
1243 - ],
1244 - ['class' => 'cell button']
1245 - );
1246 - } elseif ($field['type'] == 'multikeyvalue') {
1247 - $text .= '<label class="cell shrink">'.$field['label'].'</label>';
1248 -
1249 - $text .= '<div class="multikeyvalue_container grid-x">';
1250 -
1251 - if (!empty($field['value'])) {
1252 - $headers = json_decode($field['value'], true);
1253 - foreach ($headers as $headerKey => $headerValue) {
1254 - $text .= '<input type="text" class="cell" placeholder="'.acym_translation('ACYM_DKIM_KEY', true).'" value="'.acym_escape($headerKey).'"/>';
1255 - $text .= '<input type="text" class="cell" placeholder="'.acym_translation('ACYM_VALUE', true).'" value="'.acym_escape($headerValue).'" />';
1256 - $text .= '<div class="multikeyvalue_container_separator cell small-6"></div>';
1257 - }
1258 - }
1259 -
1260 - $text .= '<input type="text" class="cell" placeholder="'.acym_translation('ACYM_DKIM_KEY', true).'" value=""/>';
1261 - $text .= '<input type="text" class="cell" placeholder="'.acym_translation('ACYM_VALUE', true).'" value="" />';
1262 -
1263 - $text .= '<button class="button multikeyvalue_container_new">'.acym_translation('ACYM_ADD_NEW').'</button>';
1264 -
1265 - $text .= '<input type="hidden" name="'.$name.'" value="" />';
1266 - $text .= '</div>';
1267 - } elseif ($field['type'] == 'custom') {
1268 - $text .= $field['content'];
1269 - }
1270 - $plugin->settings[$key] = $text;
1271 - }
1272 -
1273 - return true;
1274 - }
1275 -
1276 - public function loadCSS(string $css, bool $raw = false, ?string $path = null): void
1277 - {
1278 - if (!$raw) {
1279 - if (empty($path)) $path = ACYM_DYNAMICS_URL.$this->name;
1280 - $css = $path.'/css/'.$css.'.css';
1281 - }
1282 - acym_addStyle($raw, $css);
1283 - }
1284 -
1285 - public function loadJavascript(string $js, bool $raw = false, ?string $path = null): void
1286 - {
1287 - if (!$raw) {
1288 - if (empty($path)) $path = ACYM_DYNAMICS_URL.$this->name;
1289 - $js = $path.'/js/'.$js.'.js';
1290 - }
1291 - acym_addScript($raw, $js);
1292 - }
1293 -
1294 - public function includeView(string $view, array $data = [], ?string $path = null): string
1295 - {
1296 - if (empty($path)) {
1297 - $path = ACYM_ADDONS_FOLDER_PATH.$this->name.DS.'views'.DS.$view.'.php';
1298 - } else {
1299 - $path = $path.DS.'views'.DS.$view.'.php';
1300 - }
1301 -
1302 - if (!file_exists($path)) {
1303 - throw new \Exception(acym_translation('ACYM_NON_EXISTING_PAGE'));
1304 - }
1305 -
1306 - ob_start();
1307 - include $path;
1308 -
1309 - return ob_get_clean();
1310 - }
1311 -
1312 - public function onAcymAddSettings(array &$plugins): void
1313 - {
1314 - if (method_exists($this, 'initSettings')) {
1315 - $this->initSettings();
1316 - }
1317 -
1318 - foreach ($plugins as $key => $plugin) {
1319 - if ($plugin->folder_name === $this->name) {
1320 - if (!empty($plugin->settings)) {
1321 - foreach ($plugin->settings as $keySettings => $value) {
1322 - if (isset($this->settings[$keySettings]['value'])) {
1323 - $this->settings[$keySettings]['value'] = $plugin->settings[$keySettings]['value'];
1324 - }
1325 - }
1326 - }
1327 - $plugins[$key]->settings = $this->settings;
1328 -
1329 - $this->generateSettings($plugins[$key]);
1330 - break;
1331 - }
1332 - }
1333 - }
1334 -
1335 - protected function getParam(string $name, $default = '')
1336 - {
1337 - return $this->savedSettings[$name]['value'] ?? $default;
1338 - }
1339 -
1340 - protected function getTranslationId(int $elementId, string $translationTool, bool $defaultLanguage = false)
1341 - {
1342 - return $elementId;
1343 - }
1344 -
1345 - public function filterSpecialMailsDailySend(array &$specialMails, int $time, string $mailType): void
1346 - {
1347 - $dailyHour = $this->config->get('daily_hour', '12');
1348 - $dailyMinute = $this->config->get('daily_minute', '00');
1349 - $dayBasedOnCMSTimezone = acym_date('now', 'Y-m-d');
1350 - $dayBasedOnCMSTimezoneAtSpecifiedHour = acym_getTimeFromCMSDate($dayBasedOnCMSTimezone.' '.$dailyHour.':'.$dailyMinute);
1351 -
1352 - $campaignClass = new CampaignClass();
1353 -
1354 - $tmpMails = [];
1355 - foreach ($specialMails as $oneMail) {
1356 - if ($oneMail->sending_type === $mailType) {
1357 - $noNextTrigger = empty($oneMail->next_trigger);
1358 - $nextTriggerIsNow = date('m-d', $oneMail->next_trigger) == date('m-d', $dayBasedOnCMSTimezoneAtSpecifiedHour);
1359 - $nextTriggerIsInPast = $oneMail->next_trigger < $time;
1360 - if ($time >= $dayBasedOnCMSTimezoneAtSpecifiedHour && ($noNextTrigger || $nextTriggerIsNow || $nextTriggerIsInPast)) {
1361 - $oneMail->next_trigger = acym_getTime('tomorrow '.$dailyHour.':'.$dailyMinute);
1362 - $oneMail->last_generated = $time;
1363 - $campaignClass->save($oneMail);
1364 - $tmpMails[] = $oneMail;
1365 - }
1366 - } else {
1367 - $tmpMails[] = $oneMail;
1368 - }
1369 - }
1370 - $specialMails = $tmpMails;
1371 - }
1372 -
1373 - protected function getIdsSelectAjax(): array
1374 - {
1375 - $ids = acym_getVar('string', 'id');
1376 - if (empty($ids)) {
1377 - return [];
1378 - }
1379 -
1380 - $ids = explode(',', $ids);
1381 - acym_arrayToInteger($ids);
1382 -
1383 - return $ids;
1384 - }
1385 -
1386 - protected function cleanExtensionContent(string $text)
1387 - {
1388 - if (ACYM_CMS === 'wordpress') {
1389 - if (!acym_isExtensionActive('classic-editor/classic-editor.php') || strpos($text, '<!-- wp:') !== false) {
1390 - return $text;
1391 - }
1392 -
1393 - return nl2br($text);
1394 - } else {
1395 - return preg_replace('#\{igallery[^}]+\}#Ui', '', $text);
1396 - }
1397 - }
1398 -
1399 - protected function callApiSendingMethod(string $url, array $data = [], array $headers = [], string $type = 'GET', array $authentication = [], bool $dataDecoded = false): array
1400 - {
1401 - if (!empty($headers) && empty($headers[0])) {
1402 - $newHeaders = [];
1403 - foreach ($headers as $key => $value) {
1404 - $newHeaders[] = $key.': '.$value;
1405 - }
1406 - $headers = $newHeaders;
1407 - }
1408 -
1409 - $curl = curl_init();
1410 -
1411 - $optionsArray = [
1412 - CURLOPT_URL => $url,
1413 - CURLOPT_RETURNTRANSFER => true,
1414 - CURLOPT_ENCODING => '',
1415 - CURLOPT_MAXREDIRS => 10,
1416 - CURLOPT_TIMEOUT => 30,
1417 - CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
1418 - CURLOPT_CUSTOMREQUEST => $type,
1419 - CURLOPT_HTTPHEADER => $headers,
1420 - CURLOPT_SSL_VERIFYHOST => 0,
1421 - CURLOPT_SSL_VERIFYPEER => 0,
1422 - ];
1423 -
1424 - if (!empty($data)) {
1425 - if (empty($dataDecoded)) {
1426 - $optionsArray[CURLOPT_POSTFIELDS] = json_encode($data);
1427 - } elseif ($dataDecoded === true) {
1428 - $optionsArray[CURLOPT_POSTFIELDS] = $data;
1429 - }
1430 - }
1431 -
1432 - if (!empty($authentication)) {
1433 - $optionsArray[CURLOPT_USERPWD] = $authentication['name'].':'.$authentication['pwd'];
1434 - }
1435 -
1436 - curl_setopt_array(
1437 - $curl,
1438 - $optionsArray
1439 - );
1440 -
1441 - $response = curl_exec($curl);
1442 - $error = curl_error($curl);
1443 - $this->responseCode = (int)curl_getinfo($curl, CURLINFO_HTTP_CODE);
1444 -
1445 - if ($error) {
1446 - return ['error_curl' => $error];
1447 - } else {
1448 - $response = json_decode($response, true);
1449 -
1450 - return $response === null ? ['error_curl' => 'Malformed response'] : $response;
1451 - }
1452 - }
1453 -
1454 - protected function getTestCredentialsSendingMethodButton(string $sendingMethodId): string
1455 - {
1456 - return '<div class="cell grid-x margin-top-1 acym__sending__methods__credentials__test">
1457 - <button type="button" sending-method-id="'.acym_escape($sendingMethodId).'" class="acym__configuration__sending__method-test cell shrink button button-secondary">
1458 - '.acym_translation('ACYM_TEST_CREDENTIALS').'
1459 - </button>
1460 - <span class="acym__configuration__sending__method-icon cell shrink margin-left-1 acym_vcenter"></span>
1461 - <span class="acym__configuration__sending__method-test__message cell shrink margin-left-1 acym_vcenter"></span>
1462 - </div>';
1463 - }
1464 -
1465 - public function getCopySettingsButton(array $data, string $sendingMethodId, string $fromPlugin, bool $withContainer = true): string
1466 - {
1467 - if (empty($data[$fromPlugin.'_installed'])) {
1468 - return '';
1469 - }
1470 -
1471 - $button = '<button
1472 - type="button"
1473 - class="cell shrink button button-secondary acym__configuration__copy__mail__settings"
1474 - acym-data-plugin="'.acym_escape($fromPlugin).'"
1475 - acym-data-method="'.acym_escape($sendingMethodId).'">
1476 - '.acym_translationSprintf('ACYM_COPY_SETTINGS_FROM', $this->sendingPlugins[$fromPlugin]).'
1477 - </button>
1478 - <span class="acym__configuration__sending__method-icon cell shrink margin-left-1 acym_vcenter"></span>';
1479 -
1480 - if ($withContainer) {
1481 - $button = '<div class="cell grid-x margin-top-1">'.$button.'</div>';
1482 - }
1483 -
1484 - return $button;
1485 - }
1486 -
1487 - protected function getLinks(string $account = '', string $pricing = ''): string
1488 - {
1489 - if (empty($account) && empty($pricing)) return '';
1490 -
1491 - $html = '<div class="cell grid-x acym-grid-margin-x shrink acym_vcenter"><p class="cell shrink">'.acym_translation('ACYM_DONT_HAVE_ACCOUNT').'</p>';
1492 - if (!empty($account)) $html .= '<a target="_blank" class="cell shrink" href="'.$account.'">'.acym_translation('ACYM_CREATE_ONE').'</a>';
1493 - if (!empty($account) && !empty($pricing)) $html .= '<p class="cell shrink">'.strtolower(acym_translation('ACYM_OR')).'</p>';
1494 - if (!empty($pricing)) $html .= '<a target="_blank" class="cell shrink" href="'.$pricing.'">'.acym_translation('ACYM_CHECK_THEIR_PRICING').'</a>';
1495 - $html .= '</div>';
1496 -
1497 - return $html;
1498 - }
1499 -
1500 - public function onAcymGetSendingMethodsSelected(array &$data): void
1501 - {
1502 - if (ACYM_CMS === 'wordpress') {
1503 - $this->config->load();
1504 - }
1505 -
1506 - $mailerMethod = $this->config->get('mailer_method', 'phpmail');
1507 - foreach ($data['sendingMethods'] as $key => $sendingMethod) {
1508 - $data['sendingMethods'][$key]['selected'] = $key == $mailerMethod;
1509 - }
1510 - }
1511 -
1512 - public function errorCallback(): void
1513 - {
1514 - foreach ($this->errors as $error) {
1515 - acym_logError($error, empty($this->name) ? get_class($this) : $this->name);
1516 - }
1517 -
1518 - $this->errors = [];
1519 - }
1520 -
1521 - public function isLogFileEmpty(): bool
1522 - {
1523 - return !acym_isLogFileErrorExist(empty($this->name) ? get_class($this) : $this->name);
1524 - }
1525 -
1526 - public function initCustomView(bool $customFields = false): void
1527 - {
1528 - $page = acym_getVar('cmd', 'page');
1529 - if (is_array($page)) return;
1530 - if (!empty($page) && is_string($page)) {
1531 - $page = str_replace(ACYM_COMPONENT.'_', '', $page);
1532 - }
1533 - $ctrl = acym_getVar('cmd', 'ctrl', $page);
1534 - if (!in_array($ctrl, ['plugins', 'dynamics'])) return;
1535 -
1536 - $task = acym_getVar('cmd', 'task', 'installed');
1537 -
1538 - if (($ctrl === 'plugins' && $task === 'installed') || ($this->active && $ctrl === 'dynamics' && $task === 'trigger')) {
1539 - $this->initElementOptionsCustomView();
1540 - $this->initReplaceOptionsCustomView();
1541 - if ($customFields) $this->initCustomOptionsCustomView();
1542 - }
1543 - }
1544 -
1545 - public function processDateToCheck(array $options): \DateTime
1546 - {
1547 - $dateNowWithTimeZone = acym_date('now', 'Y-m-d h:i:s');
1548 - $dateToCheck = new \DateTime($dateNowWithTimeZone);
1549 - $interval = new \DateInterval('P'.intval($options['days']).'D');
1550 - if ($options['relative'] === 'before') {
1551 - $dateToCheck->add($interval);
1552 - } else {
1553 - $dateToCheck->sub($interval);
1554 - }
1555 -
1556 - return $dateToCheck;
1557 - }
1558 -
1559 - public function onAcymCheckInstalled(bool &$installed): void
1560 - {
1561 - $installed = $this->installed;
1562 - }
1563 -
1564 - protected function getLinkTranslated(string $link): string
1565 - {
1566 - if (empty($this->emailLanguage)) return $link;
1567 - if (!acym_isMultilingual()) return $link;
1568 -
1569 - $translationTool = $this->config->get('translate_content', 'no');
1570 - if ($translationTool !== 'wpml') return $link;
1571 -
1572 - if (!acym_isExtensionActive('sitepress-multilingual-cms/sitepress.php')) return $link;
1573 -
1574 - $languageCode = substr($this->emailLanguage, 0, 2);
1575 -
1576 - return apply_filters('wpml_permalink', $link, $languageCode);
1577 - }
1578 -
1579 - protected function replaceShortcode(string $content): string
1580 - {
1581 - $content = do_shortcode($content);
1582 -
1583 - return preg_replace('#<!-- wp:shortcode -->(.*)<!-- /wp:shortcode -->#Uis', '$1', $content);
1584 - }
1585 -
1586 - protected function fixDivStructure(string $text): string
1587 - {
1588 - $nbOpeningDivs = substr_count($text, '<div');
1589 - $nbClosingDivs = substr_count($text, '</div>');
1590 -
1591 - if ($nbOpeningDivs > $nbClosingDivs) {
1592 - $text .= str_repeat('</div>', $nbOpeningDivs - $nbClosingDivs);
1593 - } elseif ($nbOpeningDivs < $nbClosingDivs) {
1594 - $text = str_repeat('<div>', $nbClosingDivs - $nbOpeningDivs).$text;
1595 - }
1596 -
1597 - return $text;
1598 - }
1599 -
1600 - protected function getBounceAddress(object $mailerHelper): string
1601 - {
1602 - if (method_exists($mailerHelper, 'getSendSettings')) {
1603 - return $mailerHelper->getSendSettings('bounce_email');
1604 - } else {
1605 - return $this->config->get('bounce_email');
1606 - }
1607 - }
1608 -}