PluginProbe
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress / 10.11.1
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress v10.11.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
acymailing / back / Helpers / PluginHelper.php

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

1,357 lines 55.9 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\MailClass;
6 use AcyMailing\Core\AcymObject;
7
8 class PluginHelper extends AcymObject
9 {
10 private MailerHelper $mailerHelper;
11 public string $name = 'content';
12 public string $wrappedText = '';
13 public string $contextLanguage;
14
15 public function getFormattedResult(array $elements, object $parameter): string
16 {
17 if (count($elements) < 2) {
18 return implode('', $elements);
19 }
20
21 $beforeAll = [];
22 $beforeAll['table'] = '<table cellspacing="0" cellpadding="0" border="0" width="100%" class="elementstable">'."\n";
23 $beforeAll['ul'] = '<ul class="elementsul">'."\n";
24 $beforeAll['br'] = '';
25
26 $beforeBlock = [];
27 $beforeBlock['table'] = '<tr class="elementstable_tr numrow{rownum}">'."\n";
28 $beforeBlock['ul'] = '';
29 $beforeBlock['br'] = '';
30
31 $beforeOne = [];
32 $beforeOne['table'] = '<td valign="top" width="{equalwidth}" style="{padding}" class="elementstable_td numcol{numcol}" >'."\n";
33 $beforeOne['ul'] = '<li class="elementsul_li numrow{rownum}">'."\n";
34 $beforeOne['br'] = '';
35
36 $afterOne = [];
37 $afterOne['table'] = '</td>'."\n";
38 $afterOne['ul'] = '</li>'."\n";
39 $afterOne['br'] = '<br />'."\n";
40
41 $afterBlock = [];
42 $afterBlock['table'] = '</tr>'."\n";
43 $afterBlock['ul'] = '';
44 $afterBlock['br'] = '';
45
46 $afterAll = [];
47 $afterAll['table'] = '</table>'."\n";
48 $afterAll['ul'] = '</ul>'."\n";
49 $afterAll['br'] = '';
50
51
52 $type = 'table';
53 $cols = 1;
54 if (!empty($parameter->displaytype)) {
55 $type = $parameter->displaytype;
56 }
57 if ($type == 'none') {
58 return implode('', $elements);
59 }
60 if (!empty($parameter->cols)) {
61 $cols = $parameter->cols;
62 }
63
64 $parameter->hpadding = !isset($parameter->hpadding) || is_null($parameter->hpadding) ? 10 : $parameter->hpadding;
65 $parameter->vpadding = !isset($parameter->vpadding) || is_null($parameter->vpadding) ? 10 : $parameter->vpadding;
66
67 $horizontalPadding = round($parameter->hpadding / 2);
68 $verticalPadding = round($parameter->vpadding / 2);
69
70 $string = $beforeAll[$type];
71 $a = 0;
72 $numrow = 1;
73 foreach ($elements as $key => $oneElement) {
74 $topPadding = $verticalPadding.'px';
75 $rightPadding = $horizontalPadding.'px';
76 $bottomPadding = $verticalPadding.'px';
77 $leftPadding = $horizontalPadding.'px';
78
79 if ($a == $cols) {
80 $string .= $afterBlock[$type];
81 $a = 0;
82 $numrow++;
83 }
84
85 if ($a == 0) {
86 $string .= str_replace('{rownum}', $numrow, $beforeBlock[$type]);
87 $leftPadding = '0px';
88 }
89
90 if ($a + 1 == $cols) $rightPadding = '0px';
91 if ($numrow == 1) $topPadding = '0px';
92 if (round(count($elements) / $cols) == $numrow) $bottomPadding = '0px';
93
94 $padding = 'padding: '.$topPadding.' '.$rightPadding.' '.$bottomPadding.' '.$leftPadding.' !important;';
95
96 $string .= str_replace('{numcol}', $a + 1, $beforeOne[$type]).$oneElement.$afterOne[$type];
97 $string = str_replace('{padding}', $padding, $string);
98 $a++;
99 }
100 while ($cols > $a) {
101 $string .= str_replace('{numcol}', $a + 1, $beforeOne[$type]).$afterOne[$type];
102 $a++;
103 }
104
105 $string .= $afterBlock[$type];
106 $string .= $afterAll[$type];
107
108 $equalwidth = intval(100 / $cols).'%';
109
110 return str_replace(['{equalwidth}'], [$equalwidth], $string);
111 }
112
113 public function formatString(&$replaceme, object $mytag): void
114 {
115 if (!empty($mytag->part)) {
116 $parts = explode(' ', $replaceme);
117 if ($mytag->part == 'last') {
118 $replaceme = count($parts) > 1 ? end($parts) : '';
119 } else {
120 if (is_numeric($mytag->part) && count($parts) >= $mytag->part) {
121 $replaceme = $parts[$mytag->part - 1];
122 } else {
123 $replaceme = reset($parts);
124 }
125 }
126 }
127
128 if (!empty($mytag->type)) {
129 if (empty($mytag->format)) {
130 $mytag->format = acym_translation('ACYM_DATE_FORMAT_LC3');
131 }
132 if ($mytag->type == 'date') {
133 $replaceme = acym_getDate(acym_getTime($replaceme), $mytag->format);
134 } elseif ($mytag->type == 'time') {
135 $replaceme = acym_getDate($replaceme, $mytag->format);
136 } elseif ($mytag->type == 'diff') {
137 try {
138 $date = $replaceme;
139 if (is_numeric($date)) {
140 $date = acym_getDate($replaceme, '%Y-%m-%d %H:%M:%S');
141 }
142 $dateObj = new \DateTime($date);
143 $nowObj = new \DateTime();
144 $diff = $dateObj->diff($nowObj);
145 $replaceme = $diff->format($mytag->format);
146 } catch (\Exception $e) {
147 $replaceme = 'Error using the "diff" parameter in your tag. Please make sure the DateTime() and diff() functions are available on your server.';
148 }
149 }
150 }
151
152 if (!empty($mytag->lower) || !empty($mytag->lowercase)) {
153 $replaceme = function_exists('mb_strtolower') ? mb_strtolower($replaceme, 'UTF-8') : strtolower($replaceme);
154 }
155 if (!empty($mytag->upper) || !empty($mytag->uppercase)) {
156 $replaceme = function_exists('mb_strtoupper') ? mb_strtoupper($replaceme, 'UTF-8') : strtoupper($replaceme);
157 }
158 if (!empty($mytag->ucwords)) {
159 $replaceme = ucwords($replaceme);
160 }
161 if (!empty($mytag->ucfirst)) {
162 $replaceme = ucfirst($replaceme);
163 }
164 if (isset($mytag->rtrim)) {
165 $replaceme = empty($mytag->rtrim) ? rtrim($replaceme) : rtrim($replaceme, $mytag->rtrim);
166 }
167 if (!empty($mytag->urlencode)) {
168 $replaceme = urlencode($replaceme);
169 }
170 if (!empty($mytag->substr)) {
171 $args = explode(',', $mytag->substr);
172 if (isset($args[1])) {
173 $replaceme = substr($replaceme, intval($args[0]), intval($args[1]));
174 } else {
175 $replaceme = substr($replaceme, intval($args[0]));
176 }
177 }
178
179
180 if (!empty($mytag->maxheight) || !empty($mytag->maxwidth)) {
181 $imageHelper = new ImageHelper();
182 $imageHelper->maxHeight = empty($mytag->maxheight) ? 999 : $mytag->maxheight;
183 $imageHelper->maxWidth = empty($mytag->maxwidth) ? 999 : $mytag->maxwidth;
184 $replaceme = $imageHelper->resizePictures($replaceme);
185 }
186 }
187
188 public function replaceVideos(string &$text): void
189 {
190 $text = preg_replace(
191 '#\[embed=videolink][^}]*youtube[^=]*=([^"/}]*)[^}]*}\[/embed]#i',
192 '<a target="_blank" href="https://www.youtube.com/watch?v=$1"><img src="https://img.youtube.com/vi/$1/0.jpg"/></a>',
193 $text
194 );
195 $text = preg_replace(
196 '#<video[^>]*youtube\.com/embed/([^"/]*)[^>]*>[^>]*</video>#i',
197 '<a target="_blank" href="https://www.youtube.com/watch?v=$1"><img src="https://img.youtube.com/vi/$1/0.jpg"/></a>',
198 $text
199 );
200 $text = preg_replace(
201 '#{JoooidContent[^}]*youtube[^}]*id"[^"]*"([^}"]*)"[^}]*}#i',
202 '<a target="_blank" href="https://www.youtube.com/watch?v=$1"><img src="https://img.youtube.com/vi/$1/0.jpg"/></a>',
203 $text
204 );
205 $text = preg_replace(
206 '#<iframe[^>]*src="[^"]*youtube[^"]*embed/([^"?]*)(\?[^"]*)?"[^>]*>[^<]*</iframe>#Uis',
207 '<a target="_blank" href="https://www.youtube.com/watch?v=$1"><img src="https://img.youtube.com/vi/$1/0.jpg"/></a>',
208 $text
209 );
210
211 $text = preg_replace(
212 '#{youtube}[^{]+v=([^{&]+)(&[^{]*)?{/youtube}#Uis',
213 '<a target="_blank" href="https://www.youtube.com/watch?v=$1"><img src="https://img.youtube.com/vi/$1/0.jpg"/></a>',
214 $text
215 );
216
217 $text = preg_replace('#{vimeo}(https://vimeo.com/[^{]+){/vimeo}#Uis', '<iframe src="$1"></iframe>', $text);
218 $text = preg_replace('#{vimeo}([^{]+){/vimeo}#Uis', '<iframe src="https://player.vimeo.com/video/$1"></iframe>', $text);
219
220 if (preg_match_all('#<iframe[^>]*src="[^"]*vimeo[^"]*/(\d+)([&/\?][^"]*)?"[^>]*>[^<]*</iframe>#Uis', $text, $matches)) {
221 foreach ($matches[1] as $key => $match) {
222 $hash = acym_fileGetContent('https://vimeo.com/api/v2/video/'.$match.'.php');
223 $hash = @unserialize($hash);
224 if (empty($hash)) continue;
225
226 if (strpos($matches[0][$key], ' width="') !== false) {
227 $extension = substr($hash[0]['thumbnail_large'], strrpos($hash[0]['thumbnail_large'], '.'));
228 preg_match('#width="([^"]*)"#Uis', $matches[0][$key], $width);
229
230 $replace = strpos($hash[0]['thumbnail_large'], '_') === false ? '.' : '_';
231 $hash[0]['thumbnail_large'] = substr($hash[0]['thumbnail_large'], 0, strrpos($hash[0]['thumbnail_large'], $replace)).'_'.$width[1].$extension;
232 }
233 $thumbnail = 'https://i.vimeocdn.com/filter/overlay?src='.urlencode($hash[0]['thumbnail_large']);
234 $thumbnail .= '&src='.urlencode('https://f.vimeocdn.com/p/images/crawler_play.png');
235
236 $text = str_replace(
237 $matches[0][$key],
238 '<a target="_blank" href="'.acym_escape($hash[0]['url']).'"><img class="donotresize" alt="" src="'.acym_escape($thumbnail).'" /></a>',
239 $text
240 );
241 }
242 }
243
244 $text = preg_replace('#\[embed=videolink][^}]*video":"([^"]*)[^}]*}\[/embed]#i', '<a target="_blank" href="$1"><img src="'.ACYM_IMAGES.'/video.png"/></a>', $text);
245 $text = preg_replace('#<video[^>]*src="([^"]*)"[^>]*>[^>]*</video>#i', '<a target="_blank" href="$1"><img src="'.ACYM_IMAGES.'/video.png"/></a>', $text);
246 }
247
248 private function convertbase64pictures(string &$html): void
249 {
250 if (!preg_match_all('#<img[^>]*src=("data:image/([^;]{1,5});base64[^"]*")([^>]*)>#Uis', $html, $resultspictures)) {
251 return;
252 }
253
254
255
256 $dest = ACYM_MEDIA.'resized'.DS;
257 acym_createDir($dest);
258 foreach ($resultspictures[2] as $i => $extension) {
259 $pictname = md5($resultspictures[1][$i]).'.'.$extension;
260 $picturl = ACYM_LIVE.str_replace(DS, '/', ACYM_MEDIA_FOLDER).'resized/'.$pictname;
261 $pictPath = $dest.$pictname;
262 $pictCode = trim($resultspictures[1][$i], '"');
263 if (file_exists($pictPath)) {
264 $html = str_replace($pictCode, $picturl, $html);
265 continue;
266 }
267
268 if (!ini_get('allow_url_fopen')) {
269 continue;
270 }
271
272 $getfunction = '';
273 switch ($extension) {
274 case 'gif':
275 $getfunction = 'ImageCreateFromGIF';
276 break;
277 case 'jpg':
278 case 'jpeg':
279 $getfunction = 'ImageCreateFromJPEG';
280 break;
281 case 'png':
282 $getfunction = 'ImageCreateFromPNG';
283 break;
284 }
285
286 if (empty($getfunction) || !function_exists($getfunction)) {
287 continue;
288 }
289
290 $img = $getfunction($pictCode);
291 if ($img === false) {
292 continue;
293 }
294
295 if (in_array($extension, ['gif', 'png'])) {
296 imagealphablending($img, false);
297 imagesavealpha($img, false);
298 }
299
300 ob_start();
301 switch ($extension) {
302 case 'gif':
303 $status = imagegif($img);
304 break;
305 case 'jpg':
306 case 'jpeg':
307 $status = imagejpeg($img, null, 100);
308 break;
309 case 'png':
310 $status = imagepng($img, null, 1);
311 break;
312 }
313 $imageContent = ob_get_clean();
314 $status = $status && acym_writeFile($pictPath, $imageContent);
315
316 if (!$status) {
317 continue;
318 }
319 $html = str_replace($pictCode, $picturl, $html);
320 }
321 }
322
323 public function cleanHtml(string &$html): void
324 {
325 $this->convertbase64pictures($html);
326
327 $pregreplace = [];
328 $pregreplace['#<tr([^>"]*>([^<]*<td[^>]*>[ \n\s]*<img[^>]*>[ \n\s]*</ *td[^>]*>[ \n\s]*)*</ *tr)#Uis'] = '<tr style="line-height: 0px;" $1';
329 $pregreplace['#<td(((?!style|>).)*>[ \n\s]*(<a[^>]*>)?[ \n\s]*<img[^>]*>[ \n\s]*(</a[^>]*>)?[ \n\s]*</ *td)#Uis'] = '<td style="line-height: 0px;" $1';
330
331 $pregreplace['#{tab[ =][^}]*}#is'] = '';
332 $pregreplace['#{/tabs}#is'] = '';
333 $pregreplace['#{jcomments\s+(on|off|lock)}#is'] = '';
334
335 $pregreplace["#(onmouseout|onmouseover|onclick|onfocus|onload|onblur) *= *\"(?:(?!\").)*\"#Ui"] = '';
336 $pregreplace["#< *script(?:(?!< */ *script *>).)*< */ *script *>#Uis"] = '';
337 $pregreplace["#< *iframe(?:(?!< */ *iframe *>).)*< */ *iframe *>#Uis"] = '';
338
339 $pregreplace['#(<p style=")([^>]*>\s*<img *[^>]*margin-left: auto; margin-right: auto;[^>]*>\s*</p>)#Uis'] = '$1text-align: center;$2';
340 $pregreplace['#(<img [^>]*src="[^"]+\.webp"[^>]*>)#Uis'] = '<!--[if !mso]><!-->$1<!--<![endif]-->';
341
342 $newbody = preg_replace(array_keys($pregreplace), $pregreplace, $html);
343 if (!empty($newbody)) {
344 $html = $newbody;
345 }
346
347 $body = preg_replace_callback('/src="([^"]* [^"]*)"/Ui', [$this, 'convertSpaces'], $html);
348 if (!empty($body)) $html = $body;
349
350 $html = acym_cmsCleanHtml($html);
351 }
352
353 public function convertSpaces(array $matches): string
354 {
355 return "src='".str_replace(' ', '%20', $matches[1])."'";
356 }
357
358 public function replaceTags(object &$email, array $tags, bool $html = false): void
359 {
360 if (empty($tags)) return;
361
362 $htmlVars = ['body'];
363 $textVars = [
364 'subject',
365 'AltBody',
366 'From',
367 'FromName',
368 'ReplyTo',
369 'ReplyName',
370 'bcc',
371 'cc',
372 'fromname',
373 'fromemail',
374 'replyname',
375 'replyemail',
376 'params',
377 'preheader',
378 ];
379
380 $variables = array_merge($htmlVars, $textVars);
381
382 if ($html) {
383 if (empty($this->mailerHelper)) {
384 $this->mailerHelper = new MailerHelper();
385 }
386
387 $textreplace = [];
388 foreach ($tags as $i => $replacement) {
389 if (isset($textreplace[$i])) continue;
390 $textreplace[$i] = $this->mailerHelper->textVersion($replacement);
391 }
392 } else {
393 $textreplace = $tags;
394 }
395
396 foreach ($variables as $var) {
397 if (empty($email->$var)) continue;
398 $email->$var = $this->replaceDText($email->$var, in_array($var, $htmlVars) ? $tags : $textreplace);
399 }
400 }
401
402 public function replaceDText($text, $replacement)
403 {
404 if (is_array($text)) {
405 foreach ($text as &$oneCell) {
406 if (empty($oneCell)) continue;
407 $oneCell = $this->replaceDText($oneCell, $replacement);
408 }
409 } elseif (is_string($text) && !empty($text)) {
410 foreach ($replacement as $code => $value) {
411 $codes = [$code, urlencode($code)];
412 if (is_null($value)) {
413 $value = '';
414 }
415 $safePregValue = str_replace('$', '\$', $value);
416
417 foreach ($codes as $oneCode) {
418 $text = preg_replace(
419 '#<span[^>]+'.preg_quote($oneCode, '#').'.+</em>[^<]*</span>#Uis',
420 $safePregValue,
421 $text
422 );
423
424 $text = preg_replace(
425 '#(<tr[^>]+)data-dynamic="'.preg_quote($oneCode, '#').'"([^>]+>[^<]*<td[^>]*>).+</i>[^<]*</td>[^<]*</tr>#Uis',
426 '${1}${2}'.$safePregValue.'</td></tr>',
427 $text
428 );
429
430 $text = str_replace($oneCode, $value, $text);
431 }
432 }
433 }
434
435 return $text;
436 }
437
438 public function extractTags(object $email, string $tagfamily): array
439 {
440 $results = [];
441
442 $match = '#(?:{|%7B)'.$tagfamily.'(?:%3A|\\:)(.*)(?:}|%7D)#Ui';
443 $variables = [
444 'subject',
445 'AltBody',
446 'body',
447 'From',
448 'FromName',
449 'ReplyTo',
450 'ReplyName',
451 'bcc',
452 'cc',
453 'fromname',
454 'fromemail',
455 'replyname',
456 'replyemail',
457 'params',
458 'preheader',
459 ];
460 $found = false;
461 foreach ($variables as $var) {
462 if (empty($email->$var)) continue;
463
464 if (is_array($email->$var)) {
465 foreach ($email->$var as $i => $arrayField) {
466 if (empty($arrayField)) continue;
467
468 if (is_array($arrayField)) {
469 foreach ($arrayField as $a => $oneval) {
470 $found = preg_match_all($match, $oneval, $results[$var.$i.'-'.$a]) || $found;
471 if (empty($results[$var.$i.'-'.$a][0])) unset($results[$var.$i.'-'.$a]);
472 }
473 } else {
474 $found = preg_match_all($match, $arrayField, $results[$var.$i]) || $found;
475 if (empty($results[$var.$i][0])) unset($results[$var.$i]);
476 }
477 }
478 } else {
479 $found = preg_match_all($match, $email->$var, $results[$var]) || $found;
480 if (empty($results[$var][0])) unset($results[$var]);
481 }
482 }
483
484 if (!$found) {
485 return [];
486 }
487
488 $tags = [];
489 foreach ($results as $var => $allresults) {
490 foreach ($allresults[0] as $i => $oneTag) {
491 if (isset($tags[$oneTag])) {
492 continue;
493 }
494 $tags[$oneTag] = $this->extractTag($allresults[1][$i]);
495 }
496 }
497
498 return $tags;
499 }
500
501 public function extractTag(string $oneTag): \stdClass
502 {
503 $oneTag = str_replace(['[time]+', '[time]-'], [urlencode('[time]+'), urlencode('[time]-')], $oneTag);
504 $arguments = explode('|', strip_tags(urldecode($oneTag)));
505 $tag = new \stdClass();
506 $tag->id = $arguments[0];
507 $tag->default = '';
508 for ($i = 1, $a = count($arguments); $i < $a; $i++) {
509 $args = explode(':', $arguments[$i], 2);
510 $arg0 = trim($args[0]);
511 if (empty($arg0)) continue;
512
513 if (isset($args[1])) {
514 $tag->$arg0 = $args[1];
515 if (isset($args[2])) {
516 $tag->{$args[0]} .= ':'.$args[2];
517 }
518 } else {
519 $tag->$arg0 = true;
520 }
521 }
522
523 return $tag;
524 }
525
526 public function wrapText(string $text, object $tag): string
527 {
528 if (empty($tag->wrap)) {
529 return $text;
530 }
531
532 $tag->wrap = intval($tag->wrap);
533
534 $newText = str_replace(['&lt', '&gt'], ['<', '>'], $text);
535
536 if (mb_strlen(strip_tags($newText)) <= $tag->wrap) {
537 return $newText;
538 }
539
540 if (!class_exists('DOMDocument', false)) {
541 return mb_substr(strip_tags($newText), 0, $tag->wrap).'…';
542 }
543
544 if (function_exists('libxml_use_internal_errors')) {
545 libxml_use_internal_errors(true);
546 }
547
548 $dom = new \DOMDocument('1.0', 'UTF-8');
549 $dom->loadHTML(
550 '<?xml encoding="UTF-8">'.$newText,
551 LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD
552 );
553
554 $count = 0;
555 $this->truncateNode($dom, $dom, $tag->wrap, $count);
556
557 return $dom->saveHTML();
558 }
559
560 private function truncateNode(\DOMDocument $dom, \DOMNode $node, int $limit, int &$count): bool
561 {
562 for ($i = 0; $i < $node->childNodes->length; $i++) {
563 $child = $node->childNodes->item($i);
564
565 if ($child->nodeType === XML_TEXT_NODE) {
566 $text = $child->nodeValue;
567 $len = mb_strlen($text);
568
569 if ($count + $len > $limit) {
570 $remaining = $limit - $count;
571
572 $slice = mb_substr($text, 0, $remaining);
573
574 if (preg_match('/^(.+?)([\s\p{P}]+)[^\s\p{P}]*$/u', $slice, $m)) {
575 $slice = rtrim($m[1]);
576 }
577
578 $child->nodeValue = $slice.'…';
579
580 while ($child->nextSibling) {
581 $node->removeChild($child->nextSibling);
582 }
583
584 return true;
585 }
586
587 $count += $len;
588 }
589
590 if ($child->hasChildNodes() && $this->truncateNode($dom, $child, $limit, $count)) {
591 while ($child->nextSibling) {
592 $node->removeChild($child->nextSibling);
593 }
594
595 return true;
596 }
597 }
598
599 return false;
600 }
601
602 public function getStandardDisplay(object $format): string
603 {
604 if (empty($format->tag->format)) {
605 $format->tag->format = 'TOP_LEFT';
606 }
607 if (!in_array($format->tag->format, ['TOP_LEFT', 'TOP_RIGHT', 'TITLE_IMG', 'TITLE_IMG_RIGHT', 'CENTER_IMG', 'TOP_IMG', 'COL_LEFT', 'COL_RIGHT'])) {
608 $format->tag->format = 'TOP_LEFT';
609 }
610
611 $invertValues = [
612 'TOP_LEFT' => 'TOP_RIGHT',
613 'TITLE_IMG' => 'TITLE_IMG_RIGHT',
614 'COL_LEFT' => 'COL_RIGHT',
615 'TOP_RIGHT' => 'TOP_LEFT',
616 'TITLE_IMG_RIGHT' => 'TITLE_IMG',
617 'COL_RIGHT' => 'COL_LEFT',
618 ];
619 if (!empty($format->tag->invert) && !empty($invertValues[$format->tag->format])) {
620 $format->tag->format = $invertValues[$format->tag->format];
621 }
622
623 $image = '';
624 if (!empty($format->imagePath)) {
625 $style = '';
626 $linkStyle = '';
627
628 if (in_array($format->tag->format, ['TOP_LEFT', 'TITLE_IMG'])) {
629 $style = 'left';
630 } elseif (in_array($format->tag->format, ['TOP_RIGHT', 'TITLE_IMG_RIGHT'])) {
631 $style = 'right';
632 }
633
634 if (!empty($style)) {
635 $linkStyle = 'style="float:'.$style.';"';
636
637 if ($style === 'left') {
638 $style = 'style="float:left; margin-right: 7px; margin-bottom: 7px;"';
639 } else {
640 $style = 'style="float:right; margin-left: 7px; margin-bottom: 7px;"';
641 }
642 }
643
644 preg_match('#src="([^"]+)"#Uis', $format->imagePath, $matches);
645 if (!empty($matches[1])) $format->imagePath = $matches[1];
646 $altImage = !empty($format->altImage) ? $format->altImage : '';
647 $image = '<img class="content_main_image" alt="'.acym_escape($altImage).'" src="'.$format->imagePath.'" '.$style.' />';
648
649 if (!empty($format->imageCaption) && !in_array($format->tag->format, ['TITLE_IMG', 'TITLE_IMG_RIGHT'])) {
650 $image .= '<p class="content_main_image_caption">'.acym_escape($format->imageCaption).'</p>';
651 }
652 }
653
654 $result = '';
655 if (in_array($format->tag->format, ['TITLE_IMG', 'TITLE_IMG_RIGHT'])) {
656 $format->title = $image.$format->title;
657 $image = '';
658 }
659
660 if (!empty($format->link) && !empty($image) && !empty($format->tag->clickableimg)) {
661 $image = '<a target="_blank" href="'.$format->link.'" '.$linkStyle.'>'.$image.'</a>';
662 }
663
664 if ($format->tag->format === 'TOP_IMG' && !empty($image)) {
665 $result = $image;
666 $image = '';
667 }
668
669 if (in_array($format->tag->format, ['COL_LEFT', 'COL_RIGHT'])) {
670 $maxWidth = empty($format->tag->maxwidth) ? '' : ' width: '.$format->tag->maxwidth.'px;';
671 if (empty($image)) {
672 $format->tag->format = 'TOP_LEFT';
673 } else {
674 $result = '<table><tr><td valign="middle" style="vertical-align: middle; padding-right: 7px;" class="acyleftcol">';
675 if ($format->tag->format === 'COL_LEFT') {
676 $result = '<table><tr><td valign="middle" style="vertical-align: middle; padding-right: 7px; '.$maxWidth.'" class="acyleftcol">';
677 $result .= $image.'</td><td valign="top" class="acyrightcol">';
678 }
679 }
680 }
681
682 if (!empty($format->title)) {
683 if (!empty($format->link) && !empty($format->tag->clickable)) {
684 if (empty($format->tag->type) || $format->tag->type !== 'title') {
685 $format->title = '<h2 class="acym_title">'.$format->title.'</h2>';
686 }
687
688 $title = '<a';
689 if (!empty($format->tag->type) && $format->tag->type === 'title') $title .= ' class="acym_title"';
690 $title .= ' href="'.$format->link.'" target="_blank" name="'.$this->name.'-'.$format->tag->id.'">';
691 $title .= $format->title;
692 $title .= '</a>';
693 $format->title = $title;
694 } else {
695 if (empty($format->tag->type) || $format->tag->type != 'title') {
696 $format->title = '<h2 class="acym_title">'.$format->title.'</h2>';
697 }
698 }
699
700 $result .= $format->title;
701 }
702
703 if (!empty($format->afterTitle)) {
704 $result .= $format->afterTitle;
705 }
706
707 if (!empty($format->description)) {
708 $format->description = $this->wrapText($format->description, $format->tag);
709 }
710 $this->wrappedText = $format->description;
711
712
713 $rowText = '<div class="acydescription">';
714 $endRow = '</div><br />';
715 if (in_array($format->tag->format, ['TOP_LEFT', 'TOP_RIGHT', 'TITLE_IMG', 'TITLE_IMG_RIGHT', 'TOP_IMG'])) {
716 if (!empty($image) || !empty($format->description)) {
717 $result .= $rowText.$image.$format->description.$endRow;
718 }
719 } elseif ($format->tag->format == 'CENTER_IMG') {
720 if (!empty($image)) {
721 $result .= '<div class="acymainimage">'.$image.$endRow;
722 }
723
724 if (!empty($format->description)) {
725 $result .= $rowText.$format->description.$endRow;
726 }
727 } elseif (in_array($format->tag->format, ['COL_LEFT', 'COL_RIGHT'])) {
728 if (!empty($format->description)) {
729 $result .= $rowText.$format->description.$endRow;
730 }
731
732 if ($format->tag->format === 'COL_RIGHT') {
733 $result .= '</td><td valign="middle" style="vertical-align: middle; padding-left: 7px; '.$maxWidth.'" class="acyrightcol">'.$image;
734 }
735 $result .= '</td></tr></table>';
736 }
737
738 if (!empty($format->customFields)) {
739 $result .= '<table style="width:100%;" class="customfieldsarea"><tr>';
740
741 $format->cols = empty($format->tag->nbcols) ? 1 : intval($format->tag->nbcols);
742 if (empty($format->cols)) $format->cols = 1;
743
744 $i = 0;
745 foreach ($format->customFields as $oneField) {
746 if ($i != 0 && $i % $format->cols == 0) $result .= '</tr><tr>';
747
748 if (empty($oneField[1])) {
749 $result .= '<td class="cfvalue" colspan="2">';
750 } else {
751 $result .= '<td nowrap="nowrap" class="cflabel">'.$oneField[1].'</td><td class="cfvalue">';
752 }
753
754 $result .= $oneField[0].'</td>';
755 $i++;
756 }
757
758 while ($i % $format->cols != 0) {
759 $result .= '<td colspan="2"></td>';
760 $i++;
761 }
762
763 $result .= '</tr></table>';
764 }
765
766 if (!empty($format->afterArticle)) {
767 $result .= $format->afterArticle;
768 }
769
770 return $result;
771 }
772
773 public function managePicts(object $tag, string $result): string
774 {
775 if (!isset($tag->pict)) {
776 return $result;
777 }
778
779 $imageHelper = new ImageHelper();
780 if ($tag->pict === 'resized') {
781 $imageHelper->maxHeight = empty($tag->maxheight) ? 150 : $tag->maxheight;
782 $imageHelper->maxWidth = empty($tag->maxwidth) ? 150 : $tag->maxwidth;
783 if ($imageHelper->available()) {
784 $result = $imageHelper->resizePictures($result);
785 } elseif (acym_isAdmin()) {
786 acym_enqueueMessage($imageHelper->error, 'notice');
787 }
788 } elseif ($tag->pict == '0') {
789 $result = $imageHelper->removePictures($result);
790 }
791
792 return acym_absoluteURL($result);
793 }
794
795 public function displayOptions(array $options, string $dynamicIdentifier, string $type = 'individual', $defaultValues = null): void
796 {
797 $suffix = preg_replace('[^a-zA-Z0-9]', '_', $dynamicIdentifier);
798 $updateFunction = 'updateDynamic'.$suffix;
799
800 $outputStructure = [
801 'topOptions' => [],
802 'options' => [],
803 ];
804 $jsOptionsMerge = [];
805
806 foreach ($options as $option) {
807 $currentLabel = $option['title'];
808 $currentOption = '';
809
810 if (isset($defaultValues->{$option['name']})) {
811 $option['default'] = $defaultValues->{$option['name']};
812 }
813
814 if ($option['type'] === 'pictures') {
815 $displayedPictures = $option['default'] ?? 'resized';
816 if (isset($defaultValues->pict)) $displayedPictures = $defaultValues->pict;
817 $resizeDisplay = 'resized' === $displayedPictures ? '' : 'style="display: none;"';
818 $maxWidth = $defaultValues->maxwidth ?? 150;
819 $maxHeight = $defaultValues->maxheight ?? 150;
820
821 $valImages = [];
822 $valImages[] = acym_selectOption('1', 'ACYM_YES');
823 $valImages[] = acym_selectOption('resized', 'ACYM_RESIZED');
824 $valImages[] = acym_selectOption('0', 'ACYM_NO');
825 $currentOption .= '<div class="cell large-5 acym_plugin_field">'.acym_translation('ACYM_DISPLAY').'</div>';
826 $currentOption .= '<div class="cell large-7">'.acym_radio(
827 $valImages,
828 'pict'.$suffix,
829 $displayedPictures,
830 ['onclick' => $updateFunction.'();'],
831 ['containerClass' => 'dcontent_pictures'],
832 !acym_isAdmin()
833 ).'</div>';
834 $currentOption .= '<div id="pictsize'.$suffix.'" class="cell grid-x margin-y margin-top-1" '.$resizeDisplay.'>
835 <div class="cell large-5 acym_plugin_field">'.acym_translation('ACYM_MAX_WIDTH').'</div>
836 <div class="cell large-7">
837 <input class="intext_input" name="pictwidth'.$suffix.'" type="number" onchange="'.$updateFunction.'();" value="'.intval($maxWidth).'"/>
838 </div>
839 <div class="cell large-5 acym_plugin_field">'.acym_translation('ACYM_MAX_HEIGHT').'</div>
840 <div class="cell large-7">
841 <input class="intext_input" name="pictheight'.$suffix.'" type="number" onchange="'.$updateFunction.'();" value="'.intval($maxHeight).'"/>
842 </div>
843 </div>';
844 if (!empty($option['caption'])) {
845 $currentOption .= '<div class="cell grid-x margin-top-1">';
846 $currentOption .= '<label class="cell large-5 acym_plugin_field">'.acym_translation('ACYM_CAPTION').'</label>';
847 $currentOption .= acym_radio(
848 [
849 acym_selectOption('1', 'ACYM_YES'),
850 acym_selectOption('0', 'ACYM_NO'),
851 ],
852 'caption'.$suffix,
853 $defaultValues->caption ?? '0',
854 ['onclick' => $updateFunction.'();'],
855 ['containerClass' => 'cell large-7']
856 );
857 $currentOption .= '</div>';
858
859 $jsOptionsMerge[] = 'otherinfo += "| caption:" + jQuery(\'input[name="caption'.$suffix.'"]:checked\').val();';
860 }
861
862 $jsOptionsMerge[] = '
863 var _pictVal'.$suffix.' = jQuery(\'input[name="pict'.$suffix.'"]:checked\').val();
864 otherinfo += "| pict:" + _pictVal'.$suffix.';
865
866 if(_pictVal'.$suffix.' == "resized"){
867 jQuery("#pictsize'.$suffix.'").show();
868 otherinfo += "| maxwidth:" + jQuery(\'input[name="pictwidth'.$suffix.'"]\').val();
869 otherinfo += "| maxheight:" + jQuery(\'input[name="pictheight'.$suffix.'"]\').val();
870 }else{
871 jQuery("#pictsize'.$suffix.'").hide();
872 }';
873 } elseif ($option['type'] === 'checkbox') {
874 if (!empty($option['default'])) {
875 $checkedValues = explode(',', $option['default']);
876 foreach ($option['options'] as $key => $oneOption) {
877 $oneOption[1] = in_array($key, $checkedValues);
878 $option['options'][$key] = $oneOption;
879 }
880 }
881
882 $currentOption .= '<div class="cell grid-x">';
883 foreach ($option['options'] as $value => $title) {
884 $currentOption .= '<div class="cell medium-6" '.(empty($title[2]) ? '' : $title[2]).'>
885 <input type="checkbox" name="'.acym_escape($option['name'].$suffix).'" value="'.acym_escape($value).'" id="'.acym_escape(
886 $value.$suffix
887 ).'" onclick="'.$updateFunction.'();" '.($title[1] ? 'checked="checked"' : '').'/>
888 <label style="margin-left:5px" for="'.acym_escape($value.$suffix).'">'.acym_translation($title[0]).'</label>
889 </div>';
890 }
891 $currentOption .= '</div>';
892
893 if (empty($option['separator'])) $option['separator'] = ',';
894
895 $jsOptionsMerge[] = 'var _checked'.$option['name'].$suffix.' = [];
896 jQuery("input:checkbox[name='.$option['name'].$suffix.']:checked").each(function(){
897 _checked'.$option['name'].$suffix.'.push(jQuery(this).val());
898 });
899 if(_checked'.$option['name'].$suffix.'.length) otherinfo += "| '.$option['name'].':" + _checked'.$option['name'].$suffix.'.join("'.$option['separator'].'");';
900 } elseif ($option['type'] === 'boolean') {
901 if ($option['name'] === 'autologin' && $this->config->get('autologin_urls', 0) != 1) {
902 continue;
903 }
904
905 $currentOption .= acym_boolean(
906 $option['name'].$suffix,
907 $option['default'],
908 $option['name'].$suffix,
909 ['onclick' => $updateFunction.'();']
910 );
911
912 $jsOptionsMerge[] = 'otherinfo += "| '.$option['name'].':" + jQuery(\'input[name="'.$option['name'].$suffix.'"]:checked\').val();';
913 } elseif ($option['type'] === 'radio') {
914 $radioOptions = [];
915 foreach ($option['options'] as $value => $title) {
916 $radioOptions[] = acym_selectOption($value, $title);
917 }
918
919 $currentOption .= acym_radio(
920 $radioOptions,
921 $option['name'].$suffix,
922 $option['default'],
923 ['onclick' => $updateFunction.'();'],
924 ['pluginMode' => true],
925 !acym_isAdmin()
926 );
927 $jsOptionsMerge[] = 'otherinfo += "| '.$option['name'].':" + jQuery(\'input[name="'.$option['name'].$suffix.'"]:checked\').val();';
928 } elseif ($option['type'] === 'select') {
929 $selectOptions = [];
930 foreach ($option['options'] as $value => $title) {
931 if (is_object($title)) {
932 $selectOptions[] = acym_selectOption($title->value, $title->text);
933 } else {
934 $selectOptions[] = acym_selectOption($value, $title);
935 }
936 }
937
938 $default = empty($option['default']) ? null : $option['default'];
939 if (!empty($default) && strpos($default, ',')) [$default, $defaultOrder] = explode(',', $default);
940
941 $attributes = [
942 'onchange' => $updateFunction.'();',
943 'id' => $option['name'].$suffix,
944 ];
945 if ($option['name'] === 'order') {
946 $attributes['class'] = 'acym__dynamics__ordering__select';
947 }
948 $currentOption .= acym_select(
949 $selectOptions,
950 $option['name'].$suffix,
951 $default,
952 $attributes
953 );
954
955 if ($option['name'] === 'order') {
956 $dirs = [
957 'desc' => acym_translation('ACYM_DESC'),
958 'asc' => acym_translation('ACYM_ASC'),
959 ];
960 if (empty($defaultOrder)) $defaultOrder = empty($option['defaultdir']) ? null : $option['defaultdir'];
961 $currentOption .= ' '.acym_select(
962 $dirs,
963 'orderdir'.$suffix,
964 $defaultOrder,
965 [
966 'onchange' => $updateFunction.'();',
967 'style' => 'width: 115px;',
968 'class' => 'acym__dynamics__ordering__select',
969 ]
970 );
971
972 $jsOptionsMerge[] = 'otherinfo += "| '.$option['name'].':" + jQuery(\'[name="'.$option['name'].$suffix.'"]\').val() + "," + jQuery(\'[name="orderdir'.$suffix.'"]\').val();';
973 } else {
974 $jsOptionsMerge[] = 'otherinfo += "| '.$option['name'].':" + jQuery(\'[name="'.$option['name'].$suffix.'"]\').val();';
975 }
976 } elseif ($option['type'] === 'multiselect') {
977 $selectOptions = [];
978 foreach ($option['options'] as $value => $title) {
979 $selectOptions[] = acym_selectOption($value, $title);
980 }
981
982
983 if (!isset($option['default'])) $option['default'] = [];
984 if (!is_array($option['default'])) $option['default'] = explode(',', $option['default']);
985
986 $currentOption .= acym_selectMultiple(
987 $selectOptions,
988 $option['name'].$suffix,
989 $option['default'],
990 ['onchange' => $updateFunction.'();', 'id' => $option['name'].$suffix]
991 );
992
993 $jsOptionsMerge[] = '
994 var theMultiSelect = document.querySelector(\'[name="'.$option['name'].$suffix.'[]"]\');
995 var selectedOptions = [];
996 for(var i = 0 ; i < theMultiSelect.length ; i++){
997 if(theMultiSelect[i].selected){
998 selectedOptions.push(theMultiSelect[i].value);
999 }
1000 }
1001 otherinfo += "| '.$option['name'].':" + selectedOptions.join(",");';
1002 } elseif ($option['type'] === 'text') {
1003 if (!isset($option['default'])) $option['default'] = '';
1004 $class = empty($option['class']) ? 'acym_plugin_text_field' : $option['class'];
1005 $placeholder = empty($option['placeholder']) ? '' : ' placeholder="'.acym_escape($option['placeholder']).'"';
1006 $currentOption .= '<input
1007 type="text"
1008 name="'.$option['name'].$suffix.'"
1009 id="'.$option['name'].$suffix.'"
1010 onchange="'.$updateFunction.'();"
1011 value="'.acym_escape($option['default']).'"
1012 class="'.acym_escape($class).'" '.$placeholder.'/>';
1013 $jsOptionsMerge[] = 'otherinfo += "| '.$option['name'].':" + jQuery(\'input[name="'.$option['name'].$suffix.'"]\').val();';
1014 } elseif ($option['type'] === 'number') {
1015 $min = empty($option['min']) ? ' min="0"' : ' min="'.$option['min'].'"';
1016 $max = empty($option['max']) ? '' : ' max="'.$option['max'].'"';
1017 $class = empty($option['class']) ? 'acym_plugin_text_field' : $option['class'];
1018 $currentOption .= '<input type="number"'.$min.$max.' name="'.$option['name'].$suffix.'" id="'.$option['name'].$suffix.'" onchange="'.$updateFunction.'();" value="'.intval(
1019 $option['default']
1020 ).'" class="'.acym_escape($class).'" />';
1021 $jsOptionsMerge[] = 'otherinfo += "| '.$option['name'].':" + jQuery(\'input[name="'.$option['name'].$suffix.'"]\').val();';
1022 } elseif ($option['type'] === 'intextfield') {
1023 $inputType = 'text';
1024 if (!empty($option['isNumber']) && $option['isNumber'] === 1) $inputType = 'number';
1025 $currentOption .= acym_translationSprintf(
1026 $option['text'],
1027 '<input type="'.$inputType.'" name="'.$option['name'].$suffix.'" id="'.$option['name'].$suffix.'" class="intext_input" value="'.acym_escape(
1028 $option['default']
1029 ).'" onchange="'.$updateFunction.'();"/>'
1030 );
1031 $jsOptionsMerge[] = 'otherinfo += "| '.$option['name'].':" + jQuery(\'input[name="'.$option['name'].$suffix.'"]\').val();';
1032 } elseif ($option['type'] === 'date') {
1033 $relativeTime = '-';
1034 if (!empty($option['relativeDate'])) $relativeTime = $option['relativeDate'];
1035 if (!empty($option['default']) && !is_numeric($option['default']) && false === strpos($option['default'], '[time]')) {
1036 $option['default'] = strtotime($option['default']);
1037 }
1038 $currentOption .= acym_dateField($option['name'].$suffix, $option['default'], '', ' onchange="'.$updateFunction.'();"', $relativeTime);
1039 $jsOptionsMerge[] = 'otherinfo += "| '.$option['name'].':" + jQuery(\'input[name="'.$option['name'].$suffix.'"]\').val();';
1040 } elseif ($option['type'] === 'language') {
1041 $languageOptions = [];
1042 $languageOptions['any'] = acym_translation('ACYM_ANY');
1043
1044 $languages = acym_getLanguages(true);
1045 foreach ($languages as $language) {
1046 $languageOptions[$language->language] = $language->name;
1047 }
1048
1049 if (empty($option['default'])) {
1050 $option['default'] = acym_getVar('string', 'language');
1051 if (acym_isMultilingual() && (empty($option['default']) || $option['default'] === 'main')) {
1052 $option['default'] = $this->config->get('multilingual_default');
1053 }
1054 }
1055
1056 $currentOption .= acym_select(
1057 $languageOptions,
1058 $option['name'].$suffix,
1059 empty($option['default']) ? null : $option['default'],
1060 [
1061 'onchange' => $updateFunction.'();',
1062 'id' => $option['name'].$suffix,
1063 ]
1064 );
1065
1066 $jsOptionsMerge[] = 'otherinfo += "| '.$option['name'].':" + jQuery(\'[name="'.$option['name'].$suffix.'"]\').val();';
1067 } elseif ($option['type'] == 'custom') {
1068 $currentOption .= $option['output'];
1069 $jsOptionsMerge[] = $option['js'];
1070 }
1071
1072 if (!empty($option['main']) || in_array($option['type'], ['pictures', 'checkbox'])) {
1073 $outputStructure['topOptions'][$currentLabel] = $currentOption;
1074
1075 if ($option['type'] === 'checkbox' && $currentLabel === 'ACYM_DISPLAY' && (!isset($option['format']) || $option['format'])) {
1076 $formatOption = '<div class="grid-x">';
1077 $formatOption .= '<div class="cell large-3">'.acym_translation('ACYM_FORMAT').'</div>';
1078 $formatOption .= '<div class="cell large-9 dcontentFormatContainer">';
1079
1080 $default = empty($defaultValues->format) ? 'TOP_LEFT' : $defaultValues->format;
1081 $formats = ['TOP_LEFT', 'TOP_RIGHT', 'TITLE_IMG', 'TITLE_IMG_RIGHT', 'CENTER_IMG', 'TOP_IMG', 'COL_LEFT', 'COL_RIGHT'];
1082 foreach ($formats as $oneFormat) {
1083 $class = 'button-radio';
1084 if ($default === $oneFormat) $class .= ' button-radio-selected';
1085
1086 $formatOption .= '<button
1087 class="'.$class.'"
1088 acym-button-radio-group="dcontentFormat'.$suffix.'"
1089 acym-data-type="'.$oneFormat.'"
1090 acym-callback="'.$updateFunction.'">
1091 <img alt="'.$oneFormat.'" src="'.ACYM_IMAGES.'editor/dcontent_formats/'.strtolower($oneFormat).'.png"/>
1092 </button>';
1093 }
1094 $formatOption .= '</div>';
1095
1096 if ($type === 'grouped') {
1097 $formatOption .= '<div class="cell large-3">'.acym_translation('ACYM_ALTERNATE').acym_info(['textShownInTooltip' => 'ACYM_ALTERNATE_DESC']).'</div>';
1098 $formatOption .= '<div class="cell large-9">';
1099 $formatOption .= acym_boolean(
1100 'alternate'.$suffix,
1101 !empty($defaultValues->alternate),
1102 'alternate'.$suffix,
1103 ['onclick' => $updateFunction.'();']
1104 );
1105 $formatOption .= '</div>';
1106
1107 $jsOptionsMerge[] = 'var alternate = jQuery(\'input[name="alternate'.$suffix.'"]:checked\').val();';
1108 $jsOptionsMerge[] = 'if (!acym_helper.empty(alternate)) otherinfo += "| alternate";';
1109 }
1110
1111 $formatOption .= '</div>';
1112
1113 $jsOptionsMerge[] = 'var selectedFormatOption = jQuery(\'.button-radio-selected[acym-button-radio-group="dcontentFormat'.$suffix.'"]\')';
1114 $jsOptionsMerge[] = 'if (!acym_helper.empty(selectedFormatOption)) otherinfo += "| format:" + selectedFormatOption.attr("acym-data-type");';
1115
1116 $outputStructure['topOptions']['ACYM_FORMAT'] = $formatOption;
1117 }
1118 continue;
1119 }
1120
1121 if (empty($option['section'])) {
1122 $option['section'] = 'ACYM_OTHER_OPTIONS';
1123 }
1124
1125 $currentLabel = acym_translation($currentLabel);
1126 if (!empty($option['tooltip'])) {
1127 $currentLabel .= '&nbsp;'.acym_info(['textShownInTooltip' => $option['tooltip'], 'classIcon' => 'acym_plugin_field_'.$option['name']]);
1128 }
1129 $currentLabel = '<label class="cell large-5 acym_plugin_field acym_plugin_field_'.$option['type'].'" for="'.acym_escape(
1130 $option['name'].$suffix
1131 ).'">'.$currentLabel.'</label>';
1132
1133 $outputStructure['options'][$option['section']][$currentLabel] = $currentOption;
1134 }
1135
1136 if (!empty($outputStructure['options'])) {
1137 if (isset($outputStructure['options']['ACYM_OTHER_OPTIONS'])) {
1138 $otherOptions = $outputStructure['options']['ACYM_OTHER_OPTIONS'];
1139 unset($outputStructure['options']['ACYM_OTHER_OPTIONS']);
1140 $outputStructure['options']['ACYM_OTHER_OPTIONS'] = $otherOptions;
1141 }
1142
1143 foreach ($outputStructure['options'] as $section => $options) {
1144 $formattedOptions = '';
1145 foreach ($options as $label => $option) {
1146 $formattedOptions .= '<div class="cell grid-x margin-bottom-1">'.$label;
1147 $formattedOptions .= '<div class="cell large-7">'.$option.'</div>';
1148 $formattedOptions .= '</div>';
1149 }
1150 $outputStructure['topOptions'][$section] = $formattedOptions;
1151 }
1152 }
1153
1154 $output = '';
1155 if (!empty($outputStructure['topOptions'])) {
1156 foreach ($outputStructure['topOptions'] as $label => $oneOption) {
1157 $output .= '<p class="acym__wysid__right__toolbar__p acym__wysid__right__toolbar__p__open acym__title">';
1158 $output .= acym_translation($label).'<i class="acymicon-keyboard-arrow-up"></i>';
1159 $output .= '</p>';
1160 $output .= '<div class="acym__wysid__right__toolbar__design--show acym__wysid__right__toolbar__design acym__wysid__context__modal__container grid-x">';
1161 $output .= $oneOption;
1162 $output .= '</div>';
1163 }
1164 }
1165
1166 $storageVar = 'window._additionalInfo'.$suffix;
1167 $output .= '
1168 <script type="text/javascript">
1169 var _selectedRows'.$suffix.' = [];
1170 var _selectedRows = [];
1171 '.$storageVar.' = '.$storageVar.' || {};
1172 ';
1173 if (!empty($defaultValues->id) && (empty($defaultValues->defaultPluginTab) || $dynamicIdentifier === $defaultValues->defaultPluginTab)) {
1174 $delimiter = strpos($defaultValues->id, '-') ? '-' : ',';
1175 $selected = explode($delimiter, $defaultValues->id);
1176
1177 foreach ($selected as $value) {
1178 if (empty($value)) continue;
1179 $output .= '_selectedRows'.$suffix.'['.intval($value).'] = true;
1180 ';
1181 }
1182 }
1183
1184 $output .= '
1185 function applyContent'.$suffix.'(contentid, row){
1186 if(_selectedRows'.$suffix.'[contentid]){
1187 jQuery(row).removeClass("selected_row");
1188 delete _selectedRows'.$suffix.'[contentid];
1189 }else{
1190 ';
1191
1192 if ('individual' === $type) {
1193 $output .= '
1194 for(let elementKey in _selectedRows'.$suffix.') {
1195 if(!_selectedRows'.$suffix.'.hasOwnProperty(elementKey)) continue;
1196
1197 jQuery(\'[data-id="\' + elementKey + \'"]\').removeClass("selected_row");
1198 delete _selectedRows'.$suffix.'[elementKey];
1199 }
1200 ';
1201 }
1202
1203 $output .= '
1204 jQuery(row).addClass("selected_row");
1205 _selectedRows'.$suffix.'[contentid] = true;
1206 }
1207 '.$updateFunction.'();
1208
1209 if(typeof _selectedRows !== "undefined"){
1210 _selectedRows = _selectedRows'.$suffix.';
1211 }
1212 }
1213
1214 function '.$updateFunction.'(){
1215 var tag = "";
1216 var otherinfo = "";
1217
1218 '.implode("\r\n\r\n", $jsOptionsMerge).'
1219
1220 for (let [index, info] of Object.entries('.$storageVar.')){
1221 otherinfo += "| "+index+":"+info;
1222 }
1223 ';
1224
1225 if ($type == 'individual') {
1226 $output .= '
1227 for(var i in _selectedRows'.$suffix.'){
1228 if(!_selectedRows'.$suffix.'.hasOwnProperty(i)) continue;
1229
1230 tag = tag + "{'.$dynamicIdentifier.':" + i + otherinfo + "}";
1231 }';
1232 } elseif ($type == 'grouped') {
1233 $output .= '
1234 tag = "{'.$dynamicIdentifier.':";
1235 for(var icat in _selectedRows'.$suffix.'){
1236 if(!_selectedRows'.$suffix.'.hasOwnProperty(icat)) continue;
1237 tag += icat + "-";
1238 }
1239 tag += otherinfo + "}";';
1240 } elseif ($type == 'simple') {
1241 $output .= '
1242 tag = "{'.$dynamicIdentifier.':" + otherinfo + "}";';
1243 }
1244
1245 $output .= '
1246 acym_editorWysidDynamic.insertDContent(tag);
1247 }
1248
1249 function addAdditionalInfo'.$suffix.'(index, value){
1250 '.$storageVar.'[index] = value;
1251 '.$updateFunction.'();
1252 }
1253 </script>';
1254
1255 if ($type === 'individual') {
1256 acym_trigger('displayCustomViewEditor', [&$output], 'plgAcym'.ucfirst($dynamicIdentifier));
1257 $output .= '<input type="hidden" id="acym__dynamic__update__function" value="'.$updateFunction.'">';
1258 }
1259
1260 echo $output;
1261 }
1262
1263 public function translateItem(object &$item, object &$tag, string $referenceTable, int $referenceId = 0): void
1264 {
1265 if (!acym_isExtensionActive('com_falang')) {
1266 return;
1267 }
1268
1269 if (!empty($tag->falang)) {
1270 $langId = $tag->falang;
1271 } elseif (!empty($tag->lang)) {
1272 $langId = intval(substr($tag->lang, strpos($tag->lang, ',') + 1));
1273 } elseif (!empty($this->contextLanguage)) {
1274 $languages = acym_loadObjectList('SELECT `lang_id`, `lang_code`, `sef` FROM #__languages');
1275 foreach ($languages as $language) {
1276 if (in_array($this->contextLanguage, [$language->lang_code, $language->sef])) {
1277 $langId = $language->lang_id;
1278 break;
1279 }
1280 }
1281 }
1282
1283 if (empty($langId)) {
1284 return;
1285 }
1286
1287 if (empty($referenceId)) {
1288 $referenceId = $tag->id;
1289 }
1290
1291 $translations = acym_loadObjectList(
1292 'SELECT `reference_field`, `value`
1293 FROM `#__falang_content`
1294 WHERE `published` = 1
1295 AND `reference_table` = '.acym_escapeDB($referenceTable).'
1296 AND `language_id` = '.intval($langId).'
1297 AND `reference_id` = '.intval($referenceId)
1298 );
1299
1300 if (empty($translations)) {
1301 return;
1302 }
1303
1304 foreach ($translations as $oneTranslation) {
1305 if (empty($oneTranslation->value)) {
1306 continue;
1307 }
1308
1309 $translatedField = $oneTranslation->reference_field;
1310 $item->$translatedField = $oneTranslation->value;
1311 }
1312 }
1313
1314 public function createDummyEmailObject(int $mailId, string $code, string $previewBody): object
1315 {
1316 if (!empty($mailId)) {
1317 $mailClass = new MailClass();
1318 $email = $mailClass->getOneById($mailId);
1319 }
1320
1321 if (empty($email)) {
1322 $email = new \stdClass();
1323 $email->id = 0;
1324 $email->name = '';
1325 $email->subject = '';
1326 $email->from_name = '';
1327 $email->from_email = '';
1328 $email->reply_to_name = '';
1329 $email->reply_to_email = '';
1330 $email->bcc = '';
1331 $email->links_language = '';
1332 }
1333
1334 $language = acym_getVar('string', 'language', 'main');
1335 if (!empty($language)) {
1336 if ($language === 'main') {
1337 $language = $this->config->get('multilingual_default', ACYM_DEFAULT_LANGUAGE);
1338 }
1339 $email->links_language = $language;
1340 }
1341
1342 $email->creation_date = acym_date('now', 'Y-m-d H:i:s', false);
1343 $email->creator_id = acym_currentUserId();
1344 $email->thumbnail = '';
1345 $email->drag_editor = '1';
1346 $email->type = MailClass::TYPE_STANDARD;
1347 $email->settings = '';
1348 $email->stylesheet = '';
1349 $email->attachments = '';
1350
1351 $email->body = $code;
1352 $email->previewBody = $previewBody;
1353
1354 return $email;
1355 }
1356 }
1357