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 -1372 10.2.2 → 11.1.1 View file →
@@ -1,1372 +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 -
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 -}