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

1,373 lines 56.3 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
292 if (in_array($extension, ['gif', 'png'])) {
293 imagealphablending($img, false);
294 imagesavealpha($img, false);
295 }
296
297 ob_start();
298 switch ($extension) {
299 case 'gif':
300 $status = imagegif($img);
301 break;
302 case 'jpg':
303 case 'jpeg':
304 $status = imagejpeg($img, null, 100);
305 break;
306 case 'png':
307 $status = imagepng($img, null, 1);
308 break;
309 }
310 $imageContent = ob_get_clean();
311 $status = $status && acym_writeFile($pictPath, $imageContent);
312
313 if (!$status) {
314 continue;
315 }
316 $html = str_replace($pictCode, $picturl, $html);
317 }
318 }
319
320 public function cleanHtml(string &$html): void
321 {
322 $this->convertbase64pictures($html);
323
324 $pregreplace = [];
325 $pregreplace['#<tr([^>"]*>([^<]*<td[^>]*>[ \n\s]*<img[^>]*>[ \n\s]*</ *td[^>]*>[ \n\s]*)*</ *tr)#Uis'] = '<tr style="line-height: 0px;" $1';
326 $pregreplace['#<td(((?!style|>).)*>[ \n\s]*(<a[^>]*>)?[ \n\s]*<img[^>]*>[ \n\s]*(</a[^>]*>)?[ \n\s]*</ *td)#Uis'] = '<td style="line-height: 0px;" $1';
327
328 $pregreplace['#{tab[ =][^}]*}#is'] = '';
329 $pregreplace['#{/tabs}#is'] = '';
330 $pregreplace['#{jcomments\s+(on|off|lock)}#is'] = '';
331
332 $pregreplace["#(onmouseout|onmouseover|onclick|onfocus|onload|onblur) *= *\"(?:(?!\").)*\"#Ui"] = '';
333 $pregreplace["#< *script(?:(?!< */ *script *>).)*< */ *script *>#Uis"] = '';
334 $pregreplace["#< *iframe(?:(?!< */ *iframe *>).)*< */ *iframe *>#Uis"] = '';
335
336 $pregreplace['#(<p style=")([^>]*>\s*<img *[^>]*margin-left: auto; margin-right: auto;[^>]*>\s*</p>)#Uis'] = '$1text-align: center;$2';
337 $pregreplace['#(<img [^>]*src="[^"]+\.webp"[^>]*>)#Uis'] = '<!--[if !mso]><!-->$1<!--<![endif]-->';
338
339 $newbody = preg_replace(array_keys($pregreplace), $pregreplace, $html);
340 if (!empty($newbody)) {
341 $html = $newbody;
342 }
343
344 $body = preg_replace_callback('/src="([^"]* [^"]*)"/Ui', [$this, 'convertSpaces'], $html);
345 if (!empty($body)) $html = $body;
346
347 $html = acym_cmsCleanHtml($html);
348 }
349
350 public function convertSpaces(array $matches): string
351 {
352 return "src='".str_replace(' ', '%20', $matches[1])."'";
353 }
354
355 public function replaceTags(object &$email, array $tags, bool $html = false): void
356 {
357 if (empty($tags)) return;
358
359 $htmlVars = ['body'];
360 $textVars = [
361 'subject',
362 'AltBody',
363 'From',
364 'FromName',
365 'ReplyTo',
366 'ReplyName',
367 'bcc',
368 'cc',
369 'fromname',
370 'fromemail',
371 'replyname',
372 'replyemail',
373 'params',
374 'preheader',
375 ];
376
377 $variables = array_merge($htmlVars, $textVars);
378
379 if ($html) {
380 if (empty($this->mailerHelper)) {
381 $this->mailerHelper = new MailerHelper();
382 }
383
384 $textreplace = [];
385 foreach ($tags as $i => $replacement) {
386 if (isset($textreplace[$i])) continue;
387 $textreplace[$i] = $this->mailerHelper->textVersion($replacement);
388 }
389 } else {
390 $textreplace = $tags;
391 }
392
393 foreach ($variables as $var) {
394 if (empty($email->$var)) continue;
395 $email->$var = $this->replaceDText($email->$var, in_array($var, $htmlVars) ? $tags : $textreplace);
396 }
397 }
398
399 public function replaceDText($text, $replacement)
400 {
401 if (is_array($text)) {
402 foreach ($text as &$oneCell) {
403 if (empty($oneCell)) continue;
404 $oneCell = $this->replaceDText($oneCell, $replacement);
405 }
406 } elseif (is_string($text) && !empty($text)) {
407 foreach ($replacement as $code => $value) {
408 $codes = [$code, urlencode($code)];
409 if (is_null($value)) {
410 $value = '';
411 }
412 $safePregValue = str_replace('$', '\$', $value);
413
414 foreach ($codes as $oneCode) {
415 $text = preg_replace(
416 '#<span[^>]+'.preg_quote($oneCode, '#').'.+</em>[^<]*</span>#Uis',
417 $safePregValue,
418 $text
419 );
420
421 $text = preg_replace(
422 '#(<tr[^>]+)data-dynamic="'.preg_quote($oneCode, '#').'"([^>]+>[^<]*<td[^>]*>).+</i>[^<]*</td>[^<]*</tr>#Uis',
423 '${1}${2}'.$safePregValue.'</td></tr>',
424 $text
425 );
426
427 $text = str_replace($oneCode, $value, $text);
428 }
429 }
430 }
431
432 return $text;
433 }
434
435 public function extractTags(object $email, string $tagfamily): array
436 {
437 $results = [];
438
439 $match = '#(?:{|%7B)'.$tagfamily.'(?:%3A|\\:)(.*)(?:}|%7D)#Ui';
440 $variables = [
441 'subject',
442 'AltBody',
443 'body',
444 'From',
445 'FromName',
446 'ReplyTo',
447 'ReplyName',
448 'bcc',
449 'cc',
450 'fromname',
451 'fromemail',
452 'replyname',
453 'replyemail',
454 'params',
455 'preheader',
456 ];
457 $found = false;
458 foreach ($variables as $var) {
459 if (empty($email->$var)) continue;
460
461 if (is_array($email->$var)) {
462 foreach ($email->$var as $i => $arrayField) {
463 if (empty($arrayField)) continue;
464
465 if (is_array($arrayField)) {
466 foreach ($arrayField as $a => $oneval) {
467 $found = preg_match_all($match, $oneval, $results[$var.$i.'-'.$a]) || $found;
468 if (empty($results[$var.$i.'-'.$a][0])) unset($results[$var.$i.'-'.$a]);
469 }
470 } else {
471 $found = preg_match_all($match, $arrayField, $results[$var.$i]) || $found;
472 if (empty($results[$var.$i][0])) unset($results[$var.$i]);
473 }
474 }
475 } else {
476 $found = preg_match_all($match, $email->$var, $results[$var]) || $found;
477 if (empty($results[$var][0])) unset($results[$var]);
478 }
479 }
480
481 if (!$found) {
482 return [];
483 }
484
485 $tags = [];
486 foreach ($results as $var => $allresults) {
487 foreach ($allresults[0] as $i => $oneTag) {
488 if (isset($tags[$oneTag])) {
489 continue;
490 }
491 $tags[$oneTag] = $this->extractTag($allresults[1][$i]);
492 }
493 }
494
495 return $tags;
496 }
497
498 public function extractTag(string $oneTag): \stdClass
499 {
500 $oneTag = str_replace(['[time]+', '[time]-'], [urlencode('[time]+'), urlencode('[time]-')], $oneTag);
501 $arguments = explode('|', strip_tags(urldecode($oneTag)));
502 $tag = new \stdClass();
503 $tag->id = $arguments[0];
504 $tag->default = '';
505 for ($i = 1, $a = count($arguments) ; $i < $a ; $i++) {
506 $args = explode(':', $arguments[$i], 2);
507 $arg0 = trim($args[0]);
508 if (empty($arg0)) continue;
509
510 if (isset($args[1])) {
511 $tag->$arg0 = $args[1];
512 if (isset($args[2])) {
513 $tag->{$args[0]} .= ':'.$args[2];
514 }
515 } else {
516 $tag->$arg0 = true;
517 }
518 }
519
520 return $tag;
521 }
522
523 public function wrapText(string $text, object $tag): string
524 {
525 if (empty($tag->wrap)) {
526 return $text;
527 }
528
529 $tag->wrap = intval($tag->wrap);
530
531 $allowedTags = [
532 'b',
533 'strong',
534 'i',
535 'em',
536 'a',
537 'p',
538 'div',
539 'h2',
540 'h3',
541 'h4',
542 'h5',
543 'h6',
544 ];
545
546 $aloneAllowedTags = [
547 'br',
548 'img',
549 ];
550
551 $newText = strip_tags($text, '<'.implode('><', array_merge($allowedTags, $aloneAllowedTags)).'>');
552
553 $newText = preg_replace('/^(\s|\n|(<br[^>]*>))+/i', '', trim($newText));
554 $newText = preg_replace('/(\s|\n|(<br[^>]*>))+$/i', '', trim($newText));
555
556 $newText = str_replace(['&lt', '&gt'], ['<', '>'], $newText);
557
558 $numChar = strlen($newText);
559
560 $numCharStrip = strlen(strip_tags($newText));
561
562 if ($numCharStrip <= $tag->wrap) {
563 return $newText;
564 }
565
566 $open = [];
567
568 $write = true;
569
570 $countStripChar = 0;
571
572 for ($i = 0 ; $i < $numChar ; $i++) {
573 if ($newText[$i] == '<') {
574 foreach ($allowedTags as $oneAllowedTag) {
575 if ($numChar >= ($i + strlen($oneAllowedTag) + 1) && substr($newText, $i, strlen($oneAllowedTag) + 1) == '<'.$oneAllowedTag && (in_array(
576 $newText[$i + strlen($oneAllowedTag) + 1],
577 [' ', '>']
578 ))) {
579 $write = false;
580 $open[] = '</'.$oneAllowedTag.'>';
581 }
582
583 if ($numChar >= ($i + strlen($oneAllowedTag) + 2) && substr($newText, $i, strlen($oneAllowedTag) + 2) == '</'.$oneAllowedTag) {
584 if (end($open) == '</'.$oneAllowedTag.'>') {
585 array_pop($open);
586 }
587 }
588 }
589
590 foreach ($aloneAllowedTags as $oneAllowedTag) {
591 if ($numChar >= ($i + strlen($oneAllowedTag) + 1) && substr($newText, $i, strlen($oneAllowedTag) + 1) == '<'.$oneAllowedTag && (in_array(
592 $newText[$i + strlen($oneAllowedTag) + 1],
593 [' ', '/', '>']
594 ))) {
595 $write = false;
596 }
597 }
598 }
599
600 if ($write) {
601 $countStripChar++;
602 }
603
604 if ($newText[$i] == ">") {
605 $write = true;
606 }
607
608 if ($newText[$i] == " " && $countStripChar >= $tag->wrap && $write) {
609 $newText = substr($newText, 0, $i).'...';
610
611 $open = array_reverse($open);
612 $newText = $newText.implode('', $open);
613
614 break;
615 }
616 }
617
618 $newText = preg_replace('/^(\s|\n|(<br[^>]*>))+/i', '', trim($newText));
619 $newText = preg_replace('/(\s|\n|(<br[^>]*>))+$/i', '', trim($newText));
620
621 return $newText;
622 }
623
624 public function getStandardDisplay(object $format): string
625 {
626 if (empty($format->tag->format)) {
627 $format->tag->format = 'TOP_LEFT';
628 }
629 if (!in_array($format->tag->format, ['TOP_LEFT', 'TOP_RIGHT', 'TITLE_IMG', 'TITLE_IMG_RIGHT', 'CENTER_IMG', 'TOP_IMG', 'COL_LEFT', 'COL_RIGHT'])) {
630 $format->tag->format = 'TOP_LEFT';
631 }
632
633 $invertValues = [
634 'TOP_LEFT' => 'TOP_RIGHT',
635 'TITLE_IMG' => 'TITLE_IMG_RIGHT',
636 'COL_LEFT' => 'COL_RIGHT',
637 'TOP_RIGHT' => 'TOP_LEFT',
638 'TITLE_IMG_RIGHT' => 'TITLE_IMG',
639 'COL_RIGHT' => 'COL_LEFT',
640 ];
641 if (!empty($format->tag->invert) && !empty($invertValues[$format->tag->format])) {
642 $format->tag->format = $invertValues[$format->tag->format];
643 }
644
645 $image = '';
646 if (!empty($format->imagePath)) {
647 $style = '';
648 $linkStyle = '';
649
650 if (in_array($format->tag->format, ['TOP_LEFT', 'TITLE_IMG'])) {
651 $style = 'left';
652 } elseif (in_array($format->tag->format, ['TOP_RIGHT', 'TITLE_IMG_RIGHT'])) {
653 $style = 'right';
654 }
655
656 if (!empty($style)) {
657 $linkStyle = 'style="float:'.$style.';"';
658
659 if ($style === 'left') {
660 $style = 'style="float:left; margin-right: 7px; margin-bottom: 7px;"';
661 } else {
662 $style = 'style="float:right; margin-left: 7px; margin-bottom: 7px;"';
663 }
664 }
665
666 preg_match('#src="([^"]+)"#Uis', $format->imagePath, $matches);
667 if (!empty($matches[1])) $format->imagePath = $matches[1];
668 $altImage = !empty($format->altImage) ? $format->altImage : '';
669 $image = '<img class="content_main_image" alt="'.acym_escape($altImage).'" src="'.$format->imagePath.'" '.$style.' />';
670
671 if (!empty($format->imageCaption) && !in_array($format->tag->format, ['TITLE_IMG', 'TITLE_IMG_RIGHT'])) {
672 $image .= '<p class="content_main_image_caption">'.acym_escape($format->imageCaption).'</p>';
673 }
674 }
675
676 $result = '';
677 if (in_array($format->tag->format, ['TITLE_IMG', 'TITLE_IMG_RIGHT'])) {
678 $format->title = $image.$format->title;
679 $image = '';
680 }
681
682 if (!empty($format->link) && !empty($image) && !empty($format->tag->clickableimg)) {
683 $image = '<a target="_blank" href="'.$format->link.'" '.$linkStyle.'>'.$image.'</a>';
684 }
685
686 if ($format->tag->format === 'TOP_IMG' && !empty($image)) {
687 $result = $image;
688 $image = '';
689 }
690
691 if (in_array($format->tag->format, ['COL_LEFT', 'COL_RIGHT'])) {
692 $maxWidth = empty($format->tag->maxwidth) ? '' : ' width: '.$format->tag->maxwidth.'px;';
693 if (empty($image)) {
694 $format->tag->format = 'TOP_LEFT';
695 } else {
696 $result = '<table><tr><td valign="middle" style="vertical-align: middle; padding-right: 7px;" class="acyleftcol">';
697 if ($format->tag->format === 'COL_LEFT') {
698 $result = '<table><tr><td valign="middle" style="vertical-align: middle; padding-right: 7px; '.$maxWidth.'" class="acyleftcol">';
699 $result .= $image.'</td><td valign="top" class="acyrightcol">';
700 }
701 }
702 }
703
704 if (!empty($format->title)) {
705 if (!empty($format->link) && !empty($format->tag->clickable)) {
706 if (empty($format->tag->type) || $format->tag->type !== 'title') {
707 $format->title = '<h2 class="acym_title">'.$format->title.'</h2>';
708 }
709
710 $title = '<a';
711 if (!empty($format->tag->type) && $format->tag->type === 'title') $title .= ' class="acym_title"';
712 $title .= ' href="'.$format->link.'" target="_blank" name="'.$this->name.'-'.$format->tag->id.'">';
713 $title .= $format->title;
714 $title .= '</a>';
715 $format->title = $title;
716 } else {
717 if (empty($format->tag->type) || $format->tag->type != 'title') {
718 $format->title = '<h2 class="acym_title">'.$format->title.'</h2>';
719 }
720 }
721
722 $result .= $format->title;
723 }
724
725 if (!empty($format->afterTitle)) {
726 $result .= $format->afterTitle;
727 }
728
729 if (!empty($format->description)) {
730 $format->description = $this->wrapText($format->description, $format->tag);
731 }
732 $this->wrappedText = $format->description;
733
734
735 $rowText = '<div class="acydescription">';
736 $endRow = '</div><br />';
737 if (in_array($format->tag->format, ['TOP_LEFT', 'TOP_RIGHT', 'TITLE_IMG', 'TITLE_IMG_RIGHT', 'TOP_IMG'])) {
738 if (!empty($image) || !empty($format->description)) {
739 $result .= $rowText.$image.$format->description.$endRow;
740 }
741 } elseif ($format->tag->format == 'CENTER_IMG') {
742 if (!empty($image)) {
743 $result .= '<div class="acymainimage">'.$image.$endRow;
744 }
745
746 if (!empty($format->description)) {
747 $result .= $rowText.$format->description.$endRow;
748 }
749 } elseif (in_array($format->tag->format, ['COL_LEFT', 'COL_RIGHT'])) {
750 if (!empty($format->description)) {
751 $result .= $rowText.$format->description.$endRow;
752 }
753
754 if ($format->tag->format === 'COL_RIGHT') {
755 $result .= '</td><td valign="middle" style="vertical-align: middle; padding-left: 7px; '.$maxWidth.'" class="acyrightcol">'.$image;
756 }
757 $result .= '</td></tr></table>';
758 }
759
760 if (!empty($format->customFields)) {
761 $result .= '<table style="width:100%;" class="customfieldsarea"><tr>';
762
763 $format->cols = empty($format->tag->nbcols) ? 1 : intval($format->tag->nbcols);
764 if (empty($format->cols)) $format->cols = 1;
765
766 $i = 0;
767 foreach ($format->customFields as $oneField) {
768 if ($i != 0 && $i % $format->cols == 0) $result .= '</tr><tr>';
769
770 $result .= '<td nowrap="nowrap" class="cf';
771
772 if (empty($oneField[1])) {
773 $result .= 'value" colspan="2">';
774 } else {
775 $result .= 'label">'.$oneField[1].'</td><td class="cfvalue">';
776 }
777
778 $result .= $oneField[0].'</td>';
779 $i++;
780 }
781
782 while ($i % $format->cols != 0) {
783 $result .= '<td colspan="2"></td>';
784 $i++;
785 }
786
787 $result .= '</tr></table>';
788 }
789
790 if (!empty($format->afterArticle)) {
791 $result .= $format->afterArticle;
792 }
793
794 return $result;
795 }
796
797 public function managePicts(object $tag, string $result): string
798 {
799 if (!isset($tag->pict)) {
800 return $result;
801 }
802
803 $imageHelper = new ImageHelper();
804 if ($tag->pict === 'resized') {
805 $imageHelper->maxHeight = empty($tag->maxheight) ? 150 : $tag->maxheight;
806 $imageHelper->maxWidth = empty($tag->maxwidth) ? 150 : $tag->maxwidth;
807 if ($imageHelper->available()) {
808 $result = $imageHelper->resizePictures($result);
809 } elseif (acym_isAdmin()) {
810 acym_enqueueMessage($imageHelper->error, 'notice');
811 }
812 } elseif ($tag->pict == '0') {
813 $result = $imageHelper->removePictures($result);
814 }
815
816 return acym_absoluteURL($result);
817 }
818
819 public function displayOptions(array $options, string $dynamicIdentifier, string $type = 'individual', $defaultValues = null): string
820 {
821 $suffix = preg_replace('[^a-zA-Z0-9]', '_', $dynamicIdentifier);
822 $updateFunction = 'updateDynamic'.$suffix;
823
824 $outputStructure = [
825 'topOptions' => [],
826 'options' => [],
827 ];
828 $jsOptionsMerge = [];
829
830 foreach ($options as $option) {
831 $currentLabel = $option['title'];
832 $currentOption = '';
833
834 if (isset($defaultValues->{$option['name']})) {
835 $option['default'] = $defaultValues->{$option['name']};
836 }
837
838 if ($option['type'] === 'pictures') {
839 $displayedPictures = $option['default'] ?? 'resized';
840 if (isset($defaultValues->pict)) $displayedPictures = $defaultValues->pict;
841 $resizeDisplay = 'resized' === $displayedPictures ? '' : 'style="display: none;"';
842 $maxWidth = $defaultValues->maxwidth ?? 150;
843 $maxHeight = $defaultValues->maxheight ?? 150;
844
845 $valImages = [];
846 $valImages[] = acym_selectOption('1', 'ACYM_YES');
847 $valImages[] = acym_selectOption('resized', 'ACYM_RESIZED');
848 $valImages[] = acym_selectOption('0', 'ACYM_NO');
849 $currentOption .= '<div class="cell large-5 acym_plugin_field">'.acym_translation('ACYM_DISPLAY').'</div>';
850 $currentOption .= '<div class="cell large-7">'.acym_radio(
851 $valImages,
852 'pict'.$suffix,
853 $displayedPictures,
854 ['onclick' => $updateFunction.'();'],
855 ['containerClass' => 'dcontent_pictures'],
856 !acym_isAdmin()
857 ).'</div>';
858 $currentOption .= '<div id="pictsize'.$suffix.'" class="cell grid-x margin-y margin-top-1" '.$resizeDisplay.'>
859 <div class="cell large-5 acym_plugin_field">'.acym_translation('ACYM_MAX_WIDTH').'</div>
860 <div class="cell large-7">
861 <input class="intext_input" name="pictwidth'.$suffix.'" type="number" onchange="'.$updateFunction.'();" value="'.intval($maxWidth).'"/>
862 </div>
863 <div class="cell large-5 acym_plugin_field">'.acym_translation('ACYM_MAX_HEIGHT').'</div>
864 <div class="cell large-7">
865 <input class="intext_input" name="pictheight'.$suffix.'" type="number" onchange="'.$updateFunction.'();" value="'.intval($maxHeight).'"/>
866 </div>
867 </div>';
868 if (!empty($option['caption'])) {
869 $currentOption .= '<div class="cell grid-x margin-top-1">';
870 $currentOption .= '<label class="cell large-5 acym_plugin_field">'.acym_translation('ACYM_CAPTION').'</label>';
871 $currentOption .= acym_radio(
872 [
873 acym_selectOption('1', 'ACYM_YES'),
874 acym_selectOption('0', 'ACYM_NO'),
875 ],
876 'caption'.$suffix,
877 $defaultValues->caption ?? '0',
878 ['onclick' => $updateFunction.'();'],
879 ['containerClass' => 'cell large-7']
880 );
881 $currentOption .= '</div>';
882
883 $jsOptionsMerge[] = 'otherinfo += "| caption:" + jQuery(\'input[name="caption'.$suffix.'"]:checked\').val();';
884 }
885
886 $jsOptionsMerge[] = '
887 var _pictVal'.$suffix.' = jQuery(\'input[name="pict'.$suffix.'"]:checked\').val();
888 otherinfo += "| pict:" + _pictVal'.$suffix.';
889
890 if(_pictVal'.$suffix.' == "resized"){
891 jQuery("#pictsize'.$suffix.'").show();
892 otherinfo += "| maxwidth:" + jQuery(\'input[name="pictwidth'.$suffix.'"]\').val();
893 otherinfo += "| maxheight:" + jQuery(\'input[name="pictheight'.$suffix.'"]\').val();
894 }else{
895 jQuery("#pictsize'.$suffix.'").hide();
896 }';
897 } elseif ($option['type'] === 'checkbox') {
898 if (!empty($option['default'])) {
899 $checkedValues = explode(',', $option['default']);
900 foreach ($option['options'] as $key => $oneOption) {
901 $oneOption[1] = in_array($key, $checkedValues);
902 $option['options'][$key] = $oneOption;
903 }
904 }
905
906 $currentOption .= '<div class="cell grid-x">';
907 foreach ($option['options'] as $value => $title) {
908 $currentOption .= '<div class="cell medium-6" '.(empty($title[2]) ? '' : $title[2]).'>
909 <input type="checkbox" name="'.acym_escape($option['name'].$suffix).'" value="'.acym_escape($value).'" id="'.acym_escape(
910 $value.$suffix
911 ).'" onclick="'.$updateFunction.'();" '.($title[1] ? 'checked="checked"' : '').'/>
912 <label style="margin-left:5px" for="'.acym_escape($value.$suffix).'">'.acym_translation($title[0]).'</label>
913 </div>';
914 }
915 $currentOption .= '</div>';
916
917 if (empty($option['separator'])) $option['separator'] = ',';
918
919 $jsOptionsMerge[] = 'var _checked'.$option['name'].$suffix.' = [];
920 jQuery("input:checkbox[name='.$option['name'].$suffix.']:checked").each(function(){
921 _checked'.$option['name'].$suffix.'.push(jQuery(this).val());
922 });
923 if(_checked'.$option['name'].$suffix.'.length) otherinfo += "| '.$option['name'].':" + _checked'.$option['name'].$suffix.'.join("'.$option['separator'].'");';
924 } elseif ($option['type'] === 'boolean') {
925 if ($option['name'] === 'autologin' && $this->config->get('autologin_urls', 0) != 1) {
926 continue;
927 }
928
929 $currentOption .= acym_boolean(
930 $option['name'].$suffix,
931 $option['default'],
932 $option['name'].$suffix,
933 ['onclick' => $updateFunction.'();']
934 );
935
936 $jsOptionsMerge[] = 'otherinfo += "| '.$option['name'].':" + jQuery(\'input[name="'.$option['name'].$suffix.'"]:checked\').val();';
937 } elseif ($option['type'] === 'radio') {
938 $radioOptions = [];
939 foreach ($option['options'] as $value => $title) {
940 $radioOptions[] = acym_selectOption($value, $title);
941 }
942
943 $currentOption .= acym_radio(
944 $radioOptions,
945 $option['name'].$suffix,
946 $option['default'],
947 ['onclick' => $updateFunction.'();'],
948 ['pluginMode' => true],
949 !acym_isAdmin()
950 );
951 $jsOptionsMerge[] = 'otherinfo += "| '.$option['name'].':" + jQuery(\'input[name="'.$option['name'].$suffix.'"]:checked\').val();';
952 } elseif ($option['type'] === 'select') {
953 $selectOptions = [];
954 foreach ($option['options'] as $value => $title) {
955 if (is_object($title)) {
956 $selectOptions[] = acym_selectOption($title->value, $title->text);
957 } else {
958 $selectOptions[] = acym_selectOption($value, $title);
959 }
960 }
961
962 $default = empty($option['default']) ? null : $option['default'];
963 if (!empty($default) && strpos($default, ',')) [$default, $defaultOrder] = explode(',', $default);
964
965 $attributes = [
966 'onchange' => $updateFunction.'();',
967 'id' => $option['name'].$suffix,
968 ];
969 if ($option['name'] === 'order') {
970 $attributes['class'] = 'acym__dynamics__ordering__select';
971 }
972 $currentOption .= acym_select(
973 $selectOptions,
974 $option['name'].$suffix,
975 $default,
976 $attributes
977 );
978
979 if ($option['name'] === 'order') {
980 $dirs = [
981 'desc' => acym_translation('ACYM_DESC'),
982 'asc' => acym_translation('ACYM_ASC'),
983 ];
984 if (empty($defaultOrder)) $defaultOrder = empty($option['defaultdir']) ? null : $option['defaultdir'];
985 $currentOption .= ' '.acym_select(
986 $dirs,
987 'orderdir'.$suffix,
988 $defaultOrder,
989 [
990 'onchange' => $updateFunction.'();',
991 'style' => 'width: 115px;',
992 'class' => 'acym__dynamics__ordering__select',
993 ]
994 );
995
996 $jsOptionsMerge[] = 'otherinfo += "| '.$option['name'].':" + jQuery(\'[name="'.$option['name'].$suffix.'"]\').val() + "," + jQuery(\'[name="orderdir'.$suffix.'"]\').val();';
997 } else {
998 $jsOptionsMerge[] = 'otherinfo += "| '.$option['name'].':" + jQuery(\'[name="'.$option['name'].$suffix.'"]\').val();';
999 }
1000 } elseif ($option['type'] === 'multiselect') {
1001 $selectOptions = [];
1002 foreach ($option['options'] as $value => $title) {
1003 $selectOptions[] = acym_selectOption($value, $title);
1004 }
1005
1006
1007 if (!isset($option['default'])) $option['default'] = [];
1008 if (!is_array($option['default'])) $option['default'] = explode(',', $option['default']);
1009
1010 $currentOption .= acym_selectMultiple(
1011 $selectOptions,
1012 $option['name'].$suffix,
1013 $option['default'],
1014 ['onchange' => $updateFunction.'();', 'id' => $option['name'].$suffix]
1015 );
1016
1017 $jsOptionsMerge[] = '
1018 var theMultiSelect = document.querySelector(\'[name="'.$option['name'].$suffix.'[]"]\');
1019 var selectedOptions = [];
1020 for(var i = 0 ; i < theMultiSelect.length ; i++){
1021 if(theMultiSelect[i].selected){
1022 selectedOptions.push(theMultiSelect[i].value);
1023 }
1024 }
1025 otherinfo += "| '.$option['name'].':" + selectedOptions.join(",");';
1026 } elseif ($option['type'] === 'text') {
1027 if (!isset($option['default'])) $option['default'] = '';
1028 $class = empty($option['class']) ? 'acym_plugin_text_field' : $option['class'];
1029 $placeholder = empty($option['placeholder']) ? '' : ' placeholder="'.acym_escape($option['placeholder']).'"';
1030 $currentOption .= '<input
1031 type="text"
1032 name="'.$option['name'].$suffix.'"
1033 id="'.$option['name'].$suffix.'"
1034 onchange="'.$updateFunction.'();"
1035 value="'.acym_escape($option['default']).'"
1036 class="'.acym_escape($class).'" '.$placeholder.'/>';
1037 $jsOptionsMerge[] = 'otherinfo += "| '.$option['name'].':" + jQuery(\'input[name="'.$option['name'].$suffix.'"]\').val();';
1038 } elseif ($option['type'] === 'number') {
1039 $min = empty($option['min']) ? ' min="0"' : ' min="'.$option['min'].'"';
1040 $max = empty($option['max']) ? '' : ' max="'.$option['max'].'"';
1041 $class = empty($option['class']) ? 'acym_plugin_text_field' : $option['class'];
1042 $currentOption .= '<input type="number"'.$min.$max.' name="'.$option['name'].$suffix.'" id="'.$option['name'].$suffix.'" onchange="'.$updateFunction.'();" value="'.intval(
1043 $option['default']
1044 ).'" class="'.acym_escape($class).'" />';
1045 $jsOptionsMerge[] = 'otherinfo += "| '.$option['name'].':" + jQuery(\'input[name="'.$option['name'].$suffix.'"]\').val();';
1046 } elseif ($option['type'] === 'intextfield') {
1047 $inputType = 'text';
1048 if (!empty($option['isNumber']) && $option['isNumber'] === 1) $inputType = 'number';
1049 $currentOption .= acym_translationSprintf(
1050 $option['text'],
1051 '<input type="'.$inputType.'" name="'.$option['name'].$suffix.'" id="'.$option['name'].$suffix.'" class="intext_input" value="'.acym_escape(
1052 $option['default']
1053 ).'" onchange="'.$updateFunction.'();"/>'
1054 );
1055 $jsOptionsMerge[] = 'otherinfo += "| '.$option['name'].':" + jQuery(\'input[name="'.$option['name'].$suffix.'"]\').val();';
1056 } elseif ($option['type'] === 'date') {
1057 $relativeTime = '-';
1058 if (!empty($option['relativeDate'])) $relativeTime = $option['relativeDate'];
1059 if (!empty($option['default']) && !is_numeric($option['default']) && false === strpos($option['default'], '[time]')) {
1060 $option['default'] = strtotime($option['default']);
1061 }
1062 $currentOption .= acym_dateField($option['name'].$suffix, $option['default'], '', ' onchange="'.$updateFunction.'();"', $relativeTime);
1063 $jsOptionsMerge[] = 'otherinfo += "| '.$option['name'].':" + jQuery(\'input[name="'.$option['name'].$suffix.'"]\').val();';
1064 } elseif ($option['type'] === 'language') {
1065 $languageOptions = [];
1066 $languageOptions['any'] = acym_translation('ACYM_ANY');
1067
1068 $languages = acym_getLanguages(true);
1069 foreach ($languages as $language) {
1070 $languageOptions[$language->language] = $language->name;
1071 }
1072
1073 if (empty($option['default'])) {
1074 $option['default'] = acym_getVar('string', 'language');
1075 if (acym_isMultilingual() && (empty($option['default']) || $option['default'] === 'main')) {
1076 $option['default'] = $this->config->get('multilingual_default');
1077 }
1078 }
1079
1080 $currentOption .= acym_select(
1081 $languageOptions,
1082 $option['name'].$suffix,
1083 empty($option['default']) ? null : $option['default'],
1084 [
1085 'onchange' => $updateFunction.'();',
1086 'id' => $option['name'].$suffix,
1087 ]
1088 );
1089
1090 $jsOptionsMerge[] = 'otherinfo += "| '.$option['name'].':" + jQuery(\'[name="'.$option['name'].$suffix.'"]\').val();';
1091 } elseif ($option['type'] == 'custom') {
1092 $currentOption .= $option['output'];
1093 $jsOptionsMerge[] = $option['js'];
1094 }
1095
1096 if (!empty($option['main']) || in_array($option['type'], ['pictures', 'checkbox'])) {
1097 $outputStructure['topOptions'][$currentLabel] = $currentOption;
1098
1099 if ($option['type'] === 'checkbox' && $currentLabel === 'ACYM_DISPLAY' && (!isset($option['format']) || $option['format'])) {
1100 $formatOption = '<div class="grid-x">';
1101 $formatOption .= '<div class="cell large-3">'.acym_translation('ACYM_FORMAT').'</div>';
1102 $formatOption .= '<div class="cell large-9 dcontentFormatContainer">';
1103
1104 $default = empty($defaultValues->format) ? 'TOP_LEFT' : $defaultValues->format;
1105 $formats = ['TOP_LEFT', 'TOP_RIGHT', 'TITLE_IMG', 'TITLE_IMG_RIGHT', 'CENTER_IMG', 'TOP_IMG', 'COL_LEFT', 'COL_RIGHT'];
1106 foreach ($formats as $oneFormat) {
1107 $class = 'button-radio';
1108 if ($default === $oneFormat) $class .= ' button-radio-selected';
1109
1110 $formatOption .= '<button
1111 class="'.$class.'"
1112 acym-button-radio-group="dcontentFormat'.$suffix.'"
1113 acym-data-type="'.$oneFormat.'"
1114 acym-callback="'.$updateFunction.'">
1115 <img alt="'.$oneFormat.'" src="'.ACYM_IMAGES.'editor/dcontent_formats/'.strtolower($oneFormat).'.png"/>
1116 </button>';
1117 }
1118 $formatOption .= '</div>';
1119
1120 if ($type === 'grouped') {
1121 $formatOption .= '<div class="cell large-3">'.acym_translation('ACYM_ALTERNATE').acym_info('ACYM_ALTERNATE_DESC').'</div>';
1122 $formatOption .= '<div class="cell large-9">';
1123 $formatOption .= acym_boolean(
1124 'alternate'.$suffix,
1125 !empty($defaultValues->alternate),
1126 'alternate'.$suffix,
1127 ['onclick' => $updateFunction.'();']
1128 );
1129 $formatOption .= '</div>';
1130
1131 $jsOptionsMerge[] = 'var alternate = jQuery(\'input[name="alternate'.$suffix.'"]:checked\').val();';
1132 $jsOptionsMerge[] = 'if (!acym_helper.empty(alternate)) otherinfo += "| alternate";';
1133 }
1134
1135 $formatOption .= '</div>';
1136
1137 $jsOptionsMerge[] = 'var selectedFormatOption = jQuery(\'.button-radio-selected[acym-button-radio-group="dcontentFormat'.$suffix.'"]\')';
1138 $jsOptionsMerge[] = 'if (!acym_helper.empty(selectedFormatOption)) otherinfo += "| format:" + selectedFormatOption.attr("acym-data-type");';
1139
1140 $outputStructure['topOptions']['ACYM_FORMAT'] = $formatOption;
1141 }
1142 continue;
1143 }
1144
1145 if (empty($option['section'])) {
1146 $option['section'] = 'ACYM_OTHER_OPTIONS';
1147 }
1148
1149 $currentLabel = acym_translation($currentLabel);
1150 if (!empty($option['tooltip'])) {
1151 $currentLabel .= '&nbsp;'.acym_info($option['tooltip'], 'acym_plugin_field_'.$option['name']);
1152 }
1153 $currentLabel = '<label class="cell large-5 acym_plugin_field acym_plugin_field_'.$option['type'].'" for="'.acym_escape(
1154 $option['name'].$suffix
1155 ).'">'.$currentLabel.'</label>';
1156
1157 $outputStructure['options'][$option['section']][$currentLabel] = $currentOption;
1158 }
1159
1160 if (!empty($outputStructure['options'])) {
1161 foreach ($outputStructure['options'] as $section => $options) {
1162 $formattedOptions = '';
1163 foreach ($options as $label => $option) {
1164 $formattedOptions .= '<div class="cell grid-x margin-bottom-1">'.$label;
1165 $formattedOptions .= '<div class="cell large-7">'.$option.'</div>';
1166 $formattedOptions .= '</div>';
1167 }
1168 $outputStructure['topOptions'][$section] = $formattedOptions;
1169 }
1170 }
1171
1172 $output = '';
1173 if (!empty($outputStructure['topOptions'])) {
1174 foreach ($outputStructure['topOptions'] as $label => $oneOption) {
1175 $output .= '<p class="acym__wysid__right__toolbar__p acym__wysid__right__toolbar__p__open acym__title">';
1176 $output .= acym_translation($label).'<i class="acymicon-keyboard-arrow-up"></i>';
1177 $output .= '</p>';
1178 $output .= '<div class="acym__wysid__right__toolbar__design--show acym__wysid__right__toolbar__design acym__wysid__context__modal__container grid-x">';
1179 $output .= $oneOption;
1180 $output .= '</div>';
1181 }
1182 }
1183
1184 $output .= '
1185 <script type="text/javascript">
1186 var _selectedRows'.$suffix.' = [];
1187 var _selectedRows = [];
1188 if("undefined" === typeof _additionalInfo'.$suffix.') {
1189 var _additionalInfo'.$suffix.' = {};
1190 }
1191 ';
1192 if (!empty($defaultValues->id) && (empty($defaultValues->defaultPluginTab) || $dynamicIdentifier === $defaultValues->defaultPluginTab)) {
1193 $delimiter = strpos($defaultValues->id, '-') ? '-' : ',';
1194 $selected = explode($delimiter, $defaultValues->id);
1195
1196 foreach ($selected as $value) {
1197 if (empty($value)) continue;
1198 $output .= '_selectedRows'.$suffix.'['.intval($value).'] = true;
1199 ';
1200 }
1201 }
1202
1203 $output .= '
1204 function applyContent'.$suffix.'(contentid, row){
1205 if(_selectedRows'.$suffix.'[contentid]){
1206 jQuery(row).removeClass("selected_row");
1207 delete _selectedRows'.$suffix.'[contentid];
1208 }else{
1209 ';
1210
1211 if ('individual' === $type) {
1212 $output .= '
1213 for(let elementKey in _selectedRows'.$suffix.') {
1214 if(!_selectedRows'.$suffix.'.hasOwnProperty(elementKey)) continue;
1215
1216 jQuery(\'[data-id="\' + elementKey + \'"]\').removeClass("selected_row");
1217 delete _selectedRows'.$suffix.'[elementKey];
1218 }
1219 ';
1220 }
1221
1222 $output .= '
1223 jQuery(row).addClass("selected_row");
1224 _selectedRows'.$suffix.'[contentid] = true;
1225 }
1226 '.$updateFunction.'();
1227
1228 if(typeof _selectedRows !== "undefined"){
1229 _selectedRows = _selectedRows'.$suffix.';
1230 }
1231 }
1232
1233 function '.$updateFunction.'(){
1234 var tag = "";
1235 var otherinfo = "";
1236
1237 '.implode("\r\n\r\n", $jsOptionsMerge).'
1238
1239 for (let [index, info] of Object.entries(_additionalInfo'.$suffix.')){
1240 otherinfo += "| "+index+":"+info;
1241 }
1242 ';
1243
1244 if ($type == 'individual') {
1245 $output .= '
1246 for(var i in _selectedRows'.$suffix.'){
1247 if(!_selectedRows'.$suffix.'.hasOwnProperty(i)) continue;
1248
1249 tag = tag + "{'.$dynamicIdentifier.':" + i + otherinfo + "}";
1250 }';
1251 } elseif ($type == 'grouped') {
1252 $output .= '
1253 tag = "{'.$dynamicIdentifier.':";
1254 for(var icat in _selectedRows'.$suffix.'){
1255 if(!_selectedRows'.$suffix.'.hasOwnProperty(icat)) continue;
1256 tag += icat + "-";
1257 }
1258 tag += otherinfo + "}";';
1259 } elseif ($type == 'simple') {
1260 $output .= '
1261 tag = "{'.$dynamicIdentifier.':" + otherinfo + "}";';
1262 }
1263
1264 $output .= '
1265 acym_editorWysidDynamic.insertDContent(tag);
1266 }
1267
1268 function addAdditionalInfo'.$suffix.'(index, value){
1269 _additionalInfo'.$suffix.'[index] = value;
1270 '.$updateFunction.'();
1271 }
1272 </script>';
1273
1274 if ($type == 'individual') {
1275 acym_trigger('displayCustomViewEditor', [&$output], 'plgAcym'.ucfirst($dynamicIdentifier));
1276 $output .= '<input type="hidden" id="acym__dynamic__update__function" value="'.$updateFunction.'">';
1277 }
1278
1279 return $output;
1280 }
1281
1282 public function translateItem(object &$item, object &$tag, string $referenceTable, int $referenceId = 0): void
1283 {
1284 if (!acym_isExtensionActive('com_falang')) {
1285 return;
1286 }
1287
1288 if (!empty($tag->falang)) {
1289 $langId = $tag->falang;
1290 } elseif (!empty($tag->lang)) {
1291 $langId = intval(substr($tag->lang, strpos($tag->lang, ',') + 1));
1292 } elseif (!empty($this->contextLanguage)) {
1293 $languages = acym_loadObjectList('SELECT `lang_id`, `lang_code` FROM #__languages', 'lang_code');
1294 if (!empty($languages[$this->contextLanguage])) {
1295 $langId = $languages[$this->contextLanguage]->lang_id;
1296 }
1297 }
1298
1299 if (empty($langId)) {
1300 return;
1301 }
1302
1303 if (empty($referenceId)) {
1304 $referenceId = $tag->id;
1305 }
1306
1307 $translations = acym_loadObjectList(
1308 'SELECT `reference_field`, `value`
1309 FROM `#__falang_content`
1310 WHERE `published` = 1
1311 AND `reference_table` = '.acym_escapeDB($referenceTable).'
1312 AND `language_id` = '.intval($langId).'
1313 AND `reference_id` = '.intval($referenceId)
1314 );
1315
1316 if (empty($translations)) {
1317 return;
1318 }
1319
1320 foreach ($translations as $oneTranslation) {
1321 if (empty($oneTranslation->value)) {
1322 continue;
1323 }
1324
1325 $translatedField = $oneTranslation->reference_field;
1326 $item->$translatedField = $oneTranslation->value;
1327 }
1328 }
1329
1330 public function createDummyEmailObject(int $mailId, string $code, string $previewBody): object
1331 {
1332 if (!empty($mailId)) {
1333 $mailClass = new MailClass();
1334 $email = $mailClass->getOneById($mailId);
1335 }
1336
1337 if (empty($email)) {
1338 $email = new \stdClass();
1339 $email->id = 0;
1340 $email->name = '';
1341 $email->subject = '';
1342 $email->from_name = '';
1343 $email->from_email = '';
1344 $email->reply_to_name = '';
1345 $email->reply_to_email = '';
1346 $email->bcc = '';
1347 $email->links_language = '';
1348 }
1349
1350 $language = acym_getVar('string', 'language', 'main');
1351 if (!empty($language)) {
1352 if ($language === 'main') {
1353 $language = $this->config->get('multilingual_default', ACYM_DEFAULT_LANGUAGE);
1354 }
1355 $email->links_language = $language;
1356 }
1357
1358 $email->creation_date = acym_date('now', 'Y-m-d H:i:s', false);
1359 $email->creator_id = acym_currentUserId();
1360 $email->thumbnail = '';
1361 $email->drag_editor = '1';
1362 $email->type = MailClass::TYPE_STANDARD;
1363 $email->settings = '';
1364 $email->stylesheet = '';
1365 $email->attachments = '';
1366
1367 $email->body = $code;
1368 $email->previewBody = $previewBody;
1369
1370 return $email;
1371 }
1372 }
1373