Completed
Push — master ( 8ab21b...d24e06 )
by Dennis
02:12
created

MslsAdmin::activate_autocomplete()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 3
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
/**
3
 * MslsAdmin
4
 * @author Dennis Ploetner <[email protected]>
5
 * @since 0.9.8
6
 */
7
8
/**
9
 * Administration of the options
10
 * @package Msls
11
 */
12
class MslsAdmin extends MslsMain {
13
14
	/**
15
	 * Init
16
	 * @return MslsAdmin
17
	 */
18
	public static function init() {
19
		$obj = new self();
20
21
		if ( current_user_can( 'manage_options' ) ) {
22
			$title = __( 'Multisite Language Switcher', 'multisite-language-switcher' );
23
			add_options_page( $title, $title, 'manage_options', __CLASS__, array( $obj, 'render' ) );
24
25
			add_action( 'admin_init',    array( $obj, 'register' ) );
26
			add_action( 'admin_notices', array( $obj, 'has_problems' ) );
27
28
			add_filter( 'msls_admin_validate', array( $obj, 'set_blog_language' ) );
29
		}
30
31
		return $obj;
32
	}
33
34
	/**
35
	 * There is something wrong? Here comes the message...
36
	 * @return bool
37
	 */
38
	public function has_problems() {
39
		$message = '';
40
		$options = MslsOptions::instance();
41
42
		if ( 1 == count( $options->get_available_languages() ) ) {
43
			$message = sprintf(
44
				__( '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.' ),
45
				esc_url( 'http://codex.wordpress.org/Installing_WordPress_in_Your_Language#Manually_Installing_Language_Files' ),
46
				esc_url( 'http://wordpress.org/plugins/wp-native-dashboard/' )
47
			);
48
		}
49
		elseif ( $options->is_empty() ) {
50
			$message = sprintf(
51
				__( 'Multisite Language Switcher is almost ready. You must <a href="%s">complete the configuration process</a>.' ),
52
				esc_url( admin_url( '/options-general.php?page=MslsAdmin' ) )
53
			);
54
		}
55
56
		return MslsPlugin::message_handler( $message, 'updated fade' );
57
	}
58
59
	/**
60
	 * Render the options-page
61
	 * @codeCoverageIgnore
62
	 */
63
	public function render() {
64
		printf(
65
			'<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>',
66
			__( 'Multisite Language Switcher Options', 'multisite-language-switcher' ),
67
			$this->subsubsub(),
68
			__( 'To achieve maximum flexibility, you have to configure each blog separately.', 'multisite-language-switcher' )
69
		);
70
71
		settings_fields( 'msls' );
72
		do_settings_sections( __CLASS__ );
73
74
		printf(
75
			'<p class="submit"><input name="Submit" type="submit" class="button-primary" value="%s" /></p></form></div>',
76
			( MslsOptions::instance()->is_empty() ? __( 'Configure', 'multisite-language-switcher' ) : __( 'Update', 'multisite-language-switcher' ) )
77
		);
78
	}
79
80
	/**
81
	 * Create a submenu which contains links to all blogs of the current user
82
	 * @return string
83
	 */
84
	public function subsubsub() {
85
		$arr = array();
86
87
		$blogs = MslsBlogCollection::instance();
88
		foreach ( $blogs->get_plugin_active_blogs() as $blog ) {
89
			$arr[] = sprintf(
90
				'<a href="%s"%s>%s / %s</a>',
91
				get_admin_url( $blog->userblog_id, '/options-general.php?page=MslsAdmin' ),
92
				( $blog->userblog_id == $blogs->get_current_blog_id() ? ' class="current"' : '' ),
93
				$blog->blogname,
94
				$blog->get_description()
95
			);
96
		}
97
98
		return(
99
			empty( $arr ) ?
100
			'' :
101
			sprintf(
102
				'<ul class="subsubsub"><li>%s</li></ul>',
103
				implode( ' | </li><li>', $arr )
104
			)
105
		);
106
	}
107
108
	/**
109
	 * Register the form-elements
110
	 * @codeCoverageIgnore
111
	 */
112
	public function register() {
113
		register_setting( 'msls', 'msls', array( $this, 'validate' ) );
114
115
		add_settings_section( 'language_section', __( 'Language Settings', 'multisite-language-switcher' ), array( $this, 'language_section' ), __CLASS__ );
116
		add_settings_section( 'main_section', __( 'Main Settings', 'multisite-language-switcher' ), array( $this, 'main_section' ), __CLASS__ );
117
		add_settings_section( 'advanced_section', __( 'Advanced Settings', 'multisite-language-switcher' ), array( $this, 'advanced_section' ), __CLASS__ );
118
119
		/**
120
		 * Lets you add your own settings section
121
		 * @since 1.0
122
		 * @param string $page
123
		 */
124
		do_action( 'msls_admin_register', __CLASS__ );
125
	}
126
127
	/**
128
	 * Register the fields in the language_section
129
	 * @codeCoverageIgnore
130
	 */
131
	public function language_section() {
132
		add_settings_field( 'blog_language', __( 'Blog Language', 'multisite-language-switcher' ), array( $this, 'blog_language' ), __CLASS__, 'language_section' );
133
		add_settings_field( 'admin_language', __( 'Admin Language', 'multisite-language-switcher' ), array( $this, 'admin_language' ), __CLASS__, 'language_section' );
134
135
		/**
136
		 * Lets you add your own field to the language section
137
		 * @since 1.0
138
		 * @param string $page
139
		 * @param string $section
140
		 */
141
		do_action( 'msls_admin_language_section', __CLASS__, 'language_section' );
142
	}
143
144
	/**
145
	 * Register the fields in the main_section
146
	 * @codeCoverageIgnore
147
	 */
148
	public function main_section() {
149
		add_settings_field( 'display', __( 'Display', 'multisite-language-switcher' ), array( $this, 'display' ), __CLASS__, 'main_section' );
150
		add_settings_field( 'sort_by_description', __( 'Sort output by description', 'multisite-language-switcher' ), array( $this, 'sort_by_description' ), __CLASS__, 'main_section' );
151
		add_settings_field( 'output_current_blog', __( 'Display link to the current language', 'multisite-language-switcher' ), array( $this, 'output_current_blog' ), __CLASS__, 'main_section' );
152
		add_settings_field( 'only_with_translation', __( 'Show only links with a translation', 'multisite-language-switcher' ), array( $this, 'only_with_translation' ), __CLASS__, 'main_section' );
153
		add_settings_field( 'x_default', __( 'x-default', 'multisite-language-switcher' ), array( $this, 'x_default' ), __CLASS__, 'main_section' );
154
		add_settings_field( 'description', __( 'Description', 'multisite-language-switcher' ), array( $this, 'description' ), __CLASS__, 'main_section' );
155
		add_settings_field( 'before_output', __( 'Text/HTML before the list', 'multisite-language-switcher' ), array( $this, 'before_output' ), __CLASS__, 'main_section' );
156
		add_settings_field( 'after_output', __( 'Text/HTML after the list', 'multisite-language-switcher' ), array( $this, 'after_output' ), __CLASS__, 'main_section' );
157
		add_settings_field( 'before_item', __( 'Text/HTML before each item', 'multisite-language-switcher' ), array( $this, 'before_item' ), __CLASS__, 'main_section' );
158
		add_settings_field( 'after_item', __( 'Text/HTML after each item', 'multisite-language-switcher' ), array( $this, 'after_item' ), __CLASS__, 'main_section' );
159
		add_settings_field( 'content_filter', __( 'Add hint for available translations', 'multisite-language-switcher' ), array( $this, 'content_filter' ), __CLASS__, 'main_section' );
160
		add_settings_field( 'content_priority', __( 'Hint priority', 'multisite-language-switcher' ), array( $this, 'content_priority' ), __CLASS__, 'main_section' );
161
162
		if ( ! is_subdomain_install() && is_main_site() ) {
163
			add_settings_field( 'blog_slug', __( 'Slug for posts', 'multisite-language-switcher' ), array( $this, 'blog_slug' ), __CLASS__, 'main_section' );
164
		}
165
166
		/**
167
		 * Lets you add your own field to the main section
168
		 * @since 1.0
169
		 * @param string $page
170
		 * @param string $section
171
		 */
172
		do_action( 'msls_admin_main_section', __CLASS__, 'main_section' );
173
	}
174
175
	/**
176
	 * Register the fields in the advanced_section
177
	 * @codeCoverageIgnore
178
	 */
179
	public function advanced_section() {
180
		add_settings_field( 'activate_autocomplete', __( 'Activate experimental autocomplete inputs', 'multisite-language-switcher' ), array( $this, 'activate_autocomplete' ), __CLASS__, 'advanced_section' );
181
		add_settings_field( 'image_url', __( 'Custom URL for flag-images', 'multisite-language-switcher' ), array( $this, 'image_url' ), __CLASS__, 'advanced_section' );
182
		add_settings_field( 'reference_user', __( 'Reference user', 'multisite-language-switcher' ), array( $this, 'reference_user' ), __CLASS__, 'advanced_section' );
183
		add_settings_field( 'exclude_current_blog', __( 'Exclude this blog from output', 'multisite-language-switcher' ), array( $this, 'exclude_current_blog' ), __CLASS__, 'advanced_section' );
184
185
		/**
186
		 * Lets you add your own field to the advanced section
187
		 * @since 1.0
188
		 * @param string $page
189
		 * @param string $section
190
		 */
191
		do_action( 'msls_admin_advanced_section', __CLASS__, 'advanced_section' );
192
	}
193
194
	/**
195
	 * Shows the select-form-field 'blog_language'
196
	 */
197
	public function blog_language() {
198
		echo $this->render_select(
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$this'
Loading history...
199
			'blog_language',
200
			MslsOptions::instance()->get_available_languages(),
201
			get_option( 'WPLANG', 'en_US' )
202
		);
203
	}
204
205
	/**
206
	 * Shows the select-form-field 'admin_language'
207
	 */
208
	public function admin_language() {
209
		$options = MslsOptions::instance();
210
		echo $this->render_select(
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$this'
Loading history...
211
			'admin_language',
212
			$options->get_available_languages(),
213
			$options->admin_language
214
		);
215
	}
216
217
	/**
218
	 * Shows the select-form-field 'display'
219
	 */
220
	public function display() {
221
		echo $this->render_select(
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$this'
Loading history...
222
			'display',
223
			MslsLink::get_types_description(),
224
			MslsOptions::instance()->display
225
		);
226
	}
227
228
	/**
229
	 * Shows the select-form-field 'reference_user'
230
	 */
231
	public function reference_user() {
232
		$users = array();
233
234
		foreach ( MslsBlogCollection::instance()->get_users() as $user ) {
235
			$users[ $user->ID ] = $user->user_nicename;
236
		}
237
238
		echo $this->render_select( 'reference_user', $users, MslsOptions::instance()->reference_user );
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$this'
Loading history...
239
	}
240
241
	/**
242
	 * Activate autocomplete
243
	 *
244
	 * You can decide if you want to activate the experimental autocomplete
245
	 * input fields in the backend instead of the traditional select-menus.
246
	 */
247
	public function activate_autocomplete() {
248
		echo $this->render_checkbox( 'activate_autocomplete' );
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$this'
Loading history...
249
	}
250
251
	/**
252
	 * Show sort_by_description-field
253
	 *
254
	 * You can decide that the ouput will be sorted by the description. If not
255
	 * the output will be sorted by the language-code.
256
	 */
257
	public function sort_by_description() {
258
		echo $this->render_checkbox( 'sort_by_description' );
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$this'
Loading history...
259
	}
260
261
	/**
262
	 * Exclude the current blog
263
	 *
264
	 * You can exclude a blog explicitly. All your settings will be safe but the
265
	 * plugin will ignore this blog while this option is active.
266
	 */
267
	public function exclude_current_blog() {
268
		echo $this->render_checkbox( 'exclude_current_blog' );
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$this'
Loading history...
269
	}
270
271
	/**
272
	 * Show only a link  if a translation is available
273
	 *
274
	 * Some user requested this feature. Shows only links to available
275
	 * translations.
276
	 */
277
	public function only_with_translation() {
278
		echo $this->render_checkbox( 'only_with_translation' );
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$this'
Loading history...
279
	}
280
281
	/**
282
	 * Show a link to the current blog
283
	 *
284
	 * Some user requested this feature. If active the plugin will place also a
285
	 * link to the current blog.
286
	 */
287
	public function output_current_blog() {
288
		echo $this->render_checkbox( 'output_current_blog' );
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$this'
Loading history...
289
	}
290
291
	/**
292
	 * Use this blog's hreflang as x-default
293
	 */
294
	public function x_default() {
295
		echo $this->render_checkbox( 'x_default' );
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$this'
Loading history...
296
	}
297
298
	/**
299
	 * The description for the current blog
300
	 *
301
	 * The language will be used ff there is no description.
302
	 */
303
	public function description() {
304
		echo $this->render_input( 'description', '40' );
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$this'
Loading history...
305
	}
306
307
	/**
308
	 * A String which will be placed before the output of the list
309
	 */
310
	public function before_output() {
311
		echo $this->render_input( 'before_output' );
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$this'
Loading history...
312
	}
313
314
	/**
315
	 * A String which will be placed after the output of the list
316
	 */
317
	public function after_output() {
318
		echo $this->render_input( 'after_output' );
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$this'
Loading history...
319
	}
320
321
	/**
322
	 * A String which will be placed before every item of the list
323
	 */
324
	public function before_item() {
325
		echo $this->render_input( 'before_item' );
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$this'
Loading history...
326
	}
327
328
	/**
329
	 * A String which will be placed after every item of the list
330
	 */
331
	public function after_item() {
332
		echo $this->render_input( 'after_item' );
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$this'
Loading history...
333
	}
334
335
	/**
336
	 * The output can be placed after the_content
337
	 */
338
	public function content_filter() {
339
		echo $this->render_checkbox( 'content_filter' );
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$this'
Loading history...
340
	}
341
342
	/**
343
	 * If the output in the_content is active you can set the priority too
344
	 *
345
	 * Default is 10. But may be there are other plugins active and you run into
346
	 * trouble. So you can decide a higher (from 1) or a lower (to 100) priority
347
	 * for the output
348
	 */
349
	public function content_priority() {
350
		$temp     = array_merge( range( 1, 10 ), array( 20, 50, 100 ) );
351
		$arr      = array_combine( $temp, $temp );
352
		$options  = MslsOptions::instance();
353
		$selected = ( empty( $options->content_priority ) ? 10 : $options->content_priority );
354
355
		echo $this->render_select( 'content_priority', $arr, $selected );
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$this'
Loading history...
356
	}
357
358
	/**
359
	 * A String which will be placed after the output of the list
360
	 */
361
	public function blog_slug() {
362
		if ( null === MslsOptions::instance()->blog_slug ) {
0 ignored issues
show
Documentation introduced by
The property blog_slug does not exist on object<MslsOptions>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
363
			$permalink_structure = get_option( 'permalink_structure' );
364
			if ( $permalink_structure ) {
365
				list( $blog_slug, ) = explode( '/%', $permalink_structure, 2 );
366
				MslsOptions::instance()->blog_slug = $blog_slug;
0 ignored issues
show
Documentation introduced by
The property blog_slug does not exist on object<MslsOptions>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
367
			}
368
		}
369
		echo $this->render_input( 'blog_slug' );
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$this'
Loading history...
370
	}
371
372
	/**
373
	 * Alternative image-url
374
	 * @todo This is a value of a directory-url which should be more clear
375
	 */
376
	public function image_url() {
377
		echo $this->render_input( 'image_url' );
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$this'
Loading history...
378
	}
379
380
	/**
381
	 * Render form-element (checkbox)
382
	 * @param string $key Name and ID of the form-element
383
	 * @return string
384
	 */
385
	public function render_checkbox( $key ) {
386
		return sprintf(
387
			'<input type="checkbox" id="%1$s" name="msls[%1$s]" value="1" %2$s/>',
388
			$key,
389
			checked( 1, MslsOptions::instance()->$key, false )
390
		);
391
	}
392
393
	/**
394
	 * Render form-element (text-input)
395
	 * @param string $key Name and ID of the form-element
396
	 * @param string $size Size-attribute of the input-field
397
	 * @return string
398
	 */
399
	public function render_input( $key, $size = '30' ) {
400
		return sprintf(
401
			'<input id="%1$s" name="msls[%1$s]" value="%2$s" size="%3$s"/>',
402
			$key,
403
			esc_attr( MslsOptions::instance()->$key ),
404
			$size
405
		);
406
	}
407
408
	/**
409
	 * Render form-element (select)
410
	 * @uses selected
411
	 * @param string $key Name and ID of the form-element
412
	 * @param array $arr Options as associative array
413
	 * @param string $selected Values which should be selected
414
	 * @return string
415
	 */
416
	public function render_select( $key, array $arr, $selected = '' ) {
417
		$options = array();
418
419
		foreach ( $arr as $value => $description ) {
420
			$options[] = sprintf(
421
				'<option value="%s" %s>%s</option>',
422
				$value,
423
				selected( $value, $selected, false ),
424
				$description
425
			);
426
		}
427
428
		return sprintf(
429
			'<select id="%1$s" name="msls[%1$s]">%2$s</select>',
430
			$key,
431
			implode( '', $options )
432
		);
433
	}
434
435
	/**
436
	 * Validates input before saving it
437
	 * @param array $arr Values of the submitted form
438
	 * @return array Validated input
439
	 */
440
	public function validate( array $arr ) {
441
		/**
442
		 * Returns custom filtered input array
443
		 * @since 1.0
444
		 *
445
		 * @param array $arr
446
		 */
447
		$arr = (array) apply_filters( 'msls_admin_validate', $arr );
448
449
		$arr['display'] = ( isset( $arr['display'] ) ? (int) $arr['display'] : 0 );
450
		if ( isset( $arr['blog_slug'] ) ) {
451
			$arr['blog_slug'] = untrailingslashit( $arr['blog_slug'] );
452
		}
453
		if ( isset( $arr['image_url'] ) ) {
454
			$arr['image_url'] = rtrim( esc_attr( $arr['image_url'] ), '/' );
455
		}
456
457
		return $arr;
458
	}
459
460
	/**
461
	 * Filter which sets the global blog language
462
	 * @param array $arr
463
	 * @return array
464
	 */
465
	public function set_blog_language( array $arr ) {
466
		if ( isset( $arr['blog_language'] ) ) {
467
			$blog_language = ( 'en_US' === $arr['blog_language'] ) ? '' : $arr['blog_language'];
468
			update_option( 'WPLANG', $blog_language );
469
			unset( $arr['blog_language'] );
470
		}
471
		return $arr;
472
	}
473
474
}
475