PluginProbe
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress / 11.0.1
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress v11.0.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
acymailing / back / Helpers / EditorHelper.php

EditorHelper.php in AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress 11.0.1, at back/Helpers/EditorHelper.php

415 lines 15.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace AcyMailing\Helpers;
4
5 use AcyMailing\Classes\MailClass;
6 use AcyMailing\Classes\ZoneClass;
7 use AcyMailing\Core\AcymObject;
8 use AcyMailing\Types\DtextType;
9 use Joomla\CMS\Editor\Editor as Editor;
10 use Joomla\CMS\Factory;
11
12 class EditorHelper extends AcymObject
13 {
14 private string $width = '95%';
15 private string $height = '600';
16
17 private int $cols = 100;
18 private int $rows = 30;
19
20 private $myEditor;
21 public string $editor = '';
22
23 private string $editorContent = '';
24 private array $editorConfig = [];
25 private array $emailsTest;
26 private string $name = 'editor_content';
27
28 public string $settings = 'editor_settings';
29 public string $stylesheet = 'editor_stylesheet';
30 public string $content = '';
31 public int $mailId = 0;
32 public bool $automation = false;
33 public bool $walkThrough = false;
34
35 // Used in the d&d
36 public array $data = [];
37 private string $defaultTemplate = '';
38
39 public string $autoSave;
40
41 public function display(): void
42 {
43 if ($this->isDragAndDrop()) {
44 ob_start();
45 include acym_getPartial('editor', 'default_template');
46 $this->defaultTemplate = ob_get_clean();
47
48 acym_disableCmsEditor();
49 $currentEmail = acym_currentUserEmail();
50 $this->emailsTest = [$currentEmail => $currentEmail];
51 acym_addScript(false, ACYM_JS.'tinymce/tinymce.min.js?v='.filemtime(ACYM_MEDIA.'js'.DS.'tinymce/tinymce.min.js'));
52
53 $data = $this->data;
54 $mailId = empty($data['mail']->mail_id) ? (empty($data['mail']->id) ? 0 : $data['mail']->id) : $data['mail']->mail_id;
55 $data['tabHelper'] = new TabHelper();
56 $data['plugins'] = acym_trigger('dynamicText', [$mailId]);
57 usort(
58 $data['plugins'],
59 function ($a, $b) {
60 return strtolower($a->name ?? '') > strtolower($b->name ?? '') ? 1 : -1;
61 }
62 );
63
64 $zoneClass = new ZoneClass();
65 $data['custom_zones'] = $zoneClass->getAll();
66 usort($data['custom_zones'], function ($a, $b) {
67 return strtolower($a->name) > strtolower($b->name) ? 1 : -1;
68 });
69
70 acym_setVar('mail_id', $mailId);
71 acym_setVar('mail_type', empty($data['mail']->type) ? '' : $data['mail']->type);
72 acym_setVar('automation', $this->automation ? 1 : 0);
73
74 include acym_getPartial('editor', 'editor_wysid');
75 } else {
76 // Outside of the Acy wrapper to prevent foundation from breaking the 100 different editors we could have here
77
78 // Close acym_content div
79 if (acym_isLeftMenuNecessary()) echo '</div>';
80
81 // Close acym_wrapper div and open the no foundation div
82 echo '</div><div class="acym_no_foundation">';
83
84 // Display the editor
85 $dtextType = new DtextType();
86 $dtextType->display(['withButton' => false]);
87
88 $method = 'displayWordPress';
89 $this->$method();
90
91 // The view renderer will close the acym_content div, but since we already closed it, we open a fake one
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
94 }
95 }
96
97 public function isDragAndDrop(): bool
98 {
99 return strpos($this->content, 'acym__wysid__template') !== false || $this->editor === 'acyEditor';
100 }
101
102 private function displayJoomla(): void
103 {
104 $dtextType = new DtextType();
105 $dtextType->displayButton(
106 [
107 'icon' => 'acymicon-chevrons',
108 'text' => acym_translation('ACYM_INSERT_DYNAMIC_TEXT'),
109 'class' => 'button button-secondary margin-bottom-0 margin-top-1',
110 ]
111 );
112
113 $this->editor = acym_getCMSConfig('editor', 'tinymce');
114
115 if (!class_exists('Joomla\CMS\Editor\Editor')) {
116 $this->myEditor = Factory::getEditor($this->editor);
117 } else {
118 $this->myEditor = Editor::getInstance($this->editor);
119 }
120 $this->myEditor->initialise();
121
122 // We allow the background parameter on tr,table and td.
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]';
124
125 if (!empty($this->mailId)) {
126 //Load Css editor
127 $cssurl = acym_completeLink((acym_isAdmin() ? '' : 'front').'mails&task=loadCSS&id='.$this->mailId.'&time='.time());
128 $classMail = new MailClass();
129 $filepath = $classMail->createTemplateFile($this->mailId);
130
131 if ($this->editor === 'tinymce') {
132 $this->editorConfig['content_css_custom'] = $cssurl.'&local=http';
133 $this->editorConfig['content_css'] = '0';
134
135 // We disable this for Joomla 4 because it might do a fatal due to Joomla 4 TinyMCE params not well formatted
136 if (!ACYM_J40) {
137 // Joomla broke the custom css feature in the v3.9.21 so we have to do this
138 $access = [];
139 for ($i = 1; $i < 20; $i++) {
140 $access[] = $i;
141 }
142
143 $this->editorConfig['configuration'] = (object)[
144 'toolbars' => (object)['AcyCustomCSS' => []],
145 'setoptions' => [
146 'AcyCustomCSS' => (object)[
147 'access' => $access,
148 'content_css' => '0',
149 'content_css_custom' => $cssurl.'&local=http',
150 ],
151 ],
152 ];
153 }
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
156 $this->editorConfig['content_css_custom'] = $filepath;
157 $this->editorConfig['content_css'] = '0';
158 $this->editorConfig['editor_css'] = '0';
159 } else {
160 //We still create the file so that the user can link to it manually
161 $fileurl = str_replace(DS, '/', ACYM_MEDIA_FOLDER).'templates/css/template_'.$this->mailId.'.css?time='.time();
162 $this->editorConfig['custom_css_url'] = $cssurl;
163 $this->editorConfig['custom_css_file'] = $fileurl;
164 $this->editorConfig['custom_css_path'] = $filepath;
165 //Can be useful for JCE integration for example.
166 acym_setVar('acycssfile', $fileurl);
167 }
168 }
169
170 // phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped -- Displaying the CMS editor, cannot be escaped. For Joomla editors.
171 if (empty($this->editorContent)) {
172 $this->content = esc_html($this->content);
173 ob_start();
174
175 echo $this->myEditor->display(
176 $this->name,
177 $this->content,
178 $this->width,
179 $this->height,
180 $this->cols,
181 $this->rows,
182 ['pagebreak', 'readmore'],
183 null,
184 'com_content',
185 null,
186 $this->editorConfig
187 );
188
189 $this->editorContent = ob_get_clean();
190 }
191
192 if (method_exists($this->myEditor, 'save')) {
193 acym_addScript(true, 'function acyOnSaveEditor(){'.$this->myEditor->save($this->name).'}');
194 }
195
196 echo $this->editorContent;
197 // phpcs:enable WordPress.Security.EscapeOutput.OutputNotEscaped
198 }
199
200 private function displayWordPress(): void
201 {
202 add_filter('mce_external_plugins', [$this, 'addPlugins']);
203 add_filter('mce_buttons', [$this, 'addButtons']);
204 add_filter('mce_buttons_2', [$this, 'addButtonsToolbar']);
205 add_action('media_buttons', [$this, 'addDtextButton']);
206
207 $mailClass = new MailClass();
208
209 $mail = $mailClass->getOneById($this->mailId);
210 $stylesheet = empty($mail) ? '' : trim(preg_replace('/\s\s+/', ' ', $mailClass->buildCSS($mail->stylesheet)));
211 $stylesheet = str_replace(['"', "\r\n", "\n"], ['\"', '', ''], $stylesheet);
212
213 $options = [
214 'editor_css' => '<style type="text/css">
215 .alignleft{float:left;margin:0.5em 1em 0.5em 0;}
216 .aligncenter{display: block;margin-left: auto;margin-right: auto;}
217 .alignright{float: right;margin: 0.5em 0 0.5em 1em;}
218 </style>',
219 'editor_height' => $this->height,
220 'textarea_rows' => $this->rows,
221 'wpautop' => false,
222 'tinymce' => [
223 'content_css' => '',
224 'content_style' => '.alignleft{float:left;margin:0.5em 1em 0.5em 0;} .aligncenter{display: block;margin-left: auto;margin-right: auto;} .alignright{float: right;margin: 0.5em 0 0.5em 1em;}'.$stylesheet,
225 ],
226 ];
227
228 wp_editor($this->content, $this->name, $options);
229 }
230
231 public function addDtextButton(string $editor_id = 'content'): void
232 {
233 static $instance = 0;
234 ++$instance;
235
236 printf(
237 '<button type="button" class="button" id="acym__dtext__button" data-editor="%s"><i class="acymicon-chevrons"></i> %s</button>',
238 esc_attr($editor_id),
239 esc_html(acym_translation('ACYM_INSERT_DYNAMIC_TEXT'))
240 );
241 }
242
243 // Used in partial editor
244 private function getWYSIDSettings(): string
245 {
246 $ctrl = acym_getVar('string', 'ctrl');
247 if ($this->isResetCampaign() || !in_array($ctrl, ['dashboard', 'mails', 'campaigns', 'frontmails', 'frontcampaigns'])) {
248 return '{}';
249 }
250
251 $mailId = acym_getVar('int', 'from', 0);
252 if (empty($mailId)) {
253 if ($this->settings !== 'editor_settings') {
254 return $this->settings;
255 }
256
257 $mailId = acym_getVar('int', 'id');
258 $campaignId = acym_getVar('int', 'campaignId');
259 if (!empty($campaignId) && $ctrl === 'campaigns') {
260 $mailId = acym_loadResult('SELECT mail_id FROM #__acym_campaign WHERE id = '.intval($campaignId));
261 }
262
263 if (empty($mailId)) {
264 return '{}';
265 }
266 }
267
268 $settings = acym_loadResult('SELECT settings FROM #__acym_mail WHERE id = '.intval($mailId));
269
270 return empty($settings) ? '{}' : $settings;
271 }
272
273 // Used in partial editor
274 private function getWYSIDStylesheet(): string
275 {
276 $ctrl = acym_getVar('string', 'ctrl');
277 if ($this->isResetCampaign() || !in_array($ctrl, ['mails', 'campaigns', 'frontmails', 'frontcampaigns'])) {
278 return '';
279 }
280
281 $mailId = acym_getVar('int', 'from', 0);
282 if (empty($mailId)) {
283 if ($this->stylesheet !== 'editor_stylesheet') {
284 return $this->stylesheet;
285 }
286
287 $mailId = acym_getVar('int', 'id');
288 $campaignId = acym_getVar('int', 'campaignId');
289 if (!empty($campaignId) && in_array($ctrl, ['campaigns', 'frontcampaigns'])) {
290 $mailId = acym_loadResult('SELECT mail_id FROM #__acym_campaign WHERE id = '.intval($campaignId));
291 }
292 }
293
294 $notification = acym_getVar('string', 'notification');
295 if (!empty($mailId)) {
296 $stylesheet = acym_loadResult('SELECT stylesheet FROM #__acym_mail WHERE id = '.intval($mailId));
297 } elseif (!empty($notification)) {
298 $stylesheet = acym_loadResult(
299 'SELECT stylesheet
300 FROM #__acym_mail
301 WHERE `type` = '.acym_escapeDB(MailClass::TYPE_NOTIFICATION).'
302 AND `name` = '.acym_escapeDB($notification)
303 );
304 }
305
306 return empty($stylesheet) ? '' : $stylesheet;
307 }
308
309 private function isResetCampaign(): bool
310 {
311 $fromId = acym_getVar('int', 'from', 0);
312
313 return -1 === $fromId;
314 }
315
316 /**
317 * Methods used to add buttons to the WordPress editor
318 */
319 private function addButtonAtPosition(array &$buttons, string $newButton, string $after): void
320 {
321 $position = array_search($after, $buttons);
322
323 if ($position === false) {
324 array_push($buttons, 'separator', $newButton);
325 } else {
326 array_splice($buttons, $position + 1, 0, $newButton);
327 }
328 }
329
330 public function addPlugins(array $plugins): array
331 {
332 $plugins['table'] = ACYM_JS.'tinymce/table.min.js';
333
334 return $plugins;
335 }
336
337 public function addButtons(array $buttons): array
338 {
339 $position = array_search('wp_more', $buttons);
340 if ($position !== false) {
341 $buttons[$position] = '';
342 }
343
344 array_unshift($buttons, 'separator', 'fontsizeselect');
345 array_unshift($buttons, 'separator', 'fontselect');
346 array_push($buttons, 'separator', 'table');
347
348 $this->addButtonAtPosition($buttons, 'alignjustify', 'alignright');
349 $this->addButtonAtPosition($buttons, 'underline', 'italic');
350 $this->addButtonAtPosition($buttons, 'strikethrough', 'underline');
351
352 return $buttons;
353 }
354
355 public function addButtonsToolbar(array $buttons): array
356 {
357 $position = array_search('strikethrough', $buttons);
358 if ($position !== false) {
359 $buttons[$position] = '';
360 }
361 $this->addButtonAtPosition($buttons, 'backcolor', 'forecolor');
362
363 return $buttons;
364 }
365
366 public function getSettingsStyle($settings): string
367 {
368 if (empty($settings)) {
369 return '';
370 }
371
372 if (is_string($settings) && substr($settings, 0, 2) === '{"') {
373 $settings = json_decode($settings, true);
374 }
375
376 if (!is_array($settings)) {
377 return '';
378 }
379
380 $styles = '';
381 foreach ($settings as $element => $rules) {
382 $values = '';
383 foreach ($rules as $ruleName => $value) {
384 if ($ruleName == 'overridden') continue;
385 $values .= $ruleName.': '.$value.';';
386 }
387 $styles .= '#acym__wysid__template .acym__wysid__column__element__td .acym__wysid__tinymce--text '.$element.':not(.acym__wysid__content-no-settings-style){';
388 $styles .= $values;
389 $styles .= '}';
390
391 $styles .= '#acym__wysid__template .acym__wysid__column__element__td .acymailing_content '.$element.':not(.acym__wysid__content-no-settings-style){';
392 $styles .= $values;
393 $styles .= '}';
394 }
395
396 return $styles;
397 }
398
399 private function getDefaultColors(): string
400 {
401 $mailSettings = new \stdClass();
402 if (isset($this->data['mail']->mail_settings) && !empty($this->data['mail']->mail_settings)) {
403 $mailSettings = json_decode($this->data['mail']->mail_settings, false);
404 } elseif (isset($this->data['mailInformation']->mail_settings) && !empty($this->data['mailInformation']->mail_settings)) {
405 $mailSettings = json_decode($this->data['mailInformation']->mail_settings, false);
406 }
407
408 if (!empty($mailSettings->mainColors)) {
409 return $mailSettings->mainColors;
410 }
411
412 return '';
413 }
414 }
415