tinymce-advanced.php 42 KB

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