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

418 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
166 // Can be useful for JCE integration for example
167 if (!empty($filepath)) {
168 acym_setVar('acycssfile', $fileurl);
169 }
170 }
171 }
172
173 // phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped -- Displaying the CMS editor, cannot be escaped. For Joomla editors.
174 if (empty($this->editorContent)) {
175 $this->content = esc_html($this->content);
176 ob_start();
177
178 echo $this->myEditor->display(
179 $this->name,
180 $this->content,
181 $this->width,
182 $this->height,
183 $this->cols,
184 $this->rows,
185 ['pagebreak', 'readmore'],
186 null,
187 'com_content',
188 null,
189 $this->editorConfig
190 );
191
192 $this->editorContent = ob_get_clean();
193 }
194
195 if (method_exists($this->myEditor, 'save')) {
196 acym_addScript(true, 'function acyOnSaveEditor(){'.$this->myEditor->save($this->name).'}');
197 }
198
199 echo $this->editorContent;
200 // phpcs:enable WordPress.Security.EscapeOutput.OutputNotEscaped
201 }
202
203 private function displayWordPress(): void
204 {
205 add_filter('mce_external_plugins', [$this, 'addPlugins']);
206 add_filter('mce_buttons', [$this, 'addButtons']);
207 add_filter('mce_buttons_2', [$this, 'addButtonsToolbar']);
208 add_action('media_buttons', [$this, 'addDtextButton']);
209
210 $mailClass = new MailClass();
211
212 $mail = $mailClass->getOneById($this->mailId);
213 $stylesheet = empty($mail) ? '' : trim(preg_replace('/\s\s+/', ' ', $mailClass->buildCSS($mail->stylesheet)));
214 $stylesheet = str_replace(['"', "\r\n", "\n"], ['\"', '', ''], $stylesheet);
215
216 $options = [
217 'editor_css' => '<style type="text/css">
218 .alignleft{float:left;margin:0.5em 1em 0.5em 0;}
219 .aligncenter{display: block;margin-left: auto;margin-right: auto;}
220 .alignright{float: right;margin: 0.5em 0 0.5em 1em;}
221 </style>',
222 'editor_height' => $this->height,
223 'textarea_rows' => $this->rows,
224 'wpautop' => false,
225 'tinymce' => [
226 'content_css' => '',
227 '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,
228 ],
229 ];
230
231 wp_editor($this->content, $this->name, $options);
232 }
233
234 public function addDtextButton(string $editor_id = 'content'): void
235 {
236 static $instance = 0;
237 ++$instance;
238
239 printf(
240 '<button type="button" class="button" id="acym__dtext__button" data-editor="%s"><i class="acymicon-chevrons"></i> %s</button>',
241 esc_attr($editor_id),
242 esc_html(acym_translation('ACYM_INSERT_DYNAMIC_TEXT'))
243 );
244 }
245
246 // Used in partial editor
247 private function getWYSIDSettings(): string
248 {
249 $ctrl = acym_getVar('string', 'ctrl');
250 if ($this->isResetCampaign() || !in_array($ctrl, ['dashboard', 'mails', 'campaigns', 'frontmails', 'frontcampaigns'])) {
251 return '{}';
252 }
253
254 $mailId = acym_getVar('int', 'from', 0);
255 if (empty($mailId)) {
256 if ($this->settings !== 'editor_settings') {
257 return $this->settings;
258 }
259
260 $mailId = acym_getVar('int', 'id');
261 $campaignId = acym_getVar('int', 'campaignId');
262 if (!empty($campaignId) && $ctrl === 'campaigns') {
263 $mailId = acym_loadResult('SELECT mail_id FROM #__acym_campaign WHERE id = '.intval($campaignId));
264 }
265
266 if (empty($mailId)) {
267 return '{}';
268 }
269 }
270
271 $settings = acym_loadResult('SELECT settings FROM #__acym_mail WHERE id = '.intval($mailId));
272
273 return empty($settings) ? '{}' : $settings;
274 }
275
276 // Used in partial editor
277 private function getWYSIDStylesheet(): string
278 {
279 $ctrl = acym_getVar('string', 'ctrl');
280 if ($this->isResetCampaign() || !in_array($ctrl, ['mails', 'campaigns', 'frontmails', 'frontcampaigns'])) {
281 return '';
282 }
283
284 $mailId = acym_getVar('int', 'from', 0);
285 if (empty($mailId)) {
286 if ($this->stylesheet !== 'editor_stylesheet') {
287 return $this->stylesheet;
288 }
289
290 $mailId = acym_getVar('int', 'id');
291 $campaignId = acym_getVar('int', 'campaignId');
292 if (!empty($campaignId) && in_array($ctrl, ['campaigns', 'frontcampaigns'])) {
293 $mailId = acym_loadResult('SELECT mail_id FROM #__acym_campaign WHERE id = '.intval($campaignId));
294 }
295 }
296
297 $notification = acym_getVar('string', 'notification');
298 if (!empty($mailId)) {
299 $stylesheet = acym_loadResult('SELECT stylesheet FROM #__acym_mail WHERE id = '.intval($mailId));
300 } elseif (!empty($notification)) {
301 $stylesheet = acym_loadResult(
302 'SELECT stylesheet
303 FROM #__acym_mail
304 WHERE `type` = '.acym_escapeDB(MailClass::TYPE_NOTIFICATION).'
305 AND `name` = '.acym_escapeDB($notification)
306 );
307 }
308
309 return empty($stylesheet) ? '' : $stylesheet;
310 }
311
312 private function isResetCampaign(): bool
313 {
314 $fromId = acym_getVar('int', 'from', 0);
315
316 return -1 === $fromId;
317 }
318
319 /**
320 * Methods used to add buttons to the WordPress editor
321 */
322 private function addButtonAtPosition(array &$buttons, string $newButton, string $after): void
323 {
324 $position = array_search($after, $buttons);
325
326 if ($position === false) {
327 array_push($buttons, 'separator', $newButton);
328 } else {
329 array_splice($buttons, $position + 1, 0, $newButton);
330 }
331 }
332
333 public function addPlugins(array $plugins): array
334 {
335 $plugins['table'] = ACYM_JS.'tinymce/table.min.js';
336
337 return $plugins;
338 }
339
340 public function addButtons(array $buttons): array
341 {
342 $position = array_search('wp_more', $buttons);
343 if ($position !== false) {
344 $buttons[$position] = '';
345 }
346
347 array_unshift($buttons, 'separator', 'fontsizeselect');
348 array_unshift($buttons, 'separator', 'fontselect');
349 array_push($buttons, 'separator', 'table');
350
351 $this->addButtonAtPosition($buttons, 'alignjustify', 'alignright');
352 $this->addButtonAtPosition($buttons, 'underline', 'italic');
353 $this->addButtonAtPosition($buttons, 'strikethrough', 'underline');
354
355 return $buttons;
356 }
357
358 public function addButtonsToolbar(array $buttons): array
359 {
360 $position = array_search('strikethrough', $buttons);
361 if ($position !== false) {
362 $buttons[$position] = '';
363 }
364 $this->addButtonAtPosition($buttons, 'backcolor', 'forecolor');
365
366 return $buttons;
367 }
368
369 public function getSettingsStyle($settings): string
370 {
371 if (empty($settings)) {
372 return '';
373 }
374
375 if (is_string($settings) && substr($settings, 0, 2) === '{"') {
376 $settings = json_decode($settings, true);
377 }
378
379 if (!is_array($settings)) {
380 return '';
381 }
382
383 $styles = '';
384 foreach ($settings as $element => $rules) {
385 $values = '';
386 foreach ($rules as $ruleName => $value) {
387 if ($ruleName == 'overridden') continue;
388 $values .= $ruleName.': '.$value.';';
389 }
390 $styles .= '#acym__wysid__template .acym__wysid__column__element__td .acym__wysid__tinymce--text '.$element.':not(.acym__wysid__content-no-settings-style){';
391 $styles .= $values;
392 $styles .= '}';
393
394 $styles .= '#acym__wysid__template .acym__wysid__column__element__td .acymailing_content '.$element.':not(.acym__wysid__content-no-settings-style){';
395 $styles .= $values;
396 $styles .= '}';
397 }
398
399 return $styles;
400 }
401
402 private function getDefaultColors(): string
403 {
404 $mailSettings = new \stdClass();
405 if (isset($this->data['mail']->mail_settings) && !empty($this->data['mail']->mail_settings)) {
406 $mailSettings = json_decode($this->data['mail']->mail_settings, false);
407 } elseif (isset($this->data['mailInformation']->mail_settings) && !empty($this->data['mailInformation']->mail_settings)) {
408 $mailSettings = json_decode($this->data['mailInformation']->mail_settings, false);
409 }
410
411 if (!empty($mailSettings->mainColors)) {
412 return $mailSettings->mainColors;
413 }
414
415 return '';
416 }
417 }
418