Completed
Push — master ( a0a7de...33dc9f )
by Dennis
01:14
created

MslsPlugin   F

Complexity

Total Complexity 61

Size/Duplication

Total Lines 456
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 0
Metric Value
dl 0
loc 456
rs 3.52
c 0
b 0
f 0
wmc 61
lcom 1
cbo 6

23 Methods

Rating   Name   Duplication   Size   Complexity  
A get_output() 0 9 2
A __construct() 0 3 1
A print_alternate_links() 0 3 1
A content_filter() 0 11 4
A filter_string() 0 38 5
A block_init() 0 24 2
B init() 0 61 9
A update_adminbar() 0 13 4
A admin_bar_init() 0 9 3
A admin_menu() 0 15 5
A plugins_url() 0 3 1
A plugin_dir_path() 0 3 1
A dirname() 0 3 1
A file() 0 3 2
A path() 0 3 2
A init_widget() 0 9 2
A block_render() 0 11 2
A init_i18n_support() 0 3 1
A message_handler() 0 9 2
A activate() 0 3 1
A uninstall() 0 26 4
A cleanup() 0 13 2
A get_superglobals() 0 15 4

How to fix   Complexity   

Complex Class

Complex classes like MslsPlugin often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use MslsPlugin, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * MslsPlugin
4
 * @author Dennis Ploetner <[email protected]>
5
 * @since 0.9.8
6
 */
7
8
namespace lloc\Msls;
9
10
/**
11
 * Provides functionalities for general hooks and activation/deactivation
12
 *
13
 * @package Msls
14
 */
15
class MslsPlugin {
16
17
	/**
18
	 * Injected MslsOptions object
19
	 *
20
	 * @var MslsOptions
21
	 */
22
	protected $options;
23
24
	/**
25
	 * MslsPlugin constructor.
26
	 *
27
	 * @param MslsOptions $options
28
	 */
29
	public function __construct( MslsOptions $options ) {
30
		$this->options = $options;
31
	}
32
33
	/**
34
	 * Factory
35
	 *
36
	 * @codeCoverageIgnore
37
	 *
38
	 * @return MslsPlugin
39
	 */
40
	public static function init() {
41
		$options = MslsOptions::instance();
42
		$obj     = new self( $options );
43
44
		add_action( 'plugins_loaded', [ $obj, 'init_i18n_support' ] );
45
46
		register_activation_hook( self::file(), [ $obj, 'activate' ] );
47
48
		if ( function_exists( 'is_multisite' ) && is_multisite() ) {
49
			add_filter( 'msls_get_output', [ __CLASS__, 'get_output' ] );
50
51
			add_action( 'widgets_init', [ $obj, 'init_widget' ] );
52
			add_filter( 'the_content', [ $obj, 'content_filter' ] );
53
54
			add_action( 'wp_head', [ __CLASS__, 'print_alternate_links' ] );
55
56
			if ( function_exists( 'register_block_type' ) ) {
57
				add_action( 'init', [ $obj, 'block_init' ] );
58
			}
59
60
			add_action( 'init', [ $obj, 'admin_bar_init' ] );
61
62
			\lloc\Msls\ContentImport\Service::instance()->register();
63
64
			if ( is_admin() ) {
65
				add_action( 'admin_menu', [ $obj, 'admin_menu' ] );
66
67
				add_action( 'admin_menu', [ MslsAdmin::class, 'init' ] );
68
				add_action( 'load-post.php', [ MslsMetaBox::class, 'init' ] );
69
				add_action( 'load-post-new.php', [ MslsMetaBox::class, 'init' ] );
70
				add_action( 'load-edit.php', [ MslsCustomColumn::class, 'init' ] );
71
				add_action( 'load-edit.php', [ MslsCustomFilter::class, 'init' ] );
72
73
				add_action( 'load-edit-tags.php', [ MslsCustomColumnTaxonomy::class, 'init' ] );
74
				add_action( 'load-edit-tags.php', [ MslsPostTag::class, 'init' ] );
75
76
				if ( filter_has_var( INPUT_POST, 'action' ) ) {
77
					$action = filter_input( INPUT_POST, 'action', FILTER_SANITIZE_STRING );
78
79
					if ( 'add-tag' === $action ) {
80
						add_action( 'admin_init', [ MslsPostTag::class, 'init' ] );
81
					} elseif ( 'inline-save' === $action ) {
82
						add_action( 'admin_init', [ MslsCustomColumn::class, 'init' ] );
83
					} elseif ( 'inline-save-tax' === $action ) {
84
						add_action( 'admin_init', [ MslsCustomColumnTaxonomy::class, 'init' ] );
85
					}
86
				}
87
88
				add_action( 'wp_ajax_suggest_posts', [ MslsMetaBox::class, 'suggest' ] );
89
				add_action( 'wp_ajax_suggest_terms', [ MslsPostTag::class, 'suggest' ] );
90
			}
91
		} else {
92
			add_action( 'admin_notices', function () {
93
				self::message_handler(
94
					__( 'The Multisite Language Switcher needs the activation of the multisite-feature for working properly. Please read <a onclick="window.open(this.href); return false;" href="http://codex.wordpress.org/Create_A_Network">this post</a> if you don\'t know the meaning.', 'multisite-language-switcher' )
95
				);
96
			} );
97
		}
98
99
		return $obj;
100
	}
101
102
	/**
103
	 * Gets MslsOutput object
104
	 *
105
	 * @return MslsOutput
106
	 */
107
	public static function get_output() {
108
		static $obj = null;
109
110
		if ( is_null( $obj ) ) {
111
			$obj = MslsOutput::init();
112
		}
113
114
		return $obj;
115
	}
116
117
	/**
118
	 * @param $wp_admin_bar
119
	 */
120
	public static function update_adminbar( \WP_Admin_Bar $wp_admin_bar ) {
121
		$blog_collection = MslsBlogCollection::instance();
122
		foreach ( $blog_collection->get_plugin_active_blogs() as $blog ) {
123
			$title = '<div class="blavatar"></div>' . $blog->get_title();
124
125
			$wp_admin_bar->add_node( [ 'id' => 'blog-' . $blog->userblog_id, 'title' => $title ] );
126
		}
127
128
		$blog = $blog_collection->get_current_blog();
129
		if ( is_object( $blog ) && method_exists( $blog, 'get_title' ) ) {
130
			$wp_admin_bar->add_node( [ 'id' => 'site-name', 'title' => $blog->get_title() ] );
131
		}
132
	}
133
134
	/**
135
	 * Callback for action wp_head
136
	 */
137
	public static function print_alternate_links() {
138
		echo self::get_output()->get_alternate_links(), PHP_EOL;
139
	}
140
141
	/**
142
	 * Filter for the_content()
143
	 *
144
	 * @param string $content
145
	 *
146
	 * @return string
147
	 */
148
	function content_filter( $content ) {
149
		if ( ! is_front_page() && is_singular() ) {
150
			$options = $this->options;
151
152
			if ( $options->is_content_filter() ) {
153
				$content .= $this->filter_string();
154
			}
155
		}
156
157
		return $content;
158
	}
159
160
	/**
161
	 * Create filterstring for msls_content_filter()
162
	 *
163
	 * @param string $pref
164
	 * @param string $post
165
	 *
166
	 * @return string
167
	 */
168
	function filter_string( $pref = '<p id="msls">', $post = '</p>' ) {
169
		$obj    = MslsOutput::init();
170
		$links  = $obj->get( 1, true, true );
171
		$output = __( 'This post is also available in %s.', 'multisite-language-switcher' );
172
173
		if ( has_filter( 'msls_filter_string' ) ) {
174
			/**
175
			 * Overrides the string for the output of the translation hint
176
			 *
177
			 * @param string $output
178
			 * @param array $links
179
			 *
180
			 * @since 1.0
181
			 */
182
			$output = apply_filters( 'msls_filter_string', $output, $links );
183
		} else {
184
			$output = '';
185
186
			if ( count( $links ) > 1 ) {
187
				$last   = array_pop( $links );
188
				$output = sprintf(
189
					$output,
190
					sprintf(
191
						__( '%s and %s', 'multisite-language-switcher' ),
192
						implode( ', ', $links ),
193
						$last
194
					)
195
				);
196
			} elseif ( 1 == count( $links ) ) {
197
				$output = sprintf(
198
					$output,
199
					$links[0]
200
				);
201
			}
202
		}
203
204
		return ! empty( $output ) ? $pref . $output . $post : '';
205
	}
206
207
	/**
208
	 * Register block and shortcode.
209
	 * @return bool
210
	 */
211
	public function block_init() {
212
		if ( ! $this->options->is_excluded() ) {
213
			$handle   = 'msls-widget-block';
214
			$callback = [ $this, 'block_render' ];
215
216
			wp_register_script(
217
				$handle,
218
				self::plugins_url( 'js/msls-widget-block.js' ),
219
				[ 'wp-blocks', 'wp-element', 'wp-components', 'wp-editor' ]
220
			);
221
222
			register_block_type( 'lloc/msls-widget-block', [
223
				'attributes'      => [ 'title' => [ 'type' => 'string' ] ],
224
				'editor_script'   => $handle,
225
				'render_callback' => $callback,
226
			] );
227
228
			add_shortcode( 'sc_msls_widget', $callback );
229
230
			return true;
231
		}
232
233
		return false;
234
	}
235
236
	/**
237
	 * @return bool
238
	 */
239
	public function admin_bar_init() {
240
		if ( is_admin_bar_showing() && is_super_admin() ) {
241
			add_action( 'admin_bar_menu', [ __CLASS__, 'update_adminbar' ], 999 );
242
243
			return true;
244
		}
245
246
		return false;
247
	}
248
249
	/**
250
	 * Loads styles and some js if needed
251
	 *
252
	 * The method returns true if JS is loaded or false if not
253
	 *
254
	 * @return boolean
255
	 */
256
	public function admin_menu() {
257
		$ver     = defined( 'MSLS_PLUGIN_VERSION' ) ? constant( 'MSLS_PLUGIN_VERSION' ) : false;
258
		$postfix = defined( 'SCRIPT_DEBUG' ) && constant( 'SCRIPT_DEBUG' ) ? '' : '.min';
259
260
		wp_enqueue_style( 'msls-styles', self::plugins_url( 'css/msls.css' ), [], $ver );
261
		wp_enqueue_style( 'msls-flags', self::plugins_url( 'css-flags/css/flag-icon.min.css' ), [], $ver );
262
263
		if ( $this->options->activate_autocomplete ) {
264
			wp_enqueue_script( 'msls-autocomplete', self::plugins_url( "js/msls{$postfix}.js" ), [ 'jquery-ui-autocomplete' ], $ver );
265
266
			return true;
267
		}
268
269
		return false;
270
	}
271
272
	/**
273
	 * Wrapper for plugins_url
274
	 *
275
	 * @param string $path
276
	 *
277
	 * @return string
278
	 */
279
	public static function plugins_url( string $path ): string {
280
		return plugins_url( $path, self::file() );
281
	}
282
283
	/**
284
	 * Wrapper for plugin_dir_path
285
	 *
286
	 * @param string $path
287
	 *
288
	 * @return string
289
	 */
290
	public static function plugin_dir_path( string $path ): string {
291
		return plugin_dir_path( self::file() ) . $path;
292
	}
293
294
	/**
295
	 * @param string $path
296
	 *
297
	 * @return string
298
	 */
299
	public static function dirname( string $path ): string {
300
		return dirname( self::path() ) . $path;
301
	}
302
303
	/**
304
	 * @return string
305
	 */
306
	public static function file(): string {
307
		return defined( 'MSLS_PLUGIN__FILE__' ) ? constant( 'MSLS_PLUGIN__FILE__' ) : '';
308
	}
309
310
	/**
311
	 * @return string
312
	 */
313
	public static function path(): string {
314
		return defined( 'MSLS_PLUGIN_PATH' ) ? constant( 'MSLS_PLUGIN_PATH' ) : '';
315
	}
316
317
	/**
318
	 * Register widget
319
	 *
320
	 * The widget will only be registered if the current blog is not
321
	 * excluded in the configuration of the plugin.
322
	 * @return boolean
323
	 */
324
	public function init_widget() {
325
		if ( ! $this->options->is_excluded() ) {
326
			register_widget( MslsWidget::class );
327
328
			return true;
329
		}
330
331
		return false;
332
	}
333
334
	/**
335
	 * Render widget output
336
	 *
337
	 * @return string
338
	 */
339
	public function block_render() {
340
		if ( ! $this->init_widget() ) {
341
			return '';
342
		}
343
344
		ob_start();
345
		the_widget( MslsWidget::class );
346
		$output = ob_get_clean();
347
348
		return $output;
349
	}
350
351
	/**
352
	 * Load textdomain
353
	 *
354
	 * The method should be executed always on init because we have some
355
	 * translatable string in the frontend too.
356
	 *
357
	 * @return boolean
358
	 */
359
	public function init_i18n_support() {
360
		return load_plugin_textdomain( 'multisite-language-switcher', false, self::dirname( '/languages/' ) );
361
	}
362
363
	/**
364
	 * Message handler
365
	 *
366
	 * Prints a message box to the screen.
367
	 *
368
	 * @param string $message
369
	 * @param string $css_class
370
	 *
371
	 * @return boolean
372
	 */
373
	public static function message_handler( $message, $css_class = 'error' ) {
374
		if ( ! empty( $message ) ) {
375
			printf( '<div id="msls-warning" class="%s"><p>%s</p></div>', $css_class, $message );
376
377
			return true;
378
		}
379
380
		return false;
381
	}
382
383
	/**
384
	 * Activate plugin
385
	 */
386
	public static function activate() {
387
		register_uninstall_hook( self::file(), [ __CLASS__, 'uninstall' ] );
388
	}
389
390
	/**
391
	 * Uninstall plugin
392
	 *
393
	 * The plugin data in all blogs of the current network will be
394
	 * deleted after the uninstall procedure.
395
	 *
396
	 * @return boolean
397
	 */
398
	public static function uninstall() {
399
		/**
400
		 * We want to be sure that the user has not deactivated the
401
		 * multisite because we need to use switch_to_blog and
402
		 * restore_current_blog
403
		 */
404
		if ( function_exists( 'is_multisite' ) && is_multisite() ) {
405
			$cache = MslsSqlCacher::init( __CLASS__ )->set_params( __METHOD__ );
406
407
			$blogs = $cache->get_results(
408
				$cache->prepare(
409
					"SELECT blog_id FROM {$cache->blogs} WHERE blog_id != %d AND site_id = %d",
410
					$cache->blogid,
411
					$cache->siteid
412
				)
413
			);
414
415
			foreach ( $blogs as $blog ) {
416
				switch_to_blog( $blog->blog_id );
417
				self::cleanup();
418
				restore_current_blog();
419
			}
420
		}
421
422
		return self::cleanup();
423
	}
424
425
	/**
426
	 * Cleanup the options
427
	 *
428
	 * Removes all values of the current blogs which are stored in the
429
	 * options-table and returns true if it was successful.
430
	 *
431
	 * @return boolean
432
	 */
433
	public static function cleanup() {
434
		if ( delete_option( 'msls' ) ) {
435
			$cache = MslsSqlCacher::init( __CLASS__ )->set_params( __METHOD__ );
436
			$sql   = $cache->prepare(
437
				"DELETE FROM {$cache->options} WHERE option_name LIKE %s",
438
				'msls_%'
439
			);
440
441
			return (bool) $cache->query( $sql );
442
		}
443
444
		return false;
445
	}
446
447
	/**
448
	 * Get specific vars from $_POST and $_GET in a safe way
449
	 *
450
	 * @param array $list
451
	 *
452
	 * @return array
453
	 */
454
	public function get_superglobals( array $list ) {
455
		$arr = [];
456
457
		foreach ( $list as $var ) {
458
			$arr[ $var ] = '';
459
460
			if ( filter_has_var( INPUT_POST, $var ) ) {
461
				$arr[ $var ] = filter_input( INPUT_POST, $var );
462
			} elseif ( filter_has_var( INPUT_GET, $var ) ) {
463
				$arr[ $var ] = filter_input( INPUT_GET, $var );
464
			}
465
		}
466
467
		return $arr;
468
	}
469
470
}
471