| @@ -31,8 +31,9 @@ | ||
| 31 | 31 | public int $mailId = 0; |
| 32 | 32 | public bool $automation = false; |
| 33 | 33 | public bool $walkThrough = false; |
| 34 | 34 | |
| 35 | + // Used in the d&d | |
| 35 | 36 | public array $data = []; |
| 36 | 37 | private string $defaultTemplate = ''; |
| 37 | 38 | |
| 38 | 39 | public string $autoSave; |
| @@ -71,13 +72,17 @@ | ||
| 71 | 72 | acym_setVar('automation', $this->automation ? 1 : 0); |
| 72 | 73 | |
| 73 | 74 | include acym_getPartial('editor', 'editor_wysid'); |
| 74 | 75 | } else { |
| 76 | + // Outside of the Acy wrapper to prevent foundation from breaking the 100 different editors we could have here | |
| 75 | 77 | |
| 78 | + // Close acym_content div | |
| 76 | 79 | if (acym_isLeftMenuNecessary()) echo '</div>'; |
| 77 | 80 | |
| 81 | + // Close acym_wrapper div and open the no foundation div | |
| 78 | 82 | echo '</div><div class="acym_no_foundation">'; |
| 79 | 83 | |
| 84 | + // Display the editor | |
| 80 | 85 | $dtextType = new DtextType(); |
| 81 | 86 | $dtextType->display(['withButton' => false]); |
| 82 | 87 | |
| 83 | 88 | $method = 'displayWordPress'; |
| @@ -82,9 +87,11 @@ | ||
| 82 | 87 | |
| 83 | 88 | $method = 'displayWordPress'; |
| 84 | 89 | $this->$method(); |
| 85 | 90 | |
| 91 | + // The view renderer will close the acym_content div, but since we already closed it, we open a fake one | |
| 86 | 92 | if (acym_isLeftMenuNecessary()) echo '<div>'; |
| 93 | + // The view renderer will close the acym_wrapper div, which will be the acym_no_foundation div in this case | |
| 87 | 94 | } |
| 88 | 95 | } |
| 89 | 96 | |
| 90 | 97 | public function isDragAndDrop(): bool |
| @@ -111,11 +118,13 @@ | ||
| 111 | 118 | $this->myEditor = Editor::getInstance($this->editor); |
| 112 | 119 | } |
| 113 | 120 | $this->myEditor->initialise(); |
| 114 | 121 | |
| 122 | + // We allow the background parameter on tr,table and td. | |
| 115 | 123 | $this->editorConfig['extended_elements'] = 'table[background|cellspacing|cellpadding|width|align|bgcolor|border|style|class|id],tr[background|width|bgcolor|style|class|id|valign],td[background|width|align|bgcolor|valign|colspan|rowspan|height|style|class|id|nowrap]'; |
| 116 | 124 | |
| 117 | 125 | if (!empty($this->mailId)) { |
| 126 | + //Load Css editor | |
| 118 | 127 | $cssurl = acym_completeLink((acym_isAdmin() ? '' : 'front').'mails&task=loadCSS&id='.$this->mailId.'&time='.time()); |
| 119 | 128 | $classMail = new MailClass(); |
| 120 | 129 | $filepath = $classMail->createTemplateFile($this->mailId); |
| 121 | 130 | |
| @@ -122,11 +131,13 @@ | ||
| 122 | 131 | if ($this->editor === 'tinymce') { |
| 123 | 132 | $this->editorConfig['content_css_custom'] = $cssurl.'&local=http'; |
| 124 | 133 | $this->editorConfig['content_css'] = '0'; |
| 125 | 134 | |
| 135 | + // We disable this for Joomla 4 because it might do a fatal due to Joomla 4 TinyMCE params not well formatted | |
| 126 | 136 | if (!ACYM_J40) { |
| 137 | + // Joomla broke the custom css feature in the v3.9.21 so we have to do this | |
| 127 | 138 | $access = []; |
| 128 | - for ($i = 1 ; $i < 20 ; $i++) { | |
| 139 | + for ($i = 1; $i < 20; $i++) { | |
| 129 | 140 | $access[] = $i; |
| 130 | 141 | } |
| 131 | 142 | |
| 132 | 143 | $this->editorConfig['configuration'] = (object)[ |
| @@ -140,22 +151,29 @@ | ||
| 140 | 151 | ], |
| 141 | 152 | ]; |
| 142 | 153 | } |
| 143 | 154 | } elseif ($this->editor === 'jckeditor' || $this->editor === 'fckeditor') { |
| 155 | + //For jckeditor, we need to create a fake template.css file... lets do that on the template/css/folder | |
| 144 | 156 | $this->editorConfig['content_css_custom'] = $filepath; |
| 145 | 157 | $this->editorConfig['content_css'] = '0'; |
| 146 | 158 | $this->editorConfig['editor_css'] = '0'; |
| 147 | 159 | } else { |
| 160 | + //We still create the file so that the user can link to it manually | |
| 148 | 161 | $fileurl = str_replace(DS, '/', ACYM_MEDIA_FOLDER).'templates/css/template_'.$this->mailId.'.css?time='.time(); |
| 149 | 162 | $this->editorConfig['custom_css_url'] = $cssurl; |
| 150 | 163 | $this->editorConfig['custom_css_file'] = $fileurl; |
| 151 | 164 | $this->editorConfig['custom_css_path'] = $filepath; |
| 152 | - acym_setVar('acycssfile', $fileurl); | |
| 165 | + | |
| 166 | + // Can be useful for JCE integration for example | |
| 167 | + if (!empty($filepath)) { | |
| 168 | + acym_setVar('acycssfile', $fileurl); | |
| 169 | + } | |
| 153 | 170 | } |
| 154 | 171 | } |
| 155 | 172 | |
| 173 | + // phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped -- Displaying the CMS editor, cannot be escaped. For Joomla editors. | |
| 156 | 174 | if (empty($this->editorContent)) { |
| 157 | - $this->content = acym_escape($this->content); | |
| 175 | + $this->content = esc_html($this->content); | |
| 158 | 176 | ob_start(); |
| 159 | 177 | |
| 160 | 178 | echo $this->myEditor->display( |
| 161 | 179 | $this->name, |
| @@ -178,8 +196,9 @@ | ||
| 178 | 196 | acym_addScript(true, 'function acyOnSaveEditor(){'.$this->myEditor->save($this->name).'}'); |
| 179 | 197 | } |
| 180 | 198 | |
| 181 | 199 | echo $this->editorContent; |
| 200 | + // phpcs:enable WordPress.Security.EscapeOutput.OutputNotEscaped | |
| 182 | 201 | } |
| 183 | 202 | |
| 184 | 203 | private function displayWordPress(): void |
| 185 | 204 | { |
| @@ -216,17 +235,16 @@ | ||
| 216 | 235 | { |
| 217 | 236 | static $instance = 0; |
| 218 | 237 | ++$instance; |
| 219 | 238 | |
| 220 | - $img = '<i class="acymicon-chevrons"></i> '; | |
| 221 | - | |
| 222 | 239 | printf( |
| 223 | - '<button type="button" class="button" id="acym__dtext__button" data-editor="%s">%s</button>', | |
| 240 | + '<button type="button" class="button" id="acym__dtext__button" data-editor="%s"><i class="acymicon-chevrons"></i> %s</button>', | |
| 224 | 241 | esc_attr($editor_id), |
| 225 | - $img.acym_translation('ACYM_INSERT_DYNAMIC_TEXT') | |
| 242 | + esc_html(acym_translation('ACYM_INSERT_DYNAMIC_TEXT')) | |
| 226 | 243 | ); |
| 227 | 244 | } |
| 228 | 245 | |
| 246 | + // Used in partial editor | |
| 229 | 247 | private function getWYSIDSettings(): string |
| 230 | 248 | { |
| 231 | 249 | $ctrl = acym_getVar('string', 'ctrl'); |
| 232 | 250 | if ($this->isResetCampaign() || !in_array($ctrl, ['dashboard', 'mails', 'campaigns', 'frontmails', 'frontcampaigns'])) { |
| @@ -254,8 +272,9 @@ | ||
| 254 | 272 | |
| 255 | 273 | return empty($settings) ? '{}' : $settings; |
| 256 | 274 | } |
| 257 | 275 | |
| 276 | + // Used in partial editor | |
| 258 | 277 | private function getWYSIDStylesheet(): string |
| 259 | 278 | { |
| 260 | 279 | $ctrl = acym_getVar('string', 'ctrl'); |
| 261 | 280 | if ($this->isResetCampaign() || !in_array($ctrl, ['mails', 'campaigns', 'frontmails', 'frontcampaigns'])) { |
| @@ -296,8 +315,11 @@ | ||
| 296 | 315 | |
| 297 | 316 | return -1 === $fromId; |
| 298 | 317 | } |
| 299 | 318 | |
| 319 | + /** | |
| 320 | + * Methods used to add buttons to the WordPress editor | |
| 321 | + */ | |
| 300 | 322 | private function addButtonAtPosition(array &$buttons, string $newButton, string $after): void |
| 301 | 323 | { |
| 302 | 324 | $position = array_search($after, $buttons); |
| 303 | 325 | |