Completed
Push — master ( 15db70...750821 )
by Dennis
01:29
created

MslsAdmin   B

Complexity

Total Complexity 49

Size/Duplication

Total Lines 541
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 11

Importance

Changes 0
Metric Value
dl 0
loc 541
rs 8.48
c 0
b 0
f 0
wmc 49
lcom 1
cbo 11

27 Methods

Rating   Name   Duplication   Size   Complexity  
A init() 0 30 3
A get_menu_slug() 0 3 1
A get_options_page_link() 0 3 1
A __call() 0 15 5
A has_problems() 0 18 3
A render() 0 16 2
A subsubsub() 0 22 4
A register() 0 32 2
A language_section() 0 15 1
B main_section() 0 55 1
A advanced_section() 0 31 1
A rewrites_section() 0 21 2
A blog_language() 0 6 1
A display() 0 3 1
A reference_user() 0 9 2
A activate_autocomplete() 0 6 1
A activate_content_import() 0 6 1
A sort_by_description() 0 6 1
A exclude_current_blog() 0 6 1
A only_with_translation() 0 6 1
A output_current_blog() 0 6 1
A description() 0 3 1
A content_filter() 0 6 1
A content_priority() 0 7 2
A render_rewrite() 0 12 3
A validate() 0 21 3
A set_blog_language() 0 9 3

How to fix   Complexity   

Complex Class

Complex classes like MslsAdmin 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 MslsAdmin, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * MslsAdmin
4
 * @author Dennis Ploetner <[email protected]>
5
 * @since 0.9.8
6
 */
7
8
namespace lloc\Msls;
9
10
use lloc\Msls\Component\Input\Checkbox;
11
use lloc\Msls\Component\Input\Group;
12
use lloc\Msls\Component\Input\Label;
13
use lloc\Msls\Component\Input\Text;
14
use lloc\Msls\Component\Input\Select;
15
16
/**
17
 * Administration of the options
18
 * @package Msls
19
 */
20
class MslsAdmin extends MslsMain {
21
22
	/**
23
	 * Factory
24
	 *
25
	 * @codeCoverageIgnore
26
	 *
27
	 * @return MslsAdmin
28
	 */
29
	public static function init() {
30
		if ( ! ( $obj = MslsRegistry::get_object( __CLASS__ ) ) ) {
31
			$options    = MslsOptions::instance();
32
			$collection = MslsBlogCollection::instance();
33
34
			$obj = new static( $options, $collection );
35
36
			MslsRegistry::set_object( __CLASS__, $obj );
37
38
			/**
39
			 * Override the capabilities needed for the plugin's settings
40
			 *
41
			 * @since 2.0
42
			 *
43
			 * @param string $capability
44
			 */
45
			$caps = apply_filters( 'msls_admin_caps', 'manage_options' );
46
			if ( current_user_can( $caps ) ) {
47
				$title = __( 'Multisite Language Switcher', 'multisite-language-switcher' );
48
				add_options_page( $title, $title, 'manage_options', $obj->get_menu_slug(), [ $obj, 'render' ] );
49
50
				add_action( 'admin_init', [ $obj, 'register' ] );
51
				add_action( 'admin_notices', [ $obj, 'has_problems' ] );
52
53
				add_filter( 'msls_admin_validate', [ $obj, 'set_blog_language' ] );
54
			}
55
		}
56
57
		return $obj;
58
	}
59
60
	/**
61
	 * Let's do this simple
62
	 *
63
	 * @return string
64
	 */
65
	public function get_menu_slug() {
66
		return 'MslsAdmin';
67
	}
68
69
	/**
70
	 * Get's the link for the switcher-settings in the wp-admin
71
	 *
72
	 * @return string
73
	 */
74
	public function get_options_page_link() {
75
		return sprintf( '/options-general.php?page=%s', $this->get_menu_slug() );
76
	}
77
78
	/**
79
	 * You can use every method of the decorated object
80
	 *
81
	 * @param string $method
82
	 * @param mixed $args
83
	 *
84
	 * @return mixed
85
	 */
86
	public function __call( $method, $args ) {
87
		$parts = explode( '_', $method, 2 );
88
		if ( 2 == count( $parts ) ) {
89
			switch ( $parts[0] ) {
90
				case 'rewrite':
91
					return $this->render_rewrite( $parts[1] );
92
					break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
93
				case 'text':
94
					$key   = $parts[1];
95
					$value = ! empty( $this->options->$key ) ? $this->options->$key : '';
96
					echo ( new Text( $key, $value ) )->render();
97
					break;
98
			}
99
		}
100
	}
101
102
	/**
103
	 * There is something wrong? Here comes the message...
104
	 * @return bool
105
	 */
106
	public function has_problems() {
107
		$message = '';
108
109
		if ( $this->options->is_empty() ) {
110
			$message = sprintf(
111
				__( 'Multisite Language Switcher is almost ready. You must complete the configuration process</a>.' ),
112
				esc_url( admin_url( $this->get_options_page_link() ) )
113
			);
114
		} elseif ( 1 == count( $this->options->get_available_languages() ) ) {
115
			$message = sprintf(
116
				__( 'There are no language files installed. You can <a href="%s">manually install some language files</a> or you could use a <a href="%s">plugin</a> to download these files automatically.' ),
117
				esc_url( 'http://codex.wordpress.org/Installing_WordPress_in_Your_Language#Manually_Installing_Language_Files' ),
118
				esc_url( 'http://wordpress.org/plugins/wp-native-dashboard/' )
119
			);
120
		}
121
122
		return MslsPlugin::message_handler( $message, 'updated fade' );
123
	}
124
125
	/**
126
	 * Render the options-page
127
	 * @codeCoverageIgnore
128
	 */
129
	public function render() {
130
		printf(
131
			'<div class="wrap"><div class="icon32" id="icon-options-general"><br/></div><h1>%s</h1>%s<br class="clear"/><form action="options.php" method="post"><p>%s</p>',
132
			__( 'Multisite Language Switcher Options', 'multisite-language-switcher' ),
133
			$this->subsubsub(),
134
			__( 'To achieve maximum flexibility, you have to configure each blog separately.', 'multisite-language-switcher' )
135
		);
136
137
		settings_fields( 'msls' );
138
		do_settings_sections( __CLASS__ );
139
140
		printf(
141
			'<p class="submit"><input name="Submit" type="submit" class="button button-primary" value="%s" /></p></form></div>',
142
			( $this->options->is_empty() ? __( 'Configure', 'multisite-language-switcher' ) : __( 'Update', 'multisite-language-switcher' ) )
143
		);
144
	}
145
146
147
	/**
148
	 * Create a submenu which contains links to all blogs of the current user
149
	 * @return string
150
	 */
151
	public function subsubsub() {
152
		$arr = [];
153
154
		foreach ( $this->collection->get_plugin_active_blogs() as $blog ) {
155
			$arr[] = sprintf(
156
				'<a href="%s"%s>%s / %s</a>',
157
				get_admin_url( $blog->userblog_id, $this->get_options_page_link() ),
158
				( $blog->userblog_id == $this->collection->get_current_blog_id() ? ' class="current"' : '' ),
159
				$blog->blogname,
160
				$blog->get_description()
161
			);
162
		}
163
164
		return (
165
			empty( $arr ) ?
166
			'' :
167
			sprintf(
168
				'<ul class="subsubsub"><li>%s</li></ul>',
169
				implode( ' | </li><li>', $arr )
170
			)
171
		);
172
	}
173
174
	/**
175
	 * Register the form-elements
176
	 * @codeCoverageIgnore
177
	 */
178
	public function register() {
179
		register_setting( 'msls', 'msls', [ $this, 'validate' ] );
180
181
		add_settings_section( 'language_section', __( 'Language Settings', 'multisite-language-switcher' ), array(
182
			$this,
183
			'language_section'
184
		), __CLASS__ );
185
		add_settings_section( 'main_section', __( 'Main Settings', 'multisite-language-switcher' ), array(
186
			$this,
187
			'main_section'
188
		), __CLASS__ );
189
		add_settings_section( 'advanced_section', __( 'Advanced Settings', 'multisite-language-switcher' ), array(
190
			$this,
191
			'advanced_section'
192
		), __CLASS__ );
193
194
		global $wp_rewrite;
195
		if ( $wp_rewrite->using_permalinks() ) {
196
			add_settings_section( 'rewrites_section', __( 'Rewrites Settings', 'multisite-language-switcher' ), array(
197
				$this,
198
				'rewrites_section'
199
			), __CLASS__ );
200
		}
201
202
		/**
203
		 * Lets you add your own settings section
204
		 * @since 1.0
205
		 *
206
		 * @param string $page
207
		 */
208
		do_action( 'msls_admin_register', __CLASS__ );
209
	}
210
211
	/**
212
	 * Register the fields in the language_section
213
	 * @codeCoverageIgnore
214
	 */
215
	public function language_section() {
216
		add_settings_field( 'blog_language', __( 'Blog Language', 'multisite-language-switcher' ), array(
217
			$this,
218
			'blog_language'
219
		), __CLASS__, 'language_section', array( 'label_for' => 'blog_language' ) );
220
221
		/**
222
		 * Lets you add your own field to the language section
223
		 * @since 1.0
224
		 *
225
		 * @param string $page
226
		 * @param string $section
227
		 */
228
		do_action( 'msls_admin_language_section', __CLASS__, 'language_section' );
229
	}
230
231
	/**
232
	 * Register the fields in the main_section
233
	 * @codeCoverageIgnore
234
	 */
235
	public function main_section() {
236
		add_settings_field( 'display', __( 'Display', 'multisite-language-switcher' ), array(
237
			$this,
238
			'display'
239
		), __CLASS__, 'main_section', array( 'label_for' => 'display' ) );
240
		add_settings_field( 'sort_by_description', __( 'Sort languages', 'multisite-language-switcher' ), array(
241
			$this,
242
			'sort_by_description'
243
		), __CLASS__, 'main_section' );
244
		add_settings_field( 'output_current_blog', __( 'Current language link', 'multisite-language-switcher' ), array(
245
			$this,
246
			'output_current_blog'
247
		), __CLASS__, 'main_section' );
248
		add_settings_field( 'only_with_translation', __( 'Translation links', 'multisite-language-switcher' ), array(
249
			$this,
250
			'only_with_translation'
251
		), __CLASS__, 'main_section' );
252
		add_settings_field( 'description', __( 'Description', 'multisite-language-switcher' ), array(
253
			$this,
254
			'description'
255
		), __CLASS__, 'main_section', array( 'label_for' => 'description' ) );
256
		add_settings_field( 'before_output', __( 'Text/HTML before the list', 'multisite-language-switcher' ), array(
257
			$this,
258
			'text_before_output'
259
		), __CLASS__, 'main_section', array( 'label_for' => 'before_output' ) );
260
		add_settings_field( 'after_output', __( 'Text/HTML after the list', 'multisite-language-switcher' ), array(
261
			$this,
262
			'text_after_output'
263
		), __CLASS__, 'main_section', array( 'label_for' => 'after_output' ) );
264
		add_settings_field( 'before_item', __( 'Text/HTML before each item', 'multisite-language-switcher' ), array(
265
			$this,
266
			'text_before_item'
267
		), __CLASS__, 'main_section', array( 'label_for' => 'before_item' ) );
268
		add_settings_field( 'after_item', __( 'Text/HTML after each item', 'multisite-language-switcher' ), array(
269
			$this,
270
			'text_after_item'
271
		), __CLASS__, 'main_section', array( 'label_for' => 'after_item' ) );
272
		add_settings_field( 'content_filter', __( 'Available translations hint', 'multisite-language-switcher' ), array(
273
			$this,
274
			'content_filter'
275
		), __CLASS__, 'main_section' );
276
		add_settings_field( 'content_priority', __( 'Hint priority', 'multisite-language-switcher' ), array(
277
			$this,
278
			'content_priority'
279
		), __CLASS__, 'main_section', array( 'label_for' => 'content_priority' ) );
280
281
		/**
282
		 * Lets you add your own field to the main section
283
		 * @since 1.0
284
		 *
285
		 * @param string $page
286
		 * @param string $section
287
		 */
288
		do_action( 'msls_admin_main_section', __CLASS__, 'main_section' );
289
	}
290
291
	/**
292
	 * Register the fields in the advanced_section
293
	 * @codeCoverageIgnore
294
	 */
295
	public function advanced_section() {
296
		add_settings_field( 'activate_autocomplete', __( 'Autocomplete', 'multisite-language-switcher' ), array(
297
			$this,
298
			'activate_autocomplete'
299
		), __CLASS__, 'advanced_section' );
300
		add_settings_field( 'image_url', __( 'Custom URL for flag-images', 'multisite-language-switcher' ), array(
301
			$this,
302
			'text_image_url'
303
		), __CLASS__, 'advanced_section', array( 'label_for' => 'image_url' ) );
304
		add_settings_field( 'reference_user', __( 'Reference user', 'multisite-language-switcher' ), array(
305
			$this,
306
			'reference_user'
307
		), __CLASS__, 'advanced_section', array( 'label_for' => 'reference_user' ) );
308
		add_settings_field( 'exclude_current_blog', __( 'Exclude blog', 'multisite-language-switcher' ), array(
309
			$this,
310
			'exclude_current_blog'
311
		), __CLASS__, 'advanced_section' );
312
		add_settings_field( 'activate_content_import', __( 'Content import', 'multisite-language-switcher' ), array(
313
			$this,
314
			'activate_content_import'
315
		), __CLASS__, 'advanced_section' );
316
317
		/**
318
		 * Lets you add your own field to the advanced section
319
		 * @since 1.0
320
		 *
321
		 * @param string $page
322
		 * @param string $section
323
		 */
324
		do_action( 'msls_admin_advanced_section', __CLASS__, 'advanced_section' );
325
	}
326
327
	/**
328
	 * Register the fields in the rewrites_section
329
	 * @since 1.1
330
	 * @codeCoverageIgnore
331
	 */
332
	public function rewrites_section() {
333
		foreach ( get_post_types( [ 'public' => true ], 'objects' ) as $key => $object ) {
334
			$title = sprintf( __( '%s Slug', 'multisite-language-switcher' ), $object->label );
335
			add_settings_field(
336
				"rewrite_{$key}",
337
				$title,
338
				[ $this, "rewrite_{$key}" ],
339
				__CLASS__,
340
				'rewrites_section',
341
				array( 'label_for' => "rewrite_{$key}" )
342
			);
343
		}
344
345
		/**
346
		 * Lets you add your own field to the rewrites section
347
		 *
348
		 * @param string $page
349
		 * @param string $section
350
		 */
351
		do_action( 'msls_admin_rewrites_section', __CLASS__, 'rewrites_section' );
352
	}
353
354
	/**
355
	 * Shows the select-form-field 'blog_language'
356
	 */
357
	public function blog_language() {
358
		$languages = $this->options->get_available_languages();
359
		$selected  = get_locale();
360
361
		echo ( new Select('blog_language', $languages, $selected ) )->render();
362
	}
363
364
	/**
365
	 * Shows the select-form-field 'display'
366
	 */
367
	public function display() {
368
		echo ( new Select('display', MslsLink::get_types_description(), $this->options->display ) )->render();
369
	}
370
371
	/**
372
	 * Shows the select-form-field 'reference_user'
373
	 */
374
	public function reference_user() {
375
		$users = [];
376
377
		foreach ( $this->collection->get_users() as $user ) {
378
			$users[ $user->ID ] = $user->user_nicename;
379
		}
380
381
		echo ( new Select( 'reference_user', $users, $this->options->reference_user ) )->render();
382
	}
383
384
	/**
385
	 * render
386
	 *
387
	 * You can decide if you want to activate the experimental autocomplete
388
	 * input fields in the backend instead of the traditional select-menus.
389
	 */
390
	public function activate_autocomplete() {
391
		$key   = 'activate_autocomplete';
392
		$text  = __( 'Activate experimental autocomplete inputs', 'multisite-language-switcher' );
393
394
		echo ( new Group() )->add( new Checkbox( $key, $this->options->$key ) )->add( new Label( $key, $text ) )->render();
395
	}
396
397
	/**
398
	 * Activate content import
399
	 *
400
	 * You can decide if you want to activate the content import functionality
401
	 * in the backend instead of the traditional select-menus.
402
	 */
403
	public function activate_content_import() {
404
		$key  = 'activate_content_import';
405
		$text = __( 'Activate the content import functionality', 'multisite-language-switcher' );
406
407
		echo ( new Group() )->add( new Checkbox( $key, $this->options->$key ) )->add( new Label( $key, $text ) )->render();
408
	}
409
410
	/**
411
	 * Show sort_by_description-field
412
	 *
413
	 * You can decide that the output will be sorted by the description. If not
414
	 * the output will be sorted by the language-code.
415
	 */
416
	public function sort_by_description() {
417
		$key   = 'sort_by_description';
418
		$text  = __( 'Sort languages by description', 'multisite-language-switcher' );
419
420
		echo ( new Group() )->add( new Checkbox( $key, $this->options->$key ) )->add( new Label( $key, $text ) )->render();
421
	}
422
423
	/**
424
	 * Exclude the current blog
425
	 *
426
	 * You can exclude a blog explicitly. All your settings will be safe but the
427
	 * plugin will ignore this blog while this option is active.
428
	 */
429
	public function exclude_current_blog() {
430
		$key  = 'exclude_current_blog';
431
		$text =  __( 'Exclude this blog from output', 'multisite-language-switcher' );
432
433
		echo ( new Group() )->add( new Checkbox( $key, $this->options->$key ) )->add( new Label( $key, $text ) )->render();
434
	}
435
436
	/**
437
	 * Show only a link  if a translation is available
438
	 *
439
	 * Some user requested this feature. Shows only links to available
440
	 * translations.
441
	 */
442
	public function only_with_translation() {
443
		$key  = 'only_with_translation';
444
		$text = __( 'Show only links with a translation', 'multisite-language-switcher' );
445
446
		echo ( new Group() )->add( new Checkbox( $key, $this->options->$key ) )->add( new Label( $key, $text ) )->render();
447
	}
448
449
	/**
450
	 * Show a link to the current blog
451
	 *
452
	 * Some user requested this feature. If active the plugin will place also a
453
	 * link to the current blog.
454
	 */
455
	public function output_current_blog() {
456
		$key  = 'output_current_blog';
457
		$text = __( 'Display link to the current language', 'multisite-language-switcher' );
458
459
		echo ( new Group() )->add( new Checkbox( $key, $this->options->$key ) )->add( new Label( $key, $text ) )->render();
460
	}
461
462
	/**
463
	 * The description for the current blog
464
	 *
465
	 * The language will be used ff there is no description.
466
	 */
467
	public function description() {
468
		echo ( new Text('description', $this->options->description, '40' ) )->render();
469
	}
470
471
	/**
472
	 * The output can be placed after the_content
473
	 */
474
	public function content_filter() {
475
		$key  = 'content_filter';
476
		$text = __( 'Add hint for available translations', 'multisite-language-switcher' );
477
478
		echo ( new Group() )->add( new Checkbox( $key, $this->options->$key ) )->add( new Label( $key, $text ) )->render();
479
	}
480
481
	/**
482
	 * If the output in the_content is active you can set the priority too
483
	 *
484
	 * Default is 10. But may be there are other plugins active and you run into
485
	 * trouble. So you can decide a higher (from 1) or a lower (to 100) priority
486
	 * for the output
487
	 */
488
	public function content_priority() {
489
		$temp     = array_merge( range( 1, 10 ), [ 20, 50, 100 ] );
490
		$arr      = array_combine( $temp, $temp );
491
		$selected = empty( $this->options->content_priority ) ? 10 : $this->options->content_priority;
492
493
		echo ( new Select( 'content_priority', $arr, $selected ) )->render();
494
	}
495
496
	/**
497
	 * Rewrites slugs for registered post types
498
	 *
499
	 * @param string $key
500
	 */
501
	public function render_rewrite( $key ) {
502
		$rewrite = get_post_type_object( $key )->rewrite;
503
504
		$value = '';
505
		if ( true === $rewrite ) {
506
			$value = $key;
507
		} elseif ( ! empty( $rewrite['slug'] ) ) {
508
			$value = $rewrite['slug'];
509
		}
510
511
		echo ( new Text( "rewrite_{$key}", $value, 30, true ) )->render();
512
	}
513
514
	/**
515
	 * Validates input before saving it
516
	 *
517
	 * @param array $arr Values of the submitted form
518
	 *
519
	 * @return array Validated input
520
	 */
521
	public function validate( array $arr ) {
522
		/**
523
		 * Returns custom filtered input array
524
		 * @since 1.0
525
		 *
526
		 * @param array $arr
527
		 */
528
		$arr = apply_filters( 'msls_admin_validate', $arr );
529
530
		$arr['display'] = (
531
		isset( $arr['display'] ) ?
532
			(int) $arr['display'] :
533
			0
534
		);
535
536
		if ( isset( $arr['image_url'] ) ) {
537
			$arr['image_url'] = rtrim( esc_attr( $arr['image_url'] ), '/' );
538
		}
539
540
		return $arr;
541
	}
542
543
	/**
544
	 * Filter which sets the global blog language
545
	 *
546
	 * @param array $arr
547
	 *
548
	 * @return array
549
	 */
550
	public function set_blog_language( array $arr ) {
551
		if ( isset( $arr['blog_language'] ) ) {
552
			$blog_language = ( 'en_US' === $arr['blog_language'] ) ? '' : $arr['blog_language'];
553
			update_option( 'WPLANG', $blog_language );
554
			unset( $arr['blog_language'] );
555
		}
556
557
		return $arr;
558
	}
559
560
}
561