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() { |
|
|
|
|
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() { |
|
|
|
|
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
|
|
|
|
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.