PluginProbe ʕ •ᴥ•ʔ
Advanced Editor Tools / 5.9.2
Advanced Editor Tools v5.9.2
trunk 1.0 1.0.1 2.0 2.2 3.0 3.0.1 3.1 3.2 3.2.4 3.2.7 3.3.9 3.3.9.1 3.3.9.2 3.4.2 3.4.2.1 3.4.5 3.4.5.1 3.4.9 3.5.8 3.5.9 3.5.9.1 4.0 4.0.1 4.0.2 4.1 4.1.1 4.1.7 4.1.9 4.2.3 4.2.3.1 4.2.5 4.2.8 4.3.10 4.3.10.1 4.3.8 4.4.1 4.4.3 4.5.6 4.6.3 4.6.7 4.7.11 4.8.0 4.8.1 4.8.2 5.0.0 5.0.1 5.1.0 5.2 5.2.1 5.3 5.4.0 5.5.0 5.5.1 5.6.0 5.9.0 5.9.1 5.9.2
tinymce-advanced / tinymce-advanced.php
tinymce-advanced Last commit date
block-editor 3 years ago mce 3 years ago plugin-assets 3 years ago readme.txt 5 months ago tadv_admin.php 3 years ago tinymce-advanced.php 2 years ago uninstall.php 5 years ago
tinymce-advanced.php
1182 lines
1 <?php
2 /*
3 Plugin Name: Advanced Editor Tools
4 Plugin URI: https://wordpress.org/plugins/tinymce-advanced/
5 Description: Extends and enhances the block editor (Gutenberg) and the classic editor (TinyMCE).
6 Version: 5.9.2
7 Requires at least: 5.9
8 Requires PHP: 5.6
9 Author: Automattic
10 Author URI: https://automattic.com
11 License: GPL2
12 License URI: https://www.gnu.org/licenses/gpl-2.0.html
13 Text Domain: tinymce-advanced
14
15
16 Advanced Editor Tools (previously TinyMCE Advanced) is free software: you can
17 redistribute it and/or modifyit under the terms of the GNU General Public License
18 as published bythe Free Software Foundation, either version 2 of the License, or
19 any later version.
20
21 Advanced Editor Tools is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU General Public License for more details.
25
26 You should have received a copy of the GNU General Public License along
27 with Advanced Editor Tools or WordPress. If not, see https://www.gnu.org/licenses/gpl-2.0.html.
28
29 Copyright (c) 2007-2023 Automattic, Inc. All rights reserved.
30 */
31
32 /**
33 * Main plugin file.
34 * @package advanced-editor-tools
35 */
36
37 if ( ! defined( 'ABSPATH' ) ) {
38 exit;
39 }
40
41 if ( ! class_exists( 'Advanced_Editor_Tools' ) ) :
42
43 class Advanced_Editor_Tools {
44
45 private $required_wp_version = '5.9';
46 private $plugin_version = 5900;
47
48 private $user_settings;
49 private $admin_settings;
50 private $admin_options;
51 private $editor_id;
52 private $disabled_for_editor = false;
53
54 private $plugins;
55 private $options;
56 private $toolbar_1;
57 private $toolbar_2;
58 private $toolbar_3;
59 private $toolbar_4;
60 private $used_buttons = array();
61 private $all_buttons = array();
62 private $buttons_filter = array();
63 private $toolbar_classic_block = array();
64 private $fontsize_formats = '8px 10px 12px 14px 16px 20px 24px 28px 32px 36px 48px 60px 72px 96px';
65
66 private $required_menubar_plugins = array(
67 'anchor',
68 'code',
69 'insertdatetime',
70 'nonbreaking',
71 'print',
72 'searchreplace',
73 'table',
74 'visualblocks',
75 'visualchars'
76 );
77
78 private function get_default_user_settings() {
79 return array(
80 'options' => 'menubar,advlist,menubar_block,merge_toolbars',
81 'plugins' => 'anchor,code,insertdatetime,nonbreaking,print,searchreplace,table,visualblocks,visualchars,advlist,wptadv',
82 'toolbar_1' => 'formatselect,bold,italic,blockquote,bullist,numlist,alignleft,aligncenter,alignright,link,unlink,undo,redo',
83 'toolbar_2' => 'fontselect,fontsizeselect,outdent,indent,pastetext,removeformat,charmap,wp_more,forecolor,table,wp_help',
84 'toolbar_3' => '',
85 'toolbar_4' => '',
86
87 'toolbar_classic_block' => 'formatselect,bold,italic,blockquote,bullist,numlist,alignleft,aligncenter,alignright,' .
88 'link,forecolor,backcolor,table,wp_help',
89 );
90 }
91
92 private function get_default_admin_settings() {
93 return array(
94 'options' => 'classic_paragraph_block,table_resize_bars,table_grid,table_tab_navigation,table_advtab',
95 );
96 }
97
98 private function get_all_plugins() {
99 return array(
100 'advlist',
101 'anchor',
102 'code',
103 'contextmenu',
104 'emoticons',
105 'importcss',
106 'insertdatetime',
107 'link',
108 'nonbreaking',
109 'print',
110 'searchreplace',
111 'table',
112 'visualblocks',
113 'visualchars',
114 'wptadv',
115 );
116 }
117
118 // Options are only "boolean"", array element exists or not.
119 private function get_all_user_options() {
120 return array(
121 'advlist',
122 'advlink',
123 'contextmenu',
124 'menubar',
125 'menubar_block',
126 'fontsize_formats',
127 'merge_toolbars',
128 'disable_richtext_buttons',
129 );
130 }
131
132 private function get_all_admin_options() {
133 return array(
134 'importcss',
135 'no_autop',
136 'hybrid_mode',
137 'classic_paragraph_block',
138 'replace_block_editor',
139 'table_resize_bars',
140 'table_default_attributes',
141 'table_grid',
142 'table_tab_navigation',
143 'table_advtab',
144 );
145 }
146
147 private function get_editor_locations() {
148 return array(
149 'edit_post_screen',
150 'rest_of_wpadmin',
151 'on_front_end',
152 );
153 }
154
155 public function __construct() {
156 if ( is_admin() ) {
157 add_action( 'admin_menu', array( $this, 'add_menu' ) );
158 add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
159 add_action( 'plugins_loaded', array( $this, 'load_textdomain' ) );
160 add_filter( 'plugin_action_links', array( $this, 'add_settings_link' ), 10, 2 );
161 add_action( 'before_wp_tiny_mce', array( $this, 'show_version_warning' ) );
162
163 add_action( 'admin_init', array( $this, 'import_export_settings_file' ) );
164 add_action( 'plugins_loaded', array( $this, 'update_settings' ) );
165 }
166
167 add_filter( 'wp_editor_settings', array( $this, 'disable_for_editor' ), 10, 2 );
168
169 add_filter( 'mce_buttons', array( $this, 'mce_buttons_1' ), 999, 2 );
170 add_filter( 'mce_buttons_2', array( $this, 'mce_buttons_2' ), 999, 2 );
171 add_filter( 'mce_buttons_3', array( $this, 'mce_buttons_3' ), 999, 2 );
172 add_filter( 'mce_buttons_4', array( $this, 'mce_buttons_4' ), 999, 2 );
173
174 add_filter( 'tiny_mce_before_init', array( $this, 'mce_options' ), 10, 2 );
175 add_filter( 'mce_external_plugins', array( $this, 'mce_external_plugins' ), 999 );
176 add_filter( 'tiny_mce_plugins', array( $this, 'tiny_mce_plugins' ), 999 );
177
178 add_action( 'enqueue_block_editor_assets', array( $this, 'block_editor_assets' ), 20 );
179 add_action( 'init', array( $this, 'block_editor_init' ) );
180 add_filter( 'wp_insert_post_data', array( $this, 'filter_post_content' ), 1 );
181
182 add_filter( 'excerpt_allowed_blocks', array( $this, 'excerpt_add_allowed_blocks' ) );
183 }
184
185 public function disable_for_editor( $settings, $editor_id ) {
186 static $editor_style_added = false;
187
188 if ( empty( $this->admin_settings ) ) {
189 $this->load_settings();
190 }
191
192 $this->disabled_for_editor = false;
193 $this->editor_id = $editor_id;
194
195 if ( ! empty( $this->admin_settings['disabled_editors'] ) ) {
196 $disabled_editors = explode( ',', $this->admin_settings['disabled_editors'] );
197 $current_screen = isset( $GLOBALS['current_screen'] ) ? $GLOBALS['current_screen'] : new stdClass;
198
199 if ( is_admin() ) {
200 if ( $editor_id === 'content' && ( $current_screen->id === 'post' || $current_screen->id === 'page' ) ) {
201 if ( in_array( 'edit_post_screen', $disabled_editors, true ) ) {
202 $this->disabled_for_editor = true;
203 }
204 } elseif ( in_array( 'rest_of_wpadmin', $disabled_editors, true ) ) {
205 $this->disabled_for_editor = true;
206 }
207 } elseif ( in_array( 'on_front_end', $disabled_editors, true ) ) {
208 $this->disabled_for_editor = true;
209 }
210 }
211
212 if ( ! $this->disabled_for_editor && ! $editor_style_added ) {
213 if ( $this->check_admin_setting( 'importcss' ) && $this->has_editor_style() === false ) {
214 add_editor_style();
215 }
216
217 $editor_style_added = true;
218 }
219
220 return $settings;
221 }
222
223 private function is_disabled() {
224 return $this->disabled_for_editor;
225 }
226
227 private function has_editor_style() {
228 if ( ! current_theme_supports( 'editor-style' ) ) {
229 return false;
230 }
231
232 $editor_stylesheets = get_editor_stylesheets();
233
234 if ( is_array( $editor_stylesheets ) ) {
235 foreach ( $editor_stylesheets as $url ) {
236 if ( strpos( $url, 'editor-style.css' ) !== false ) {
237 return $url;
238 }
239 }
240 }
241
242 return '';
243 }
244
245 public function load_textdomain() {
246 load_plugin_textdomain( 'tinymce-advanced', false, 'tinymce-advanced/langs' );
247 }
248
249 public function enqueue_scripts( $page ) {
250 if ( 'settings_page_tinymce-advanced' === $page ) {
251 $plugin_url = plugins_url( 'plugin-assets', __FILE__ );
252
253 wp_enqueue_style( 'tadv-css', $plugin_url . '/tadv.css', array( 'editor-buttons' ), $this->plugin_version );
254 wp_enqueue_script( 'tadv-js', $plugin_url . '/tadv.js', array( 'jquery-ui-sortable' ), $this->plugin_version, true );
255 wp_enqueue_style( 'tadv-mce-skin', includes_url( 'js/tinymce/skins/lightgray/skin.min.css' ), array(), $this->plugin_version );
256
257 add_action( 'admin_footer', array( $this, 'load_mce_translation' ) );
258 }
259 }
260
261 public function load_mce_translation() {
262 if ( ! class_exists( '_WP_Editors' ) ) {
263 require( ABSPATH . WPINC . '/class-wp-editor.php' );
264 }
265
266 ?>
267 <script>var tadvTranslation = <?php echo _WP_Editors::wp_mce_translation( '', true ); ?>;</script>
268 <?php
269 }
270
271 public function load_settings() {
272 if ( empty( $this->admin_settings ) ) {
273 $this->admin_settings = get_option( 'tadv_admin_settings', false );
274 }
275
276 if ( empty( $this->user_settings ) ) {
277 $this->user_settings = get_option( 'tadv_settings', false );
278 }
279
280 // load defaults if the options don't exist...
281 if ( $this->admin_settings === false ) {
282 $this->admin_settings = $this->get_default_admin_settings();
283 }
284
285 $this->admin_options = ! empty( $this->admin_settings['options'] ) ? explode( ',', $this->admin_settings['options'] ) : array();
286
287 $default_user_settings = $this->get_default_user_settings();
288
289 if ( $this->user_settings === false ) {
290 $this->user_settings = $default_user_settings;
291 }
292
293 if ( empty( $this->user_settings['toolbar_1'] ) ) {
294 $this->user_settings['toolbar_1'] = $default_user_settings['toolbar_1'];
295 }
296
297 if ( empty( $this->user_settings['toolbar_classic_block'] ) ) {
298 $this->user_settings['toolbar_classic_block'] = $default_user_settings['toolbar_classic_block'];
299 }
300
301 $this->options = ! empty( $this->user_settings['options'] ) ? explode( ',', $this->user_settings['options'] ) : array();
302 $this->plugins = ! empty( $this->user_settings['plugins'] ) ? explode( ',', $this->user_settings['plugins'] ) : array();
303 $this->toolbar_1 = ! empty( $this->user_settings['toolbar_1'] ) ? explode( ',', $this->user_settings['toolbar_1'] ) : array();
304 $this->toolbar_2 = ! empty( $this->user_settings['toolbar_2'] ) ? explode( ',', $this->user_settings['toolbar_2'] ) : array();
305 $this->toolbar_3 = ! empty( $this->user_settings['toolbar_3'] ) ? explode( ',', $this->user_settings['toolbar_3'] ) : array();
306 $this->toolbar_4 = ! empty( $this->user_settings['toolbar_4'] ) ? explode( ',', $this->user_settings['toolbar_4'] ) : array();
307
308 $this->toolbar_classic_block = ! empty( $this->user_settings['toolbar_classic_block'] ) ? explode( ',', $this->user_settings['toolbar_classic_block'] ) : array();
309
310 $this->used_buttons = array_merge( $this->toolbar_1, $this->toolbar_2, $this->toolbar_3, $this->toolbar_4, $this->toolbar_classic_block );
311 $this->get_all_buttons();
312
313 // Force refresh after activation.
314 if ( ! empty( $GLOBALS['tinymce_version'] ) && strpos( $GLOBALS['tinymce_version'], '-tadv-' ) === false ) {
315 $GLOBALS['tinymce_version'] .= '-tadv-' . $this->plugin_version;
316 }
317 }
318
319 public function show_version_warning() {
320 if ( is_admin() && current_user_can( 'update_plugins' ) && get_current_screen()->base === 'post' ) {
321 $this->warn_if_unsupported();
322 }
323 }
324
325 public function warn_if_unsupported() {
326 if ( ! $this->check_minimum_supported_version() ) {
327 $wp_version = ! empty( $GLOBALS['wp_version'] ) ? $GLOBALS['wp_version'] : '(undefined)';
328
329 ?>
330 <div class="error notice is-dismissible"><p>
331 <?php
332
333 printf(
334 __( 'Advanced Editor Tools requires WordPress version %1$s or newer. It appears that you are running %2$s. This can make the editor unstable.', 'tinymce-advanced' ),
335 $this->required_wp_version,
336 esc_html( $wp_version )
337 );
338
339 echo '<br>';
340
341 printf(
342 __( 'Please upgrade your WordPress installation or download an <a href="%s">older version of the plugin</a>.', 'tinymce-advanced' ),
343 'https://wordpress.org/plugins/tinymce-advanced/advanced/#download-previous-link'
344 );
345
346 ?>
347 </p></div>
348 <?php
349 }
350 }
351
352 // Min version
353 private function check_minimum_supported_version() {
354 include( ABSPATH . WPINC . '/version.php' ); // get an unmodified $wp_version
355 $wp_version = str_replace( '-src', '', $wp_version );
356
357 return ( version_compare( $wp_version, $this->required_wp_version, '>=' ) );
358 }
359
360 public function update_settings() {
361 $version = (int) get_option( 'tadv_version', 0 );
362
363 if ( $version >= $this->plugin_version ) {
364 return;
365 }
366
367 if ( $version < 4000 ) {
368 // First install or upgrade to TinyMCE 4.0
369 $this->user_settings = $this->get_default_user_settings();
370 $this->admin_settings = $this->get_default_admin_settings();
371
372 update_option( 'tadv_settings', $this->user_settings );
373 update_option( 'tadv_admin_settings', $this->admin_settings );
374 update_option( 'tadv_version', $this->plugin_version );
375
376 // Clean out old options
377 delete_option('tadv_options');
378 delete_option('tadv_toolbars');
379 delete_option('tadv_plugins');
380 delete_option('tadv_btns1');
381 delete_option('tadv_btns2');
382 delete_option('tadv_btns3');
383 delete_option('tadv_btns4');
384 delete_option('tadv_allbtns');
385
386 return;
387 }
388
389 $admin_settings = get_option( 'tadv_admin_settings', false );
390 $user_settings = get_option( 'tadv_settings', false );
391 $user_defaults = $this->get_default_user_settings();
392
393 if ( $version < 5000 ) {
394 // Update for WP 5.0
395 $admin_5000 = ! empty( $admin_settings['options'] ) ? $admin_settings['options'] : '';
396 $user_5000 = ! empty( $user_settings['options'] ) ? $user_settings['options'] : '';
397
398 if ( empty( $admin_5000 ) ) {
399 $admin_5000 = 'hybrid_mode,classic_paragraph_block';
400 } elseif ( strpos( $admin_5000, 'no_hybrid_mode' ) !== false ) {
401 $admin_5000 = str_replace( 'no_hybrid_mode', 'classic_paragraph_block', $admin_5000 );
402 } else {
403 $admin_5000 .= ',hybrid_mode,classic_paragraph_block';
404 }
405
406 if ( empty( $user_5000 ) ) {
407 $user_5000 = 'menubar_block,merge_toolbars';
408 } elseif ( strpos( $user_5000, 'no_merge_toolbars' ) !== false ) {
409 $user_5000 = str_replace( 'no_merge_toolbars', 'menubar_block', $user_5000 );
410 } else {
411 $user_5000 .= ',menubar_block,merge_toolbars';
412 }
413
414 $admin_settings['options'] = $admin_5000;
415 $user_settings['options'] = $user_5000;
416 }
417
418 if ( $version < 5200 ) {
419 // Update for 5.2, table options
420 if ( empty( $admin_settings ) || ! is_array( $admin_settings ) ) {
421 $admin_settings = array(
422 'options' => 'table_resize_bars,table_grid,table_tab_navigation,table_advtab',
423 );
424 } elseif ( empty( $admin_settings['options'] ) || ! is_string( $admin_settings['options'] ) ) {
425 $admin_settings['options'] = 'table_resize_bars,table_grid,table_tab_navigation,table_advtab';
426 } else {
427 $admin_settings['options'] .= ',table_resize_bars,table_grid,table_tab_navigation,table_advtab';
428 }
429 }
430
431 update_option( 'tadv_admin_settings', $admin_settings );
432 update_option( 'tadv_settings', $user_settings );
433
434 // Current version
435 update_option( 'tadv_version', $this->plugin_version );
436 }
437
438 public function get_all_buttons() {
439 if ( ! empty( $this->all_buttons ) ) {
440 return $this->all_buttons;
441 }
442
443 $buttons = array(
444 // Core
445 'bold' => 'Bold',
446 'italic' => 'Italic',
447 'underline' => 'Underline',
448 'strikethrough' => 'Strikethrough',
449 'alignleft' => 'Align left',
450 'aligncenter' => 'Align center',
451 'alignright' => 'Align right',
452 'alignjustify' => 'Justify',
453 'styleselect' => 'Formats',
454 'formatselect' => 'Paragraph',
455 'fontselect' => 'Font Family',
456 'fontsizeselect' => 'Font Sizes',
457 'cut' => 'Cut',
458 'copy' => 'Copy',
459 'paste' => 'Paste',
460 'bullist' => 'Bulleted list',
461 'numlist' => 'Numbered list',
462 'outdent' => 'Decrease indent',
463 'indent' => 'Increase indent',
464 'blockquote' => 'Blockquote',
465 'undo' => 'Undo',
466 'redo' => 'Redo',
467 'removeformat' => 'Clear formatting',
468 'subscript' => 'Subscript',
469 'superscript' => 'Superscript',
470
471 // From plugins
472 'hr' => 'Horizontal line',
473 'link' => 'Insert/edit link',
474 'unlink' => 'Remove link',
475 'image' => 'Insert/edit image',
476 'charmap' => 'Special character',
477 'pastetext' => 'Paste as text',
478 'print' => 'Print',
479 'anchor' => 'Anchor',
480 'searchreplace' => 'Find and replace',
481 'visualblocks' => 'Show blocks',
482 'visualchars' => 'Show invisible characters',
483 'code' => 'Source code',
484 'wp_code' => 'Code',
485 'fullscreen' => 'Fullscreen',
486 'insertdatetime' => 'Insert date/time',
487 'media' => 'Insert/edit video',
488 'nonbreaking' => 'Nonbreaking space',
489 'table' => 'Table',
490 'ltr' => 'Left to right',
491 'rtl' => 'Right to left',
492 'emoticons' => 'Emoticons',
493 'forecolor' => 'Text color',
494 'backcolor' => 'Background color',
495
496 // WP
497 'wp_adv' => 'Toolbar Toggle',
498 'wp_help' => 'Keyboard Shortcuts',
499 'wp_more' => 'Read more...',
500 'wp_page' => 'Page break',
501
502 'tadv_mark' => 'Mark',
503 );
504
505 // add/remove allowed buttons
506 $buttons = apply_filters( 'tadv_allowed_buttons', $buttons );
507
508 $this->all_buttons = $buttons;
509 $this->buttons_filter = array_keys( $buttons );
510 return $buttons;
511 }
512
513 public function get_plugins( $plugins = array() ) {
514
515 if ( ! is_array( $this->used_buttons ) ) {
516 $this->load_settings();
517 }
518
519 if ( in_array( 'anchor', $this->used_buttons, true ) )
520 $plugins[] = 'anchor';
521
522 if ( in_array( 'visualchars', $this->used_buttons, true ) )
523 $plugins[] = 'visualchars';
524
525 if ( in_array( 'visualblocks', $this->used_buttons, true ) )
526 $plugins[] = 'visualblocks';
527
528 if ( in_array( 'nonbreaking', $this->used_buttons, true ) )
529 $plugins[] = 'nonbreaking';
530
531 if ( in_array( 'emoticons', $this->used_buttons, true ) )
532 $plugins[] = 'emoticons';
533
534 if ( in_array( 'insertdatetime', $this->used_buttons, true ) )
535 $plugins[] = 'insertdatetime';
536
537 if ( in_array( 'table', $this->used_buttons, true ) )
538 $plugins[] = 'table';
539
540 if ( in_array( 'print', $this->used_buttons, true ) )
541 $plugins[] = 'print';
542
543 if ( in_array( 'searchreplace', $this->used_buttons, true ) )
544 $plugins[] = 'searchreplace';
545
546 if ( in_array( 'code', $this->used_buttons, true ) )
547 $plugins[] = 'code';
548
549 // From options
550 if ( $this->check_user_setting( 'advlist' ) )
551 $plugins[] = 'advlist';
552
553 if ( $this->check_user_setting( 'advlink' ) )
554 $plugins[] = 'link';
555
556 if ( $this->check_admin_setting( 'importcss' ) )
557 $plugins[] = 'importcss';
558
559 if ( $this->check_user_setting( 'contextmenu' ) )
560 $plugins[] = 'contextmenu';
561
562 // add/remove used plugins
563 $plugins = apply_filters( 'tadv_used_plugins', $plugins, $this->used_buttons );
564
565 return array_unique( $plugins );
566 }
567
568 private function check_user_setting( $setting ) {
569 if ( ! is_array( $this->options ) ) {
570 $this->load_settings();
571 }
572
573 // Back-compat for 'fontsize_formats'
574 if ( $setting === 'fontsize_formats' && $this->check_admin_setting( 'fontsize_formats' ) ) {
575 return true;
576 }
577
578 return in_array( $setting, $this->options, true );
579 }
580
581 private function check_admin_setting( $setting ) {
582 if ( ! is_array( $this->admin_options ) ) {
583 $this->load_settings();
584 }
585
586 if ( strpos( $setting, 'enable_' ) === 0 ) {
587 $disabled_editors = ! empty( $this->admin_settings['disabled_editors'] ) ? explode( ',', $this->admin_settings['disabled_editors'] ) : array();
588 return ! in_array( str_replace( 'enable_', '', $setting ), $disabled_editors );
589 }
590
591 return in_array( $setting, $this->admin_options, true );
592 }
593
594 public function mce_buttons_1( $original, $editor_id ) {
595 if ( $this->is_disabled() ) {
596 return $original;
597 }
598
599 if ( ! is_array( $this->options ) ) {
600 $this->load_settings();
601 }
602
603 if ( $editor_id === 'classic-block' ) {
604 $buttons_1 = $this->toolbar_classic_block;
605 } else {
606 $buttons_1 = $this->toolbar_1;
607 }
608
609 if ( is_array( $original ) && ! empty( $original ) ) {
610 $original = array_diff( $original, $this->buttons_filter );
611 $buttons_1 = array_merge( $buttons_1, $original );
612 }
613
614 return $buttons_1;
615 }
616
617 public function mce_buttons_2( $original, $editor_id ) {
618 if ( $this->is_disabled() ) {
619 return $original;
620 }
621
622 if ( ! is_array( $this->options ) ) {
623 $this->load_settings();
624 }
625
626 if ( $editor_id === 'classic-block' ) {
627 $buttons_2 = array();
628 } else {
629 $buttons_2 = $this->toolbar_2;
630 }
631
632 if ( is_array( $original ) && ! empty( $original ) ) {
633 $original = array_diff( $original, $this->buttons_filter );
634 $buttons_2 = array_merge( $buttons_2, $original );
635 }
636
637 return $buttons_2;
638 }
639
640 public function mce_buttons_3( $original, $editor_id ) {
641 if ( $this->is_disabled() ) {
642 return $original;
643 }
644
645 if ( ! is_array( $this->options ) ) {
646 $this->load_settings();
647 }
648
649 if ( $editor_id === 'classic-block' ) {
650 $buttons_3 = array();
651 } else {
652 $buttons_3 = $this->toolbar_3;
653 }
654
655 if ( is_array( $original ) && ! empty( $original ) ) {
656 $original = array_diff( $original, $this->buttons_filter );
657 $buttons_3 = array_merge( $buttons_3, $original );
658 }
659
660 return $buttons_3;
661 }
662
663 public function mce_buttons_4( $original, $editor_id ) {
664 if ( $this->is_disabled() ) {
665 return $original;
666 }
667
668 if ( ! is_array( $this->options ) ) {
669 $this->load_settings();
670 }
671
672 if ( $editor_id === 'classic-block' ) {
673 $buttons_4 = array();
674 } else {
675 $buttons_4 = $this->toolbar_4;
676 }
677
678 if ( is_array( $original ) && ! empty( $original ) ) {
679 $original = array_diff( $original, $this->buttons_filter );
680 $buttons_4 = array_merge( $buttons_4, $original );
681 }
682
683 return $buttons_4;
684 }
685
686 public function mce_options( $init, $editor_id = '' ) {
687 if ( $this->is_disabled() ) {
688 return $init;
689 }
690
691 $init['image_advtab'] = true;
692 $init['rel_list'] = '[{text: "None", value: ""}, {text: "Nofollow", value: "nofollow noreferrer"}]';
693 // Prevent user errors.
694 $init['removed_menuitems'] = 'newdocument';
695
696 if ( $this->check_admin_setting( 'no_autop' ) ) {
697 $init['wpautop'] = false;
698 $init['indent'] = true;
699 $init['tadv_noautop'] = true;
700 }
701
702 if ( $editor_id === 'classic-block' ) {
703 if ( $this->check_user_setting( 'menubar_block' ) ) {
704 $init['menubar'] = true;
705 }
706
707 if (
708 $this->check_user_setting( 'merge_toolbars' ) &&
709 ! empty( $init['toolbar1'] ) &&
710 is_string( $init['toolbar1'] )
711 ) {
712 if ( ! empty( $init['toolbar2'] ) && is_string( $init['toolbar2'] ) ) {
713 $init['toolbar1'] = $init['toolbar1'] . ',' . $init['toolbar2'];
714 $init['toolbar2'] = '';
715 }
716 if ( ! empty( $init['toolbar3'] ) && is_string( $init['toolbar3'] ) ) {
717 $init['toolbar1'] = $init['toolbar1'] . ',' . $init['toolbar3'];
718 $init['toolbar3'] = '';
719 }
720 if ( ! empty( $init['toolbar4'] ) && is_string( $init['toolbar4'] ) ) {
721 $init['toolbar1'] = $init['toolbar1'] . ',' . $init['toolbar4'];
722 $init['toolbar4'] = '';
723 }
724 }
725 } else {
726 if ( $this->check_user_setting( 'menubar' ) ) {
727 $init['menubar'] = true;
728 }
729 }
730
731 if ( ! in_array( 'wp_adv', $this->toolbar_1, true ) ) {
732 $init['wordpress_adv_hidden'] = false;
733 }
734
735 if ( $this->check_admin_setting( 'importcss' ) ) {
736 $init['importcss_file_filter'] = 'editor-style.css';
737 }
738
739 if ( $this->check_user_setting( 'fontsize_formats' ) ) {
740 $init['fontsize_formats'] = $this->fontsize_formats;
741 }
742
743 if ( in_array( 'table', $this->plugins, true ) ) {
744 $init['table_toolbar'] = false;
745
746 // Prefer percentage values
747 $init['table_responsive_width'] = true;
748
749 if ( ! $this->check_admin_setting( 'table_resize_bars' ) ) {
750 $init['table_resize_bars'] = false;
751 $init['object_resizing'] = 'img';
752 }
753
754 if ( ! $this->check_admin_setting( 'table_default_attributes' ) ) {
755 $init['table_default_attributes'] = '{}';
756 }
757
758 if ( ! $this->check_admin_setting( 'table_grid' ) ) {
759 $init['table_grid'] = false;
760 }
761
762 if ( ! $this->check_admin_setting( 'table_tab_navigation' ) ) {
763 $init['table_tab_navigation'] = false;
764 }
765
766 if ( ! $this->check_admin_setting( 'table_advtab' ) ) {
767 $init['table_advtab'] = false;
768 $init['table_cell_advtab'] = false;
769 $init['table_row_advtab'] = false;
770 $init['table_appearance_options'] = false;
771 }
772 }
773
774 return $init;
775 }
776
777 public function block_editor_assets() {
778 $plugin_url = plugins_url( 'block-editor', __FILE__ );
779
780 if ( ! is_array( $this->admin_options ) ) {
781 $this->load_settings();
782 }
783
784 if ( $this->check_admin_setting( 'hybrid_mode' ) || $this->check_admin_setting( 'classic_paragraph_block' ) ) {
785 $strings = array();
786 $dependencies = array( 'wp-element', 'wp-components', 'wp-i18n', 'wp-keycodes', 'wp-blocks', 'wp-edit-post', 'wp-hooks', 'lodash' );
787 wp_enqueue_script( 'tadv-classic-paragraph', $plugin_url . '/classic-paragraph.js', $dependencies, $this->plugin_version );
788
789 if ( $this->check_admin_setting( 'classic_paragraph_block' ) ) {
790 $strings = array(
791 'classicParagraphTitle' => __( 'Classic Paragraph', 'tinymce-advanced' ),
792 'classicParagraph' => 'yes',
793 'description' => __( 'For use instead of the Paragraph Block. Supports transforming to and from multiple Paragraph blocks, Image, Table, List, Quote, Custom HTML, and most other blocks.', 'tinymce-advanced' ),
794 );
795
796 wp_enqueue_style( 'tadv-classic-paragraph-styles', $plugin_url . '/classic-paragraph.css', array(), $this->plugin_version );
797 }
798
799 if ( $this->check_admin_setting( 'hybrid_mode' ) ) {
800 $strings['hybridMode'] = 'yes';
801 }
802
803 wp_localize_script( 'tadv-classic-paragraph', 'tadvBlockRegister', $strings );
804 }
805
806 // Block editor toolbars
807 if ( ! $this->check_user_setting( 'disable_richtext_buttons' ) ) {
808 $dependencies = array( 'wp-element', 'wp-components', 'wp-i18n', 'wp-editor', 'wp-rich-text' );
809 wp_enqueue_script( 'tadv-block-buttons', $plugin_url . '/richtext-buttons.js', $dependencies, $this->plugin_version );
810
811 $strings = array(
812 'strRemoveFormatting' => __( 'Clear formatting', 'tinymce-advanced' ),
813 'strMark' => __( 'Mark', 'tinymce-advanced' ),
814 );
815
816 wp_localize_script( 'tadv-block-buttons', 'tadvBlockButtons', $strings );
817
818 wp_enqueue_style( 'tadv-block-buttons-styles', $plugin_url . '/richtext-buttons.css', array(), $this->plugin_version );
819 }
820
821 wp_enqueue_style( 'tadv-block-editor-styles', $plugin_url . '/tma-block-editor.css', array(), $this->plugin_version );
822 }
823
824 public function block_editor_init() {
825 if ( $this->check_admin_setting( 'replace_block_editor' ) && ! class_exists( 'Classic_Editor' ) ) {
826 add_filter( 'use_block_editor_for_post_type', '__return_false', 1000 );
827 }
828 }
829
830 public function filter_post_content( $data ) {
831 $content = $data['post_content'];
832 // Fix for the fix to keep <p> tags inside the classic block :-(
833 // $data is slashed...
834 if ( strpos( $content, '<p data-tadv-p=\"keep\">' ) !== false ) {
835 $content = str_replace( '<p data-tadv-p=\"keep\">', '<p>', $content );
836 }
837
838 $data['post_content'] = $content;
839 return $data;
840 }
841
842 // Excerpts can be generated from classic paragraph blocks
843 public function excerpt_add_allowed_blocks( $allowed_blocks ) {
844 // Make sure a plugin doesn't pass the wrong type here...
845 $allowed_blocks = (array) $allowed_blocks;
846 $allowed_blocks[] = 'tadv/classic-paragraph';
847 return $allowed_blocks;
848 }
849
850 public function mce_external_plugins( $mce_plugins ) {
851 if ( ! is_array( $this->options ) ) {
852 $this->load_settings();
853 }
854
855 if ( $this->is_disabled() ) {
856 return $mce_plugins;
857 }
858
859 if ( ! is_array( $this->plugins ) ) {
860 $this->plugins = array();
861 }
862
863 $this->plugins[] = 'wptadv';
864
865 if ( $this->check_user_setting( 'menubar' ) || $this->check_user_setting( 'menubar_block' ) ) {
866 $this->plugins = array_merge( $this->plugins, $this->required_menubar_plugins );
867 }
868
869 $this->plugins = array_intersect( $this->plugins, $this->get_all_plugins() );
870
871 $plugin_url = plugins_url( 'mce/', __FILE__ );
872 $mce_plugins = (array) $mce_plugins;
873 $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
874
875 foreach ( $this->plugins as $plugin ) {
876 $mce_plugins["$plugin"] = $plugin_url . $plugin . "/plugin{$suffix}.js";
877 }
878
879 return $mce_plugins;
880 }
881
882 public function tiny_mce_plugins( $plugins ) {
883 if ( $this->is_disabled() ) {
884 return $plugins;
885 }
886
887 if ( in_array( 'image', $this->used_buttons, true ) && ! in_array( 'image', $plugins, true ) ) {
888 $plugins[] = 'image';
889 }
890
891 if ( ( in_array( 'rtl', $this->used_buttons, true ) || in_array( 'ltr', $this->used_buttons, true ) ) &&
892 ! in_array( 'directionality', (array) $plugins, true ) ) {
893
894 $plugins[] = 'directionality';
895 }
896
897 return $plugins;
898 }
899
900 private function parse_buttons( $toolbar_id = false, $buttons = false ) {
901 if ( $toolbar_id && ! $buttons && ! empty( $_POST[$toolbar_id] ) )
902 $buttons = $_POST[$toolbar_id];
903
904 if ( is_array( $buttons ) ) {
905 $_buttons = array_map( array( @$this, 'filter_name' ), $buttons );
906 return implode( ',', array_filter( $_buttons ) );
907 }
908
909 return '';
910 }
911
912 private function filter_name( $str ) {
913 if ( empty( $str ) || ! is_string( $str ) )
914 return '';
915 // Button names
916 return preg_replace( '/[^a-z0-9_]/i', '', $str );
917 }
918
919 private function sanitize_settings( $settings ) {
920 $_settings = array();
921
922 if ( ! is_array( $settings ) ) {
923 return $_settings;
924 }
925
926 foreach( $settings as $name => $value ) {
927 $name = preg_replace( '/[^a-z0-9_]+/', '', $name );
928
929 if ( strpos( $name, 'toolbar_' ) === 0 ) {
930 $_settings[$name] = $this->parse_buttons( false, explode( ',', $value ) );
931 } else if ( 'options' === $name || 'plugins' === $name || 'disabled_plugins' === $name ) {
932 $_settings[$name] = preg_replace( '/[^a-z0-9_,]+/', '', $value );
933 }
934 }
935
936 return $_settings;
937 }
938
939 /**
940 * Validare array of settings against a whitelist.
941 *
942 * @param array $settings The settings.
943 * @param array $checklist The whitelist.
944 * @return string The validated settings CSV.
945 */
946 private function validate_settings( $settings, $checklist ) {
947 if ( empty( $settings ) ) {
948 return '';
949 } elseif ( is_string( $settings ) ) {
950 $settings = explode( ',', $settings );
951 } elseif ( ! is_array( $settings ) ) {
952 return '';
953 }
954
955 $_settings = array();
956
957 foreach ( $settings as $value ) {
958 if ( in_array( $value, $checklist, true ) ) {
959 $_settings[] = $value;
960 }
961 }
962
963 return implode( ',', $_settings );
964 }
965
966 private function save_settings( $all_settings = null ) {
967 $settings = $user_settings = array();
968 $default_settings = $this->get_default_user_settings();
969
970 if ( empty( $this->buttons_filter ) ) {
971 $this->get_all_buttons();
972 }
973
974 if ( ! empty( $all_settings['settings'] ) ) {
975 $user_settings = $all_settings['settings'];
976 }
977
978 for ( $i = 1; $i < 6; $i++ ) {
979 $toolbar_name = ( $i < 5 ) ? 'toolbar_' . $i : 'toolbar_classic_block';
980
981 if ( ! empty( $user_settings[ $toolbar_name ] ) ) {
982 $toolbar = explode( ',', $user_settings[ $toolbar_name ] );
983 } elseif ( ! empty( $_POST[ $toolbar_name ] ) && is_array( $_POST[ $toolbar_name ] ) ) {
984 $toolbar = $_POST[ $toolbar_name ];
985 } else {
986 $toolbar = array();
987 }
988
989 if ( $i > 1 && in_array( 'wp_adv', $toolbar, true ) ) {
990 $toolbar = array_diff( $toolbar, array( 'wp_adv' ) );
991 }
992
993 $settings[ $toolbar_name ] = $this->validate_settings( $toolbar, $this->buttons_filter );
994 }
995
996 if ( ! empty( $user_settings['options'] ) ) {
997 $options = explode( ',', $user_settings['options'] );
998 } elseif ( ! empty( $_POST['options'] ) && is_array( $_POST['options'] ) ) {
999 $options = $_POST['options'];
1000
1001 if ( ! empty( $_POST['richtext_buttons'] ) && $_POST['richtext_buttons'] === 'no' ) {
1002 $options[] = 'disable_richtext_buttons';
1003 }
1004 } else {
1005 $options = array();
1006 }
1007
1008 $settings['options'] = $this->validate_settings( $options, $this->get_all_user_options() );
1009
1010 if ( ! empty( $user_settings['plugins'] ) ) {
1011 $plugins = explode( ',', $user_settings['plugins'] );
1012 } else {
1013 $plugins = array();
1014 }
1015
1016 if ( ! empty( $settings['options']['menubar'] ) || ! empty( $settings['options']['menubar_block'] ) ) {
1017 $plugins = array_merge( $plugins, $this->required_menubar_plugins );
1018 }
1019
1020 // Merge the submitted plugins with plugins needed for the buttons.
1021 $this->user_settings = $settings;
1022 $this->load_settings();
1023 $plugins = $this->get_plugins( $plugins );
1024
1025 $settings['plugins'] = $this->validate_settings( $plugins, $this->get_all_plugins() );
1026
1027 $this->user_settings = $settings;
1028 $this->load_settings();
1029
1030 // Save the new settings.
1031 update_option( 'tadv_settings', $settings );
1032
1033 if ( ! is_multisite() || current_user_can( 'manage_sites' ) ) {
1034 $this->save_admin_settings( $all_settings );
1035 }
1036 }
1037
1038 private function save_admin_settings( $all_settings = null ) {
1039 $admin_settings = $save_admin_settings = array();
1040
1041 if ( ! empty( $all_settings['admin_settings'] ) ) {
1042 $admin_settings = $all_settings['admin_settings'];
1043 }
1044
1045 if ( ! empty( $admin_settings ) ) {
1046 if ( ! empty( $admin_settings['options'] ) ) {
1047 $save_admin_settings['options'] = $this->validate_settings( $admin_settings['options'], $this->get_all_admin_options() );
1048 } else {
1049 $save_admin_settings['options'] = '';
1050 }
1051
1052 $disabled_editors = array_intersect( $this->get_editor_locations(), explode( ',', $admin_settings['disabled_editors'] ) );
1053 } elseif ( isset( $_POST['tadv-save'] ) ) {
1054 if ( ! empty( $_POST['admin_options'] ) && is_array( $_POST['admin_options'] ) ) {
1055 $save_admin_settings['options'] = $this->validate_settings( $_POST['admin_options'], $this->get_all_admin_options() );
1056 }
1057
1058 if ( ! empty( $_POST['tadv_enable_at'] ) && is_array( $_POST['tadv_enable_at'] ) ) {
1059 $tadv_enable_at = $_POST['tadv_enable_at'];
1060 } else {
1061 $tadv_enable_at = array();
1062 }
1063
1064 $disabled_editors = array_diff( $this->get_editor_locations(), $tadv_enable_at );
1065 } else {
1066 return;
1067 }
1068
1069 $save_admin_settings['disabled_editors'] = implode( ',', $disabled_editors );
1070
1071 $this->admin_settings = $save_admin_settings;
1072 update_option( 'tadv_admin_settings', $save_admin_settings );
1073 }
1074
1075 private function import_from_file() {
1076 if ( empty( $_FILES['tadv-import']['name'] ) ) {
1077 return 1;
1078 }
1079
1080 $file_type = wp_check_filetype( $_FILES['tadv-import']['name'], array( 'json' => 'application/json' ) );
1081
1082 if ( $file_type['ext'] !== 'json' ) {
1083 return 1;
1084 }
1085
1086 $settings = @file_get_contents( $_FILES['tadv-import']['tmp_name'] );
1087
1088 if ( empty( $settings ) ) {
1089 return 2;
1090 }
1091
1092 $settings = json_decode( $settings, true );
1093
1094 if ( ! is_array( $settings ) ) {
1095 return 3;
1096 }
1097
1098 $this->save_settings( $settings );
1099 return 0;
1100 }
1101
1102 public function import_export_settings_file() {
1103 if ( ! current_user_can( 'manage_options' ) ) {
1104 return;
1105 }
1106
1107 if (
1108 isset( $_POST['tadv-import-file'] ) &&
1109 isset( $_POST['tadv-import-settings-nonce'] ) &&
1110 wp_verify_nonce( $_POST['tadv-import-settings-nonce'], 'tadv-import-settings' )
1111 ) {
1112 $err = $this->import_from_file();
1113 $url = admin_url( 'options-general.php?page=tinymce-advanced' );
1114 $url = add_query_arg( 'tadv-import-file-complete', $err, $url );
1115
1116 wp_safe_redirect( $url );
1117 exit;
1118 } elseif (
1119 isset( $_POST['tadv-export-settings'] ) &&
1120 isset( $_POST['tadv-export-settings-nonce'] ) &&
1121 wp_verify_nonce( $_POST['tadv-export-settings-nonce'], 'tadv-export-settings' )
1122 ) {
1123 $this->load_settings();
1124 $output = array( 'settings' => $this->user_settings );
1125
1126 // TODO: only admin || SA
1127 $output['admin_settings'] = $this->admin_settings;
1128
1129 $sitename = get_bloginfo( 'name' );
1130
1131 if ( mb_strlen( $sitename ) > 100 ) {
1132 $sitename = mb_substr( $sitename, 0, 100 );
1133 }
1134
1135 $sitename = preg_replace( '/[ \.-]+/', '-', $sitename );
1136
1137 $date = date( 'Y-m-d' );
1138 $filename = sanitize_file_name( $sitename . '-TMA-settings-' . $date . '.json' );
1139
1140 nocache_headers();
1141 header( 'Content-Type: application/json; charset=utf-8' );
1142 header( "Content-Disposition: attachment; filename=$filename" );
1143
1144 echo wp_json_encode( $output );
1145 exit;
1146 }
1147 }
1148
1149 public function settings_page() {
1150 if ( ! defined( 'TADV_ADMIN_PAGE' ) ) {
1151 define( 'TADV_ADMIN_PAGE', true );
1152 }
1153
1154 include_once( plugin_dir_path( __FILE__ ) . 'tadv_admin.php' );
1155 }
1156
1157 public function add_menu() {
1158 $page_title = __( 'Advanced Editor Tools', 'tinymce-advanced' );
1159 $menu_item_label = __( 'Advanced Editor Tools', 'tinymce-advanced' );
1160 add_options_page( $page_title, $menu_item_label, 'manage_options', 'tinymce-advanced', array( $this, 'settings_page' ) );
1161 }
1162
1163 /**
1164 * Add a link to the settings page
1165 */
1166 public function add_settings_link( $links, $file ) {
1167 if (
1168 strrpos( $file, '/tinymce-advanced.php' ) === ( strlen( $file ) - 21 ) &&
1169 current_user_can( 'manage_options' )
1170 ) {
1171 $settings_link = sprintf( '<a href="%s">%s</a>', admin_url( 'options-general.php?page=tinymce-advanced' ), __( 'Settings', 'tinymce-advanced' ) );
1172 $links = (array) $links;
1173 $links['tma_settings_link'] = $settings_link;
1174 }
1175
1176 return $links;
1177 }
1178 }
1179
1180 new Advanced_Editor_Tools;
1181 endif;
1182