| @@ -880,9 +880,9 @@ | ||
| 880 | 880 | { |
| 881 | 881 | $suffix = preg_replace('#[^a-zA-Z0-9]#U', '_', $dynamicIdentifier); |
| 882 | 882 | $updateFunction = 'updateDynamic'.$suffix; |
| 883 | 883 | |
| 884 | - $jsOptionsMerge = []; | |
| 884 | + $jsOptions = []; | |
| 885 | 885 | $topOptions = []; |
| 886 | 886 | $sections = []; |
| 887 | 887 | |
| 888 | 888 | // ---- Phase 1: classify options + collect the JS (in original loop order) ---- |
| @@ -899,9 +899,9 @@ | ||
| 899 | 899 | ) { |
| 900 | 900 | continue; |
| 901 | 901 | } |
| 902 | 902 | |
| 903 | - $this->appendOptionJs($jsOptionsMerge, $option, $suffix, $type); | |
| 903 | + $jsOptions[] = $option; | |
| 904 | 904 | |
| 905 | 905 | $isTop = !empty($option['main']) || in_array($option['type'], ['pictures', 'checkbox'], true); |
| 906 | 906 | |
| 907 | 907 | if ($isTop) { |
| @@ -955,9 +955,9 @@ | ||
| 955 | 955 | echo '</div>'; |
| 956 | 956 | } |
| 957 | 957 | |
| 958 | 958 | // ---- Phase 3: the inline script + individual extras ---- |
| 959 | - $this->displayDynamicScript($jsOptionsMerge, $suffix, $updateFunction, $dynamicIdentifier, $type, $defaultValues); | |
| 959 | + $this->displayDynamicScript($jsOptions, $suffix, $updateFunction, $dynamicIdentifier, $type, $defaultValues); | |
| 960 | 960 | |
| 961 | 961 | if ($type === 'individual') { |
| 962 | 962 | acym_trigger('displayCustomViewEditor', [], 'plgAcym'.ucfirst($dynamicIdentifier)); |
| 963 | 963 | echo '<input type="hidden" id="acym__dynamic__update__function" value="'.esc_attr($updateFunction).'">'; |
| @@ -1075,13 +1075,24 @@ | ||
| 1075 | 1075 | case 'language': |
| 1076 | 1076 | $this->displayLanguageField($option, $suffix, $updateFunction); |
| 1077 | 1077 | break; |
| 1078 | 1078 | case 'custom': |
| 1079 | - echo $option['output']; | |
| 1079 | + $this->displayCustomOptionOutput($option); | |
| 1080 | 1080 | break; |
| 1081 | 1081 | } |
| 1082 | 1082 | } |
| 1083 | 1083 | |
| 1084 | + private function displayCustomOptionOutput(array $option): void | |
| 1085 | + { | |
| 1086 | + if (empty($option['output'])) { | |
| 1087 | + return; | |
| 1088 | + } | |
| 1089 | + | |
| 1090 | + if (!is_string($option['output']) && is_callable($option['output'])) { | |
| 1091 | + ($option['output'])(); | |
| 1092 | + } | |
| 1093 | + } | |
| 1094 | + | |
| 1084 | 1095 | private function displayPicturesField(array $option, string $suffix, string $updateFunction, $defaultValues): void |
| 1085 | 1096 | { |
| 1086 | 1097 | $displayedPictures = $option['default'] ?? 'resized'; |
| 1087 | 1098 | if (isset($defaultValues->pict)) { |
| @@ -1179,9 +1190,9 @@ | ||
| 1179 | 1190 | name="'.esc_attr($option['name'].$suffix).'" |
| 1180 | 1191 | value="'.esc_attr($value).'" |
| 1181 | 1192 | id="'.esc_attr($value.$suffix).'" |
| 1182 | 1193 | onclick="'.esc_attr($updateFunction).'();" '; |
| 1183 | - acym_checked((bool)$title[1]); | |
| 1194 | + checked((bool)$title[1]); | |
| 1184 | 1195 | echo ' />'; |
| 1185 | 1196 | echo '<label style="margin-left:5px" for="'.esc_attr($value.$suffix).'">'; |
| 1186 | 1197 | echo esc_html(acym_translation($title[0])); |
| 1187 | 1198 | echo '</label>'; |
| @@ -1363,69 +1374,81 @@ | ||
| 1363 | 1374 | |
| 1364 | 1375 | echo '</div>'; |
| 1365 | 1376 | } |
| 1366 | 1377 | |
| 1367 | - private function appendOptionJs(array &$jsOptionsMerge, array $option, string $suffix, string $type): void | |
| 1378 | + private function echoOptionJs(array $option, string $suffix, string $type): void | |
| 1368 | 1379 | { |
| 1369 | 1380 | switch ($option['type']) { |
| 1370 | 1381 | case 'pictures': |
| 1371 | 1382 | if (!empty($option['caption'])) { |
| 1372 | - $jsOptionsMerge[] = 'otherinfo += "| caption:" + jQuery(\'input[name="caption'.esc_attr($suffix).'"]:checked\').val();'; | |
| 1383 | + echo 'otherinfo += "| caption:" + jQuery(\'input[name="caption'.esc_attr($suffix).'"]:checked\').val(); | |
| 1384 | + '; | |
| 1373 | 1385 | } |
| 1374 | - $jsOptionsMerge[] = ' | |
| 1386 | + echo ' | |
| 1375 | 1387 | var _pictVal'.esc_attr($suffix).' = jQuery(\'input[name="pict'.esc_attr($suffix).'"]:checked\').val(); |
| 1376 | 1388 | otherinfo += "| pict:" + _pictVal'.esc_attr($suffix).'; |
| 1377 | 1389 | |
| 1378 | - if(_pictVal'.esc_attr($suffix).' == "resized"){ | |
| 1390 | + if (_pictVal'.esc_attr($suffix).' == "resized") { | |
| 1379 | 1391 | jQuery("#pictsize'.esc_attr($suffix).'").show(); |
| 1380 | 1392 | otherinfo += "| maxwidth:" + jQuery(\'input[name="pictwidth'.esc_attr($suffix).'"]\').val(); |
| 1381 | 1393 | otherinfo += "| maxheight:" + jQuery(\'input[name="pictheight'.esc_attr($suffix).'"]\').val(); |
| 1382 | 1394 | }else{ |
| 1383 | 1395 | jQuery("#pictsize'.esc_attr($suffix).'").hide(); |
| 1384 | - }'; | |
| 1396 | + } | |
| 1397 | + '; | |
| 1398 | + | |
| 1385 | 1399 | break; |
| 1386 | 1400 | |
| 1387 | 1401 | case 'checkbox': |
| 1388 | 1402 | $separator = empty($option['separator']) ? ',' : $option['separator']; |
| 1389 | - $jsOptionsMerge[] = 'var _checked'.esc_attr($option['name'].$suffix).' = []; | |
| 1403 | + echo 'var _checked'.esc_attr($option['name'].$suffix).' = []; | |
| 1390 | 1404 | jQuery("input:checkbox[name='.esc_attr($option['name'].$suffix).']:checked").each(function(){ |
| 1391 | 1405 | _checked'.esc_attr($option['name'].$suffix).'.push(jQuery(this).val()); |
| 1392 | 1406 | }); |
| 1393 | 1407 | if(_checked'.esc_attr($option['name'].$suffix).'.length) otherinfo += "| '.esc_attr($option['name']).':" + _checked'.esc_attr( |
| 1394 | 1408 | $option['name'].$suffix |
| 1395 | - ).'.join("'.esc_attr($separator).'");'; | |
| 1409 | + ).'.join("'.esc_attr($separator).'"); | |
| 1410 | + '; | |
| 1396 | 1411 | |
| 1397 | 1412 | if ($option['title'] === 'ACYM_DISPLAY' && (!isset($option['format']) || $option['format'])) { |
| 1398 | 1413 | if ($type === 'grouped') { |
| 1399 | - $jsOptionsMerge[] = 'var alternate = jQuery(\'input[name="alternate'.esc_attr($suffix).'"]:checked\').val();'; | |
| 1400 | - $jsOptionsMerge[] = 'if (!acym_helper.empty(alternate)) otherinfo += "| alternate";'; | |
| 1414 | + echo 'var alternate = jQuery(\'input[name="alternate'.esc_attr($suffix).'"]:checked\').val(); | |
| 1415 | + '; | |
| 1416 | + echo 'if (!acym_helper.empty(alternate)) otherinfo += "| alternate"; | |
| 1417 | + '; | |
| 1401 | 1418 | } |
| 1402 | - $jsOptionsMerge[] = 'var selectedFormatOption = jQuery(\'.button-radio-selected[acym-button-radio-group="dcontentFormat'.esc_attr($suffix).'"]\')'; | |
| 1403 | - $jsOptionsMerge[] = 'if (!acym_helper.empty(selectedFormatOption)) otherinfo += "| format:" + selectedFormatOption.attr("acym-data-type");'; | |
| 1419 | + echo 'var selectedFormatOption = jQuery(\'.button-radio-selected[acym-button-radio-group="dcontentFormat'.esc_attr($suffix).'"]\'); | |
| 1420 | + '; | |
| 1421 | + echo 'if (!acym_helper.empty(selectedFormatOption)) otherinfo += "| format:" + selectedFormatOption.attr("acym-data-type"); | |
| 1422 | + '; | |
| 1404 | 1423 | } |
| 1405 | 1424 | break; |
| 1406 | 1425 | |
| 1407 | 1426 | case 'boolean': |
| 1408 | 1427 | case 'radio': |
| 1409 | - $jsOptionsMerge[] = 'otherinfo += "| '.esc_attr($option['name']).':" + jQuery(\'input[name="'.esc_attr($option['name'].$suffix).'"]:checked\').val();'; | |
| 1428 | + echo 'otherinfo += "| '.esc_attr($option['name']).':" + jQuery(\'input[name="'.esc_attr($option['name'].$suffix).'"]:checked\').val(); | |
| 1429 | + '; | |
| 1410 | 1430 | break; |
| 1411 | 1431 | |
| 1412 | 1432 | case 'select': |
| 1413 | 1433 | if ($option['name'] === 'order') { |
| 1414 | - $jsOptionsMerge[] = 'otherinfo += "| '.esc_attr($option['name']).':" + jQuery(\'[name="'.esc_attr( | |
| 1434 | + echo 'otherinfo += "| '.esc_attr($option['name']).':" + jQuery(\'[name="'.esc_attr( | |
| 1415 | 1435 | $option['name'].$suffix |
| 1416 | - ).'"]\').val() + "," + jQuery(\'[name="orderdir'.esc_attr($suffix).'"]\').val();'; | |
| 1436 | + ).'"]\').val() + "," + jQuery(\'[name="orderdir'.esc_attr($suffix).'"]\').val(); | |
| 1437 | + '; | |
| 1417 | 1438 | } else { |
| 1418 | - $jsOptionsMerge[] = 'otherinfo += "| '.esc_attr($option['name']).':" + jQuery(\'[name="'.esc_attr($option['name'].$suffix).'"]\').val();'; | |
| 1439 | + echo 'otherinfo += "| '.esc_attr($option['name']).':" + jQuery(\'[name="'.esc_attr($option['name'].$suffix).'"]\').val(); | |
| 1440 | + '; | |
| 1419 | 1441 | } |
| 1420 | 1442 | break; |
| 1421 | 1443 | |
| 1422 | 1444 | case 'language': |
| 1423 | - $jsOptionsMerge[] = 'otherinfo += "| '.esc_attr($option['name']).':" + jQuery(\'[name="'.esc_attr($option['name'].$suffix).'"]\').val();'; | |
| 1445 | + echo 'otherinfo += "| '.esc_attr($option['name']).':" + jQuery(\'[name="'.esc_attr($option['name'].$suffix).'"]\').val(); | |
| 1446 | + '; | |
| 1424 | 1447 | break; |
| 1425 | 1448 | |
| 1426 | 1449 | case 'multiselect': |
| 1427 | - $jsOptionsMerge[] = ' | |
| 1450 | + echo ' | |
| 1428 | 1451 | var theMultiSelect = document.querySelector(\'[name="'.esc_attr($option['name'].$suffix).'[]"]\'); |
| 1429 | 1452 | var selectedOptions = []; |
| 1430 | 1453 | for(var i = 0 ; i < theMultiSelect.length ; i++){ |
| 1431 | 1454 | if(theMultiSelect[i].selected){ |
| @@ -1431,9 +1454,10 @@ | ||
| 1431 | 1454 | if(theMultiSelect[i].selected){ |
| 1432 | 1455 | selectedOptions.push(theMultiSelect[i].value); |
| 1433 | 1456 | } |
| 1434 | 1457 | } |
| 1435 | - otherinfo += "| '.esc_attr($option['name']).':" + selectedOptions.join(",");'; | |
| 1458 | + otherinfo += "| '.esc_attr($option['name']).':" + selectedOptions.join(","); | |
| 1459 | + '; | |
| 1436 | 1460 | break; |
| 1437 | 1461 | |
| 1438 | 1462 | case 'text': |
| 1439 | 1463 | case 'number': |
| @@ -1438,20 +1462,55 @@ | ||
| 1438 | 1462 | case 'text': |
| 1439 | 1463 | case 'number': |
| 1440 | 1464 | case 'intextfield': |
| 1441 | 1465 | case 'date': |
| 1442 | - $jsOptionsMerge[] = 'otherinfo += "| '.esc_attr($option['name']).':" + jQuery(\'input[name="'.esc_attr($option['name'].$suffix).'"]\').val();'; | |
| 1466 | + echo 'otherinfo += "| '.esc_attr($option['name']).':" + jQuery(\'input[name="'.esc_attr($option['name'].$suffix).'"]\').val(); | |
| 1467 | + '; | |
| 1443 | 1468 | break; |
| 1444 | 1469 | |
| 1445 | 1470 | case 'custom': |
| 1446 | - //TODO | |
| 1447 | - $jsOptionsMerge[] = $option['js']; | |
| 1471 | + $this->echoLegacyOptionJs($option); | |
| 1448 | 1472 | break; |
| 1449 | 1473 | } |
| 1450 | 1474 | } |
| 1451 | 1475 | |
| 1452 | - private function displayDynamicScript(array $jsOptionsMerge, string $suffix, string $updateFunction, string $dynamicIdentifier, string $type, $defaultValues): void | |
| 1476 | + private function echoLegacyOptionJs(array $option): void | |
| 1453 | 1477 | { |
| 1478 | + if (empty($option['js'])) { | |
| 1479 | + return; | |
| 1480 | + } | |
| 1481 | + | |
| 1482 | + $jsonFlags = JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT; | |
| 1483 | + | |
| 1484 | + foreach (explode(';', $option['js']) as $statement) { | |
| 1485 | + $statement = trim($statement); | |
| 1486 | + if ($statement === '') { | |
| 1487 | + continue; | |
| 1488 | + } | |
| 1489 | + | |
| 1490 | + // otherinfo += "| key:constant" | |
| 1491 | + if (preg_match('#^otherinfo\s*\+=\s*"\|\s*([a-zA-Z0-9_-]+):([^"]*)"$#', $statement, $matches)) { | |
| 1492 | + echo 'otherinfo += '.json_encode('| '.$matches[1].':'.$matches[2], $jsonFlags).'; | |
| 1493 | + '; | |
| 1494 | + continue; | |
| 1495 | + } | |
| 1496 | + | |
| 1497 | + // otherinfo += "| key:" + jQuery('selector').val() | |
| 1498 | + if (preg_match('#^otherinfo\s*\+=\s*"\|\s*([a-zA-Z0-9_-]+):"\s*\+\s*jQuery\(\s*\'(.*)\'\s*\)\.val\(\)$#', $statement, $matches)) { | |
| 1499 | + echo 'otherinfo += '.json_encode('| '.$matches[1].':', $jsonFlags).' + jQuery('.json_encode($matches[2], $jsonFlags).').val(); | |
| 1500 | + '; | |
| 1501 | + continue; | |
| 1502 | + } | |
| 1503 | + | |
| 1504 | + acym_logError( | |
| 1505 | + 'Unsupported deprecated "js" option declared by an add-on for the option "'.($option['name'] ?? '').'", it was not applied: '.$statement, | |
| 1506 | + 'plugin' | |
| 1507 | + ); | |
| 1508 | + } | |
| 1509 | + } | |
| 1510 | + | |
| 1511 | + private function displayDynamicScript(array $jsOptions, string $suffix, string $updateFunction, string $dynamicIdentifier, string $type, $defaultValues): void | |
| 1512 | + { | |
| 1454 | 1513 | $storageVar = 'window._additionalInfo'.$suffix; |
| 1455 | 1514 | |
| 1456 | 1515 | echo '<script type="text/javascript">'; |
| 1457 | 1516 | echo 'var _selectedRows'.esc_attr($suffix).' = [];'; |
| @@ -1488,9 +1547,11 @@ | ||
| 1488 | 1547 | echo '}'; |
| 1489 | 1548 | |
| 1490 | 1549 | echo 'function '.esc_attr($updateFunction).'(){'; |
| 1491 | 1550 | echo 'var tag = ""; var otherinfo = "";'; |
| 1492 | - echo implode("\r\n\r\n", $jsOptionsMerge); | |
| 1551 | + foreach ($jsOptions as $option) { | |
| 1552 | + $this->echoOptionJs($option, $suffix, $type); | |
| 1553 | + } | |
| 1493 | 1554 | echo 'for (let [index, info] of Object.entries('.esc_attr($storageVar).')){ otherinfo += "| "+index+":"+info; }'; |
| 1494 | 1555 | |
| 1495 | 1556 | if ($type === 'individual') { |
| 1496 | 1557 | echo 'for(var i in _selectedRows'.esc_attr($suffix).'){'; |
| @@ -1594,11 +1655,12 @@ | ||
| 1594 | 1655 | |
| 1595 | 1656 | $language = acym_getVar('string', 'language', 'main'); |
| 1596 | 1657 | if (!empty($language)) { |
| 1597 | 1658 | if ($language === 'main') { |
| 1598 | - $language = $this->config->get('multilingual_default', ACYM_DEFAULT_LANGUAGE); | |
| 1659 | + $language = acym_getDefaultNewsletterLanguage(); | |
| 1599 | 1660 | } |
| 1600 | 1661 | $email->links_language = $language; |
| 1662 | + $email->language = $language; | |
| 1601 | 1663 | } |
| 1602 | 1664 | |
| 1603 | 1665 | $email->creation_date = acym_date('now', 'Y-m-d H:i:s', false); |
| 1604 | 1666 | $email->creator_id = acym_currentUserId(); |