Passed
Push — master ( a60687...f06b1d )
by Jip
02:39
created

Stencil_Config::get_download_link()   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 1
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
	 * Implementations that require a specific minimal PHP version
30
	 *
31
	 * @var array
32
	 */
33
	private $implementation_php_requirements = array(
34
		'stencil-dwoo'  => '5.3.0',
35
		'stencil-dwoo2' => '5.3.0',
36
	);
37
38
	/**
39
	 * Option page
40
	 *
41
	 * @var string
42
	 */
43
	private $option_page = 'stencil-options';
44
45
	/**
46
	 * Option group
47
	 *
48
	 * @var string
49
	 */
50
	private $option_group = 'stencil-implementations';
51
52
	/**
53
	 * The name of the option
54
	 *
55
	 * @var string
56
	 */
57
	private $option_name = 'install';
58
59
	/**
60
	 * Stencil_Config constructor.
61
	 */
62
	public function __construct() {
63
		// Register hooks for config page.
64
		add_action( 'admin_menu', array( $this, 'create_admin_menu' ) );
65
		add_action( 'admin_init', array( $this, 'register_options' ) );
66
	}
67
68
	/**
69
	 * Create the menu item
70
	 */
71
	public function create_admin_menu() {
72
		// Create new top-level menu.
73
		add_menu_page(
74
			__( 'Stencil implementations', 'stencil' ),
75
			'Stencil',
76
			'install_plugins',
77
			'stencil-implementations',
78
			array( $this, 'settings_page' )
79
		);
80
	}
81
82
	/**
83
	 * Register settings
84
	 */
85
	public function register_options() {
86
87
		register_setting( $this->option_group, $this->option_name );
88
89
		add_settings_section(
90
			'stencil-implementations',
91
			'',
92
			'',
93
			$this->option_page
94
		);
95
96
		add_settings_field(
97
			'implementations',
98
			__( 'Implementations', 'stencil' ),
99
			array( $this, 'option_implementations' ),
100
			$this->option_page,
101
			'stencil-implementations'
102
		);
103
	}
104
105
	/**
106
	 * Show plugins that are not installed yet (but tracked)
107
	 * Check to install; installed plugins are grayed out and checked
108
	 * but are ignored on save.
109
	 */
110
	public function option_implementations() {
111
		foreach ( $this->known_implementations as $slug => $name ) {
112
113
			$attributes = array();
114
			$available  = true;
115
			$base       = $this->option_name;
116
			$error      = '';
117
118
			if ( isset( $this->implementation_php_requirements[ $slug ] ) ) {
119
				if ( version_compare( PHP_VERSION, $this->implementation_php_requirements[ $slug ], '<' ) ) {
120
					$available = false;
121
					$error     = sprintf( __( 'PHP version %s required, %s available.' ), $this->implementation_php_requirements[ $slug ], PHP_VERSION );
122
				}
123
			}
124
125
			$exists = is_dir( WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . $slug );
126
127
			/**
128
			 * Disable input if plugin is installed.
129
			 */
130
			if ( $exists ) {
131
				$attributes[] = 'checked="checked"';
132
			}
133
134
			if ( $exists || ! $available ) {
135
				$attributes[] = 'disabled="disabled"';
136
				$base         = 'dummy';
137
			}
138
139
			printf(
140
				'<label><input type="checkbox" name="%s"%s>%s%s</label><br>',
141
				esc_attr( sprintf( '%s[plugin][%s]', $base, $slug ) ),
142
				implode( ' ', $attributes ),
143
				esc_html( $name ),
144
				! empty( $error ) ? sprintf( ' <small>(%s)</small>', $error ) : ''
145
			);
146
		}
147
	}
148
149
	/**
150
	 * Show the settings
151
	 */
152
	public function settings_page() {
153
154
		/**
155
		 * Show a list of known implementations
156
		 * Mark installed ones
157
		 * Provide checkbox to (bulk) install optional ones
158
		 */
159
160
		print( '<div class="wrap">' );
161
		printf( '<h2>%s</h2>', __( 'Stencil settings', 'stencil' ) );
162
163
		$this->maybe_install_plugins();
164
165
		print( '<form method="post" action="options.php">' );
166
167
		settings_fields( $this->option_group );
168
		do_settings_sections( $this->option_page );
169
		submit_button( __( 'Install selected implementation(s)', 'stencil' ) );
170
171
		print( '</form>' );
172
173
		print( '</div>' );
174
	}
175
176
	/**
177
	 * Install selected plugins
178
	 */
179
	public function maybe_install_plugins() {
180
		/**
181
		 * When a plugin can be updated; the field will be check on the settings
182
		 * When all plugins have been installed, they disappear from the list.
183
		 */
184
		$install_plugins = get_option( $this->option_name );
185
186
		if (
187
			empty( $install_plugins ) ||
188
			! isset( $install_plugins['plugin'] ) ||
189
			! is_array( $install_plugins['plugin'] )
190
		) {
191
			return;
192
		}
193
194
		printf( '<h2>%s</h2>', __( 'Installing plugins...', 'stencil' ) );
195
196
		foreach ( $install_plugins['plugin'] as $slug => $on ) {
197
198
			$installed = $this->install_plugin( $slug );
199
200
			if ( ! $installed ) {
201
				printf(
202
					'<em>%s</em><br>',
203
					sprintf(
204
						__( 'Plugin %s could not be installed!', 'stencil' ),
205
						$this->known_implementations[ $slug ]
206
					)
207
				);
208
			}
209
210
			unset( $install_plugins['plugin'][ $slug ] );
211
		}
212
213
		printf( '<b>%s</b>', __( 'Done.', 'stencil' ) );
214
215
		if ( empty( $install_plugins['plugin'] ) ) {
216
			unset( $install_plugins['plugin'] );
217
		}
218
219
		update_option( $this->option_name, $install_plugins );
220
221
	}
222
223
	/**
224
	 * Install plugin by slug
225
	 *
226
	 * @param string $slug Plugin slug.
227
	 *
228
	 * @return bool
229
	 */
230
	public function install_plugin( $slug ) {
231
		$download_link = $this->get_download_link( $slug );
232
233
		include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
234
235
		iframe_header();
236
		$upgrader = new Plugin_Upgrader( new Plugin_Installer_Skin( array() ) );
237
		$upgrader->install( $download_link );
238
		iframe_footer();
239
240
		return true;
241
	}
242
243
	/**
244
	 * Get the download link for the plugin
245
	 *
246
	 * @param string $slug Plugin slug.
247
	 *
248
	 * @return string
249
	 */
250
	private function get_download_link( $slug ) {
251
		return sprintf( 'https://github.com/moorscode/%s/archive/master.zip', $slug );
252
	}
253
}
254