PluginProbe
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress / 11.1.1
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress v11.1.1
11.1.1 11.1.0 11.0.5 11.0.4 11.0.3 11.0.2 11.0.1 11.0.0 10.11.1 10.11.0 10.10.2 10.10.1 10.10.0 10.9.1 trunk 10.0.0 10.0.1 10.1.0 10.1.1 10.1.2 10.1.3 10.1.4 10.2.0 10.2.1 10.2.2 All 62 releases
← All changes | back/Helpers/PluginHelper.php +0 -1356 10.11.1 → 11.1.1 View file →
@@ -1,1356 +1,0 @@
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 -}