Completed
Push — develop ( 03416e...7846c8 )
by Marco
01:28
created

includes/class-admin.php (2 issues)

Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
// Exit if accessed directly
4
if ( ! defined( 'ABSPATH' ) ) {
5
	exit;
6
}
7
8
/**
9
 * Class that provides admin functionalities
10
 *
11
 * @package Black_Studio_TinyMCE_Widget
12
 * @since 2.0.0
13
 */
14
15
if ( ! class_exists( 'Black_Studio_TinyMCE_Admin' ) ) {
16
17
	final class Black_Studio_TinyMCE_Admin {
18
19
		/**
20
		 * The single instance of the class
21
		 *
22
		 * @var object
23
		 * @since 2.0.0
24
		 */
25
		protected static $_instance = null;
26
27
		/**
28
		 * Array containing the plugin links
29
		 *
30
		 * @var array
31
		 * @since 2.0.0
32
		 */
33
		protected $links;
34
35
		/**
36
		 * Return the single class instance
37
		 *
38
		 * @return object
39
		 * @since 2.0.0
40
		 */
41
		public static function instance() {
42
			if ( is_null( self::$_instance ) ) {
43
				self::$_instance = new self();
44
			}
45
			return self::$_instance;
46
		}
47
48
		/**
49
		 * Class constructor
50
		 *
51
		 * @uses add_action()
52
		 * @uses add_filter()
53
		 * @uses get_option()
54
		 * @uses get_bloginfo()
55
		 *
56
		 * @global object $wp_embed
57
		 * @since 2.0.0
58
		 */
59
		protected function __construct() {
60
			// Register action and filter hooks
61
			add_action( 'plugins_loaded', array( $this, 'load_textdomain' ) );
62
			add_action( 'admin_init', array( $this, 'admin_init' ), 20 );
63
		}
64
65
		/**
66
		 * Prevent the class from being cloned
67
		 *
68
		 * @return void
69
		 * @since 2.0.0
70
		 */
71
		protected function __clone() {
72
			_doing_it_wrong( __FUNCTION__, __( 'Cheatin&#8217; uh?' ), '2.0' );
73
		}
74
75
		/**
76
		 * Load language files
77
		 *
78
		 * @uses load_plugin_textdomain()
79
		 *
80
		 * @return void
81
		 * @since 2.0.0
82
		 */
83
		public function load_textdomain() {
84
			load_plugin_textdomain( 'black-studio-tinymce-widget', false, dirname( dirname( plugin_basename( __FILE__ ) ) ) . '/languages/' );
85
		}
86
87
		/**
88
		 * Checks if the plugin admin code should be loaded
89
		 *
90
		 * @uses apply_filters()
91
		 *
92
		 * @global string $pagenow
93
		 * @return void
94
		 * @since 2.0.0
95
		 */
96
		public function enabled() {
97
			global $pagenow;
98
			$enabled_pages = apply_filters( 'black_studio_tinymce_enable_pages', array( 'widgets.php', 'customize.php', 'admin-ajax.php' ) );
99
			return apply_filters( 'black_studio_tinymce_enable', in_array( $pagenow, $enabled_pages ) );
100
		}
101
102
		/**
103
		 * Add actions and filters (only in widgets admin page)
104
		 *
105
		 * @uses add_action()
106
		 * @uses add_filter()
107
		 * @uses do_action()
108
		 *
109
		 * @return void
110
		 * @since 2.0.0
111
		 */
112
		public function admin_init() {
113
			$this->init_links();
114
			add_action( 'plugin_row_meta', array( $this, 'plugin_row_meta' ), 10, 2 );
115
			if ( $this->enabled() ) {
116
				add_action( 'admin_head', array( $this, 'enqueue_media' ) );
117
				add_action( 'admin_print_scripts', array( $this, 'admin_print_scripts' ) );
118
				add_action( 'admin_print_styles', array( $this, 'admin_print_styles' ) );
119
				add_action( 'admin_print_footer_scripts', array( $this, 'admin_print_footer_scripts' ) );
120
				add_action( 'black_studio_tinymce_before_editor', array( $this, 'display_links' ) ); // consider donating if you remove links
121
				add_action( 'black_studio_tinymce_editor', array( $this, 'editor' ), 10, 4 );
122
				add_action( 'black_studio_tinymce_after_editor', array( $this, 'fix_the_editor_content_filter' ) );
123
				add_action( 'wp_tiny_mce_init', array( $this, 'wp_tiny_mce_init' ) );
124
				add_filter( 'wp_editor_settings', array( $this, 'editor_settings' ), 5, 2 );
125
				add_filter( 'tiny_mce_before_init', array( $this, 'tinymce_fix_rtl' ), 10 );
126
				add_filter( 'tiny_mce_before_init', array( $this, 'tinymce_fullscreen' ), 10, 2 );
127
				add_filter( 'quicktags_settings', array( $this, 'quicktags_fullscreen' ), 10, 2 );
128
				if ( ! user_can_richedit() ) {
129
					add_action( 'admin_notices', array( $this, 'visual_editor_disabled_notice' ) );
130
				}
131
				add_action( 'wp_ajax_bstw_visual_editor_disabled_dismiss_notice', array( $this, 'visual_editor_disabled_dismiss_notice' ) );
132
				do_action( 'black_studio_tinymce_load' );
133
			}
134
		}
135
136
		/**
137
		 * Instantiate tinyMCE editor
138
		 *
139
		 * @uses add_thickbox()
140
		 * @uses wp_enqueue_media()
141
		 *
142
		 * @return void
143
		 * @since 2.0.0
144
		 */
145
		public function enqueue_media() {
146
			// Add support for thickbox media dialog
147
			add_thickbox();
148
			// New media modal dialog (WP 3.5+)
149
			if ( function_exists( 'wp_enqueue_media' ) ) {
150
				wp_enqueue_media();
151
			}
152
		}
153
154
		/**
155
		 * Enqueue styles
156
		 *
157
		 * @uses wp_enqueue_style()
158
		 * @uses Black_Studio_TinyMCE_Plugin::enqueue_style()
159
		 *
160
		 * @return void
161
		 * @since 2.0.0
162
		 */
163
		public function admin_print_styles() {
164
			wp_enqueue_style( 'wp-jquery-ui-dialog' );
165
			wp_enqueue_style( 'editor-buttons' );
166
			$this->enqueue_style();
167
		}
168
169
		/**
170
		 * Helper function to enqueue style
171
		 *
172
		 * @uses apply_filters()
173
		 * @uses wp_enqueue_style()
174
		 * @uses plugins_url()
175
		 * @uses SCRIPT_DEBUG
176
		 *
177
		 * @return void
178
		 * @since 2.0.0
179
		 */
180
		public function enqueue_style() {
181
			$style = apply_filters( 'black-studio-tinymce-widget-style', 'black-studio-tinymce-widget' );
182
			$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
183
			wp_enqueue_style(
184
				$style,
185
				plugins_url( 'css/' . $style . $suffix. '.css', dirname( __FILE__ ) ),
186
				array(),
187
				bstw()->get_version()
188
			);
189
		}
190
191
		/**
192
		 * Enqueue header scripts
193
		 *
194
		 * @uses wp_enqueue_script()
195
		 * @uses do_action()
196
		 *
197
		 * @return void
198
		 * @since 2.0.0
199
		 */
200
		public function admin_print_scripts() {
201
			wp_enqueue_script( 'media-upload' );
202
			wp_enqueue_script( 'wplink' );
203
			wp_enqueue_script( 'wpdialogs-popup' );
204
			$this->enqueue_script();
205
			$this->localize_script();
206
			do_action( 'wp_enqueue_editor', array( 'tinymce' => true ) );
207
		}
208
209
		/**
210
		 * Helper function to enqueue script
211
		 *
212
		 * @uses apply_filters()
213
		 * @uses wp_enqueue_script()
214
		 * @uses plugins_url()
215
		 * @uses SCRIPT_DEBUG
216
		 *
217
		 * @return void
218
		 * @since 2.0.0
219
		 */
220
		public function enqueue_script() {
221
			$script = apply_filters( 'black-studio-tinymce-widget-script', 'black-studio-tinymce-widget' );
222
			$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
223
			wp_enqueue_script(
224
				$script,
225
				plugins_url( 'js/' . $script . $suffix . '.js', dirname( __FILE__ ) ),
226
				array( 'jquery', 'editor', 'quicktags' ),
227
				bstw()->get_version(),
228
				true
229
			);
230
		}
231
232
		/**
233
		 * Helper function to enqueue localized script
234
		 *
235
		 * @uses apply_filters()
236
		 * @uses wp_localize_script()
237
		 *
238
		 * @return void
239
		 * @since 2.0.0
240
		 */
241
		public function localize_script() {
242
			$container_selectors = apply_filters( 'black_studio_tinymce_container_selectors', array(  'div.widget', 'div.widget-inside' ) );
243
			$activate_events = apply_filters( 'black_studio_tinymce_activate_events', array() );
244
			$deactivate_events = apply_filters( 'black_studio_tinymce_deactivate_events', array() );
245
			$data = array(
246
				'container_selectors' => implode( ', ', $container_selectors ),
247
				'activate_events' => $activate_events,
248
				'deactivate_events' => $deactivate_events,
249
				/* translators: error message shown when a duplicated widget ID is detected */
250
				'error_duplicate_id' => __( 'ERROR: Duplicate widget ID detected. To avoid content loss, please create a new widget with the same content and then delete this one.', 'black-studio-tinymce-widget' )
251
			);
252
			wp_localize_script( apply_filters( 'black-studio-tinymce-widget-script', 'black-studio-tinymce-widget' ), 'bstw_data', $data );
253
		}
254
255
		/**
256
		 * Enqueue footer scripts
257
		 *
258
		 * @return void
259
		 * @since 2.0.0
260
		 */
261
		public function admin_print_footer_scripts() {
262
			$this->editor( '', 'black-studio-tinymce-widget', 'black-studio-tinymce-widget' );
263
		}
264
265
		/**
266
		 * Output the visual editor
267
		 *
268
		 * @uses wp_editor()
269
		 *
270
		 * @param string $text
271
		 * @param string $editor_id
272
		 * @param string $name
273
		 * @param string $type
274
		 * @return void
275
		 * @since 2.0.0
276
		 */
277
		public function editor( $text, $editor_id, $name = '', $type = 'visual' ) {
278
			wp_editor( $text, $editor_id, array( 'textarea_name' => $name, 'default_editor' => $type == 'visual' ? 'tmce' : 'html' ) );
279
		}
280
281
		/**
282
		 * Remove editor content filters for multiple editor instances
283
		 * Workaround for WordPress Core bug #28403 https://core.trac.wordpress.org/ticket/28403
284
		 *
285
		 * @uses remove_filter
286
		 *
287
		 * @return void
288
		 * @since 2.1.7
289
		 */
290
		public function fix_the_editor_content_filter() {
291
			remove_filter( 'the_editor_content', 'wp_htmledit_pre' );
292
			remove_filter( 'the_editor_content', 'wp_richedit_pre' );
293
		}
294
295
		/**
296
		 * Setup editor instance for event handling
297
		 *
298
		 * @return void
299
		 * @since 2.2.1
300
		 */
301
		public function wp_tiny_mce_init() {
302
			$script = 'black-studio-tinymce-widget-setup';
303
			$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
304
			echo "\t\t" . '<script type="text/javascript" src="' . plugins_url( 'js/' . $script . $suffix . '.js', dirname( __FILE__ ) ) . '"></script>' . "\n"; // xss ok
305
		}
306
307
		/**
308
		 * Set editor settings
309
		 *
310
		 * @param mixed[] $settings
311
		 * @param string $editor_id
312
		 * @return mixed[]
313
		 * @since 2.0.0
314
		 */
315
		public function editor_settings( $settings, $editor_id ) {
316
			if ( strstr( $editor_id, 'black-studio-tinymce' ) ) {
317
				$settings['tinymce'] = array(
318
					'wp_skip_init' => 'widget-black-studio-tinymce-__i__-text' == $editor_id,
319
					'add_unload_trigger' => false,
320
					'wp_autoresize_on' => false,
321
				);
322
				$settings['editor_height'] = 350;
323
				$settings['dfw'] = true;
324
				$settings['editor_class'] = 'black-studio-tinymce';
325
			}
326
			return $settings;
327
		}
328
329
		/**
330
		 * Initialize plugin links
331
		 *
332
		 * @return void
333
		 * @since 2.0.0
334
		 */
335
		public function init_links() {
336
			$this->links = array(
337
				/* translators: text used for plugin home link */
338
				'https://wordpress.org/plugins/black-studio-tinymce-widget/' => __( 'Home', 'black-studio-tinymce-widget' ),
339
				/* translators: text used for support faq link */
340
				'https://wordpress.org/plugins/black-studio-tinymce-widget/faq/' => __( 'FAQ', 'black-studio-tinymce-widget' ),
341
				/* translators: text used for support forum link */
342
				'https://wordpress.org/support/plugin/black-studio-tinymce-widget' => __( 'Support', 'black-studio-tinymce-widget' ),
343
				/* translators: text used for reviews link */
344
				'https://wordpress.org/support/view/plugin-reviews/black-studio-tinymce-widget' => __( 'Rate', 'black-studio-tinymce-widget' ),
345
				/* translators: text used for follow on twitter link */
346
				'https://twitter.com/blackstudioita' => __( 'Follow', 'black-studio-tinymce-widget' ),
347
				/* translators: text used for donation link */
348
				'http://www.blackstudio.it/en/wordpress-plugins/black-studio-tinymce-widget/' => __( 'Donate', 'black-studio-tinymce-widget' ),
349
			);
350
		}
351
352
		/**
353
		 * Display plugin links
354
		 *
355
		 * @return void
356
		 * @since 2.0.0
357
		 */
358
		public function display_links() {
359
			echo "\t<div class='bstw-links'>\n";
360
			echo "\t\t<span class='bstw-links-list'>\n";
361
			$counter = count( $this->links ) - 1;
362
			foreach ( $this->links as $url => $label ) {
363
				$separator = ( $counter-- > 0 ? ' | ' : '' );
364
				echo "\t\t\t<a href='" . esc_url( $url ) . "' target='_blank'>" . esc_html( $label ) . "</a>$separator\n"; // xss ok
365
			}
366
			echo "\t\t</span>\n";
367
			/* translators: text used for the icon that shows the plugin links */
368
			echo "\t\t<a class='bstw-links-icon icon16 icon-plugins' href='#' title='" . esc_attr( __( 'About Black Studio TinyMCE Widget plugin', 'black-studio-tinymce-widget' ) ) . "'></a>\n";
369
			echo "\t</div>\n";
370
		}
371
372
		/**
373
		 * Show row meta on the plugin screen
374
		 *
375
		 * @uses esc_html()
376
		 * @uses esc_url()
377
		 *
378
		 * @param string[] $links
379
		 * @param string $file
380
		 * @return string[]
381
		 * @since 2.0.0
382
		 */
383
		public function plugin_row_meta( $links, $file ) {
384
			if ( $file == bstw()->get_basename() ) {
385
				foreach ( $this->links as $url => $label ) {
386
					$links[ $label ] = '<a href="' . esc_url( $url ) . '" target="_blank">' . esc_html( $label ) . '</a>';
387
				}
388
			}
389
			return $links;
390
		}
391
392
		/**
393
		 * Fix for rtl languages
394
		 *
395
		 * @param mixed[] $settings
396
		 * @return mixed[]
397
		 * @since 2.1.0
398
		 */
399
		public function tinymce_fix_rtl( $settings ) {
400
			// This fix has to be applied to all editor instances (not just BSTW ones)
401
			if ( is_rtl() && isset( $settings['plugins'] ) && ',directionality' == $settings['plugins'] ) {
402
				unset( $settings['plugins'] );
403
			}
404
			return $settings;
405
		}
406
407
		/**
408
		 * Apply TinyMCE default fullscreen
409
		 *
410
		 * @param mixed[] $settings
411
		 * @param string $editor_id
412
		 * @return mixed[]
413
		 * @since 2.1.2
414
		 */
415
		public function tinymce_fullscreen( $settings, $editor_id ) {
416
			if ( strstr( $editor_id, 'black-studio-tinymce' ) ) {
417
				for ( $i = 1; $i <= 4; $i++ ) {
418
					$toolbar = 'toolbar' . $i;
419
					if ( isset( $settings[ $toolbar ] ) ) {
420
						$settings[ $toolbar ] = str_replace( 'wp_fullscreen', 'wp_fullscreen,fullscreen', $settings[ $toolbar ] );
421
					}
422
				}
423
			}
424
			return $settings;
425
		}
426
427
		/**
428
		 * Disable Quicktags default fullscreen
429
		 *
430
		 * @param mixed[] $settings
431
		 * @param string $editor_id
432
		 * @return mixed[]
433
		 * @since 2.1.2
434
		 */
435
		public function quicktags_fullscreen( $settings, $editor_id ) {
436
			if ( strstr( $editor_id, 'black-studio-tinymce' ) ) {
437
				$settings['buttons'] = str_replace( ',fullscreen', '', $settings['buttons'] );
438
			}
439
			return $settings;
440
		}
441
442
		/**
443
		 * Show admin notice when visual editor is disabled in current user's profile settings
444
		 *
445
		 * @uses get_user_meta()
446
		 * @uses get_current_user_id()
447
		 *
448
		 * @return void
449
		 * @since 2.4.0
450
		 */
451
		public function visual_editor_disabled_notice() {
452
			global $pagenow;
453
			$dismissed = false;
454
			if ( function_exists( 'get_user_meta' ) ) {
455
				$dismissed = get_user_meta( get_current_user_id(), '_bstw_visual_editor_disabled_notice_dismissed', true );
1 ignored issue
show
get_user_meta() usage is highly discouraged, check VIP documentation on "Working with wp_users"
Loading history...
456
			}
457
			if ( 'widgets.php' == $pagenow && empty( $dismissed ) ) {
458
				echo '<div class="bstw-visual-editor-disabled-notice notice notice-warning is-dismissible">';
459
				/* translators: warning message shown when when visual editor is disabled in current user's profile settings */
460
				echo '<p>' . esc_html( __( 'Visual Editor is disabled in your Profile settings. You need to enable it in order to use the Visual Editor widget at its full potential.', 'black-studio-tinymce-widget' ) ) . '</p>';
461
				echo '</div>';
462
			}
463
		}
464
		
465
		/**
466
		 * Store dismission of the "Visual Editor disabled" notice for the current user
467
		 *
468
		 * @uses add_user_meta()
469
		 * @uses get_current_user_id()
470
		 *
471
		 * @return void
472
		 * @since 2.4.0
473
		 */
474
		public function visual_editor_disabled_dismiss_notice() {
475
			if ( function_exists( 'add_user_meta' ) ) {
476
				add_user_meta( get_current_user_id(), '_bstw_visual_editor_disabled_notice_dismissed', true );
1 ignored issue
show
add_user_meta() usage is highly discouraged, check VIP documentation on "Working with wp_users"
Loading history...
477
			}
478
		}
479
480
	} // END class Black_Studio_TinyMCE_Admin
481
482
} // END class_exists check
483