Passed
Push — master ( b27ccb...7ef923 )
by Jip
02:58
created

Stencil_Config   A

Complexity

Total Complexity 32

Size/Duplication

Total Lines 362
Duplicated Lines 23.76 %

Coupling/Cohesion

Components 1
Dependencies 0
Metric Value
wmc 32
lcom 1
cbo 0
dl 86
loc 362
rs 9.6

12 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A create_admin_menu() 0 10 1
B register_options() 0 27 1
C option_implementations() 0 38 8
A option_themes() 0 12 2
B settings_page() 0 26 1
C maybe_install_plugins() 43 43 7
C maybe_install_themes() 43 43 7
A install_plugin() 0 12 1
A get_plugin_download_link() 0 3 1
A install_theme() 0 12 1
A get_theme_download_link() 0 3 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
/**
3
 * Configure Implementations
4
 *
5
 * @package Stencil
6
 * @subpackage CMS
7
 */
8
9
/**
10
 * Class Stencil_Config
11
 */
12
class Stencil_Config {
13
	/**
14
	 * Implementations provided by us.
15
	 *
16
	 * @var array
17
	 */
18
	private $known_implementations = array(
19
		'stencil-dwoo'     => 'Dwoo',
20
		'stencil-dwoo2'    => 'Dwoo 2',
21
		'stencil-mustache' => 'Mustache',
22
		'stencil-savant3'  => 'Savant 3',
23
		'stencil-smarty2'  => 'Smarty 2.x',
24
		'stencil-smarty3'  => 'Smarty 3.x',
25
		'stencil-twig'     => 'Twig',
26
	);
27
28
	/**
29
	 * Sample themes
30
	 *
31
	 * @var array
32
	 */
33
	private $sample_themes = array(
34
		'dwoo2'    => 'Dwoo',
35
		'mustache' => 'Mustache',
36
		'savant'   => 'Savant',
37
		'smarty'   => 'Smarty',
38
		'twig'     => 'Twig',
39
	);
40
41
	/**
42
	 * Implementations that require a specific minimal PHP version
43
	 *
44
	 * @var array
45
	 */
46
	private $implementation_php_requirements = array(
47
		'stencil-dwoo'  => '5.3.0',
48
		'stencil-dwoo2' => '5.3.0',
49
	);
50
51
	/**
52
	 * Option page
53
	 *
54
	 * @var string
55
	 */
56
	private $option_page = 'stencil-options';
57
58
	/**
59
	 * Option group
60
	 *
61
	 * @var string
62
	 */
63
	private $option_group = 'stencil-implementations';
64
65
	/**
66
	 * The name of the option
67
	 *
68
	 * @var string
69
	 */
70
	private $option_name = 'install';
71
72
	/**
73
	 * Stencil_Config constructor.
74
	 */
75
	public function __construct() {
76
		// Register hooks for config page.
77
		add_action( 'admin_menu', array( $this, 'create_admin_menu' ) );
78
		add_action( 'admin_init', array( $this, 'register_options' ) );
79
	}
80
81
	/**
82
	 * Create the menu item
83
	 */
84
	public function create_admin_menu() {
85
		// Create new top-level menu.
86
		add_menu_page(
87
			__( 'Stencil implementations', 'stencil' ),
88
			'Stencil',
89
			'install_plugins',
90
			'stencil-implementations',
91
			array( $this, 'settings_page' )
92
		);
93
	}
94
95
	/**
96
	 * Register settings
97
	 */
98
	public function register_options() {
99
100
		register_setting( $this->option_group, $this->option_name );
101
102
		add_settings_section(
103
			'stencil-implementations',
104
			'',
105
			'',
106
			$this->option_page
107
		);
108
109
		add_settings_field(
110
			'implementations',
111
			__( 'Implementations', 'stencil' ),
112
			array( $this, 'option_implementations' ),
113
			$this->option_page,
114
			'stencil-implementations'
115
		);
116
117
		add_settings_field(
118
			'themes',
119
			__( 'Sample themes', 'stencil' ),
120
			array( $this, 'option_themes' ),
121
			$this->option_page,
122
			'stencil-implementations'
123
		);
124
	}
125
126
	/**
127
	 * Show plugins that are not installed yet (but tracked)
128
	 * Check to install; installed plugins are grayed out and checked
129
	 * but are ignored on save.
130
	 */
131
	public function option_implementations() {
132
		foreach ( $this->known_implementations as $slug => $name ) {
133
134
			$attributes = array();
135
			$available  = true;
136
			$base       = $this->option_name;
137
			$error      = '';
138
139
			if ( isset( $this->implementation_php_requirements[ $slug ] ) ) {
140
				if ( version_compare( PHP_VERSION, $this->implementation_php_requirements[ $slug ], '<' ) ) {
141
					$available = false;
142
					$error     = sprintf( __( 'PHP version %s required, %s available.' ), $this->implementation_php_requirements[ $slug ], PHP_VERSION );
143
				}
144
			}
145
146
			$exists = is_dir( WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . $slug );
147
148
			/**
149
			 * Disable input if plugin is installed.
150
			 */
151
			if ( $exists ) {
152
				$attributes[] = 'checked="checked"';
153
			}
154
155
			if ( $exists || ! $available ) {
156
				$attributes[] = 'disabled="disabled"';
157
				$base         = 'dummy';
158
			}
159
160
			printf(
161
				'<label><input type="checkbox" name="%s"%s>%s%s</label><br>',
162
				esc_attr( sprintf( '%s[plugin][%s]', $base, $slug ) ),
163
				implode( ' ', $attributes ),
164
				esc_html( $name ),
165
				! empty( $error ) ? sprintf( ' <small>(%s)</small>', $error ) : ''
166
			);
167
		}
168
	}
169
170
	/**
171
	 * Show plugins that are not installed yet (but tracked)
172
	 * Check to install; installed plugins are grayed out and checked
173
	 * but are ignored on save.
174
	 */
175
	public function option_themes() {
176
		foreach ( $this->sample_themes as $slug => $name ) {
177
			/**
178
			 * Disable input if plugin is installed.
179
			 */
180
			printf(
181
				'<label><input type="checkbox" name="%s">%s</label><br>',
182
				esc_attr( sprintf( '%s[theme][%s]', $this->option_name, $slug ) ),
183
				esc_html( $name )
184
			);
185
		}
186
	}
187
188
	/**
189
	 * Show the settings
190
	 */
191
	public function settings_page() {
192
193
		/**
194
		 * Show a list of known implementations
195
		 * Mark installed ones
196
		 * Provide checkbox to (bulk) install optional ones
197
		 */
198
199
		print( '<div class="wrap">' );
200
		printf( '<h2>%s</h2>', __( 'Stencil settings', 'stencil' ) );
201
202
		$this->maybe_install_plugins();
203
		$this->maybe_install_themes();
204
205
		print( '<form method="post" action="options.php">' );
206
207
		settings_fields( $this->option_group );
208
		do_settings_sections( $this->option_page );
209
		submit_button( __( 'Install selected item(s)', 'stencil' ) );
210
211
		print( '</form>' );
212
213
		printf( '<p><em>%s</em></p>', __( 'Note that plugins do not update because they are provided via github, not the WordPress plugin directory.', 'stencil' ) );
214
215
		print( '</div>' );
216
	}
217
218
	/**
219
	 * Install selected plugins
220
	 */
221 View Code Duplication
	public function maybe_install_plugins() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
222
		/**
223
		 * When a plugin can be updated; the field will be check on the settings
224
		 * When all plugins have been installed, they disappear from the list.
225
		 */
226
		$install_plugins = get_option( $this->option_name );
227
228
		if (
229
			empty( $install_plugins ) ||
230
			! isset( $install_plugins['plugin'] ) ||
231
			! is_array( $install_plugins['plugin'] )
232
		) {
233
			return;
234
		}
235
236
		printf( '<h2>%s</h2>', __( 'Installing plugins...', 'stencil' ) );
237
238
		foreach ( $install_plugins['plugin'] as $slug => $on ) {
239
240
			$installed = $this->install_plugin( $slug );
241
242
			if ( ! $installed ) {
243
				printf(
244
					'<em>%s</em><br>',
245
					sprintf(
246
						__( 'Plugin %s could not be installed!', 'stencil' ),
247
						$this->known_implementations[ $slug ]
248
					)
249
				);
250
			}
251
252
			unset( $install_plugins['plugin'][ $slug ] );
253
		}
254
255
		printf( '<b>%s</b>', __( 'Done.', 'stencil' ) );
256
257
		if ( empty( $install_plugins['plugin'] ) ) {
258
			unset( $install_plugins['plugin'] );
259
		}
260
261
		update_option( $this->option_name, $install_plugins );
262
263
	}
264
265
	/**
266
	 * Install selected themes
267
	 */
268 View Code Duplication
	public function maybe_install_themes() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
269
		/**
270
		 * When a plugin can be updated; the field will be check on the settings
271
		 * When all plugins have been installed, they disappear from the list.
272
		 */
273
		$install_plugins = get_option( $this->option_name );
274
275
		if (
276
			empty( $install_plugins ) ||
277
			! isset( $install_plugins['theme'] ) ||
278
			! is_array( $install_plugins['theme'] )
279
		) {
280
			return;
281
		}
282
283
		printf( '<h2>%s</h2>', __( 'Installing themes...', 'stencil' ) );
284
285
		foreach ( $install_plugins['theme'] as $slug => $on ) {
286
287
			$installed = $this->install_theme( $slug );
288
289
			if ( ! $installed ) {
290
				printf(
291
					'<em>%s</em><br>',
292
					sprintf(
293
						__( 'Theme %s could not be installed!', 'stencil' ),
294
						$this->known_implementations[ $slug ]
295
					)
296
				);
297
			}
298
299
			unset( $install_plugins['theme'][ $slug ] );
300
		}
301
302
		printf( '<b>%s</b>', __( 'Done.', 'stencil' ) );
303
304
		if ( empty( $install_plugins['theme'] ) ) {
305
			unset( $install_plugins['theme'] );
306
		}
307
308
		update_option( $this->option_name, $install_plugins );
309
310
	}
311
312
	/**
313
	 * Install plugin by slug
314
	 *
315
	 * @param string $slug Plugin slug.
316
	 *
317
	 * @return bool
318
	 */
319
	public function install_plugin( $slug ) {
320
		$download_link = $this->get_plugin_download_link( $slug );
321
322
		include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
323
324
		iframe_header();
325
		$upgrader = new Plugin_Upgrader( new Plugin_Installer_Skin( array() ) );
326
		$upgrader->install( $download_link );
327
		iframe_footer();
328
329
		return true;
330
	}
331
332
	/**
333
	 * Get the download link for the plugin
334
	 *
335
	 * @param string $slug Plugin slug.
336
	 *
337
	 * @return string
338
	 */
339
	private function get_plugin_download_link( $slug ) {
340
		return sprintf( 'https://github.com/moorscode/%s/archive/master.zip', $slug );
341
	}
342
343
	/**
344
	 * Install theme by slug
345
	 *
346
	 * @param string $slug Theme slug.
347
	 *
348
	 * @return bool
349
	 */
350
	public function install_theme( $slug ) {
351
		$download_link = $this->get_theme_download_link( $slug );
352
353
		include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
354
355
		iframe_header();
356
		$upgrader = new Theme_Upgrader( new Theme_Installer_Skin( array() ) );
357
		$upgrader->install( $download_link );
358
		iframe_footer();
359
360
		return true;
361
	}
362
363
	/**
364
	 * Get the download link for the plugin
365
	 *
366
	 * @param string $slug Plugin slug.
367
	 *
368
	 * @return string
369
	 */
370
	private function get_theme_download_link( $slug ) {
371
		return sprintf( 'https://github.com/moorscode/stencil-sample-theme-%s/archive/master.zip', $slug );
372
	}
373
}
374