Completed
Push — master ( df8ec4...96358d )
by Nazar
04:25
created

plugins::admin_plugins_cleanup()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 5
rs 9.4286
cc 1
eloc 4
nc 1
nop 0
1
<?php
2
/**
3
 * @package    CleverStyle CMS
4
 * @subpackage System module
5
 * @category   modules
6
 * @author     Nazar Mokrynskyi <[email protected]>
7
 * @copyright  Copyright (c) 2015, Nazar Mokrynskyi
8
 * @license    MIT License, see license.txt
9
 */
10
namespace cs\modules\System\api\Controller\admin;
11
use
12
	cs\Cache as System_cache,
13
	cs\Config,
14
	cs\Event,
15
	cs\ExitException,
16
	cs\Language,
17
	cs\Page,
18
	cs\Session,
19
	cs\modules\System\Packages_manipulation;
20
trait plugins {
21
	/**
22
	 * @param int[]    $route_ids
23
	 * @param string[] $route_path
24
	 *
25
	 * @throws ExitException
26
	 */
27
	static function admin_plugins_get ($route_ids, $route_path) {
1 ignored issue
show
Unused Code introduced by
The parameter $route_ids is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
28
		if (isset($route_path[3])) {
29
			switch ($route_path[3]) {
30
				/**
31
				 * Get dependent packages for plugin
32
				 */
33
				case 'dependent_packages':
34
					static::get_dependent_packages_for_plugin($route_path[2]);
35
					break;
36
				/**
37
				 * Get dependencies for plugin
38
				 */
39
				case 'dependencies':
40
					static::get_dependencies_for_plugin($route_path[2]);
41
					break;
42
				/**
43
				 * Get dependencies for plugin during update
44
				 */
45
				case 'update_dependencies':
46
					static::get_update_dependencies_for_plugin($route_path[2]);
47
					break;
48
				default:
49
					throw new ExitException(400);
50
			}
51
			return;
52
		}
53
		/**
54
		 * Get array of plugins in extended form
55
		 */
56
		static::get_plugins_list();
57
	}
58
	/**
59
	 * @param string $plugin
60
	 *
61
	 * @throws ExitException
62
	 */
63
	protected static function get_dependent_packages_for_plugin ($plugin) {
64
		if (!in_array($plugin, Config::instance()->components['plugins'])) {
65
			throw new ExitException(404);
66
		}
67
		$meta_file = PLUGINS."/$plugin/meta.json";
68
		Page::instance()->json(
69
			file_exists($meta_file) ? Packages_manipulation::get_dependent_packages(file_get_json($meta_file)) : []
70
		);
71
	}
72
	/**
73
	 * @param string $plugin
74
	 *
75
	 * @throws ExitException
76
	 */
77
	protected static function get_dependencies_for_plugin ($plugin) {
78
		$plugins = get_files_list(PLUGINS, false, 'd');
79
		if (!in_array($plugin, $plugins, true)) {
80
			throw new ExitException(404);
81
		}
82
		$meta_file = PLUGINS."/$plugin/meta.json";
83
		Page::instance()->json(
84
			file_exists($meta_file) ? Packages_manipulation::get_dependencies(file_get_json($meta_file)) : []
85
		);
86
	}
87
	/**
88
	 * @param string $plugin
89
	 *
90
	 * @throws ExitException
91
	 */
92
	protected static function get_update_dependencies_for_plugin ($plugin) {
93
		$plugins = get_files_list(PLUGINS, false, 'd');
94
		if (!in_array($plugin, $plugins, true)) {
95
			throw new ExitException(404);
96
		}
97
		$tmp_location = TEMP.'/System/admin/'.Session::instance()->get_id().'.phar';
98
		if (!file_exists($tmp_location) || !file_exists(PLUGINS."/$plugin/meta.json")) {
99
			throw new ExitException(400);
100
		}
101
		$tmp_dir = "phar://$tmp_location";
102
		if (!file_exists("$tmp_dir/meta.json")) {
103
			throw new ExitException(400);
104
		}
105
		$existing_meta = file_get_json(PLUGINS."/$plugin/meta.json");
106
		$new_meta      = file_get_json("$tmp_dir/meta.json");
107
		if (
108
			$existing_meta['package'] !== $new_meta['package'] ||
109
			$existing_meta['category'] !== $new_meta['category']
110
		) {
111
			throw new ExitException(Language::instance()->this_is_not_plugin_installer_file, 400);
112
		}
113
		Page::instance()->json(
114
			Packages_manipulation::get_dependencies($new_meta)
115
		);
116
	}
117
	protected static function get_plugins_list () {
118
		$Config       = Config::instance();
119
		$plugins      = get_files_list(PLUGINS, false, 'd');
120
		$plugins_list = [];
121
		foreach ($plugins as $plugin_name) {
122
			$plugin = [
123
				'active' => (int)in_array($plugin_name, $Config->components['plugins']),
124
				'name'   => $plugin_name
125
			];
126
			/**
127
			 * Check if readme available
128
			 */
129
			static::check_plugin_feature_availability($plugin, 'readme');
130
			/**
131
			 * Check if license available
132
			 */
133
			static::check_plugin_feature_availability($plugin, 'license');
134
			if (file_exists(PLUGINS."/$plugin_name/meta.json")) {
135
				$plugin['meta'] = file_get_json(PLUGINS."/$plugin_name/meta.json");
136
			}
137
			$plugins_list[] = $plugin;
138
		}
139
		unset($plugin_name, $plugin);
140
		Page::instance()->json($plugins_list);
141
	}
142
	/**
143
	 * @param array  $plugin
144
	 * @param string $feature
145
	 */
146
	protected static function check_plugin_feature_availability (&$plugin, $feature) {
147
		/**
148
		 * Check if feature available
149
		 */
150
		$file = file_exists_with_extension(PLUGINS."/$plugin[name]/$feature", ['txt', 'html']);
151
		if ($file) {
152
			$plugin[$feature] = [
153
				'type'    => substr($file, -3) == 'txt' ? 'txt' : 'html',
154
				'content' => file_get_contents($file)
155
			];
156
		}
157
	}
158
	/**
159
	 * Disable plugin
160
	 *
161
	 * Provides next events:
162
	 *  admin/System/components/plugins/enable/before
163
	 *  ['name' => plugin_name]
164
	 *
165
	 *  admin/System/components/plugins/enable/after
166
	 *  ['name' => plugin_name]
167
	 *
168
	 * @param int[]    $route_ids
169
	 * @param string[] $route_path
170
	 *
171
	 * @throws ExitException
172
	 */
173
	static function admin_plugins_enable ($route_ids, $route_path) {
1 ignored issue
show
Unused Code introduced by
The parameter $route_ids is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
174
		if (!isset($route_path[2])) {
175
			throw new ExitException(400);
176
		}
177
		$Config  = Config::instance();
178
		$plugin  = $route_path[2];
179
		$plugins = get_files_list(PLUGINS, false, 'd');
180
		if (!in_array($plugin, $plugins, true) || in_array($plugin, $Config->components['plugins'])) {
181
			throw new ExitException(400);
182
		}
183
		if (!Event::instance()->fire(
184
			'admin/System/components/plugins/enable/before',
185
			[
186
				'name' => $plugin
187
			]
188
		)
189
		) {
190
			throw new ExitException(500);
191
		}
192
		$Config->components['plugins'][] = $plugin;
193
		if (!$Config->save()) {
194
			throw new ExitException(500);
195
		}
196
		Event::instance()->fire(
197
			'admin/System/components/plugins/enable/before',
198
			[
199
				'name' => $plugin
200
			]
201
		);
202
		static::admin_plugins_cleanup();
203
	}
204
	protected static function admin_plugins_cleanup () {
205
		clean_pcache();
206
		unset(System_cache::instance()->functionality);
207
		clean_classes_cache();
208
	}
209
	/**
210
	 * Disable plugin
211
	 *
212
	 * Provides next events:
213
	 *  admin/System/components/plugins/disable/before
214
	 *  ['name' => plugin_name]
215
	 *
216
	 *  admin/System/components/plugins/disable/after
217
	 *  ['name' => plugin_name]
218
	 *
219
	 * @param int[]    $route_ids
220
	 * @param string[] $route_path
221
	 *
222
	 * @throws ExitException
223
	 */
224
	static function admin_plugins_disable ($route_ids, $route_path) {
1 ignored issue
show
Unused Code introduced by
The parameter $route_ids is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
225
		if (!isset($route_path[2])) {
226
			throw new ExitException(400);
227
		}
228
		$Config       = Config::instance();
229
		$plugin       = $route_path[2];
230
		$plugin_index = array_search($plugin, $Config->components['plugins'], true);
231
		if ($plugin_index === false) {
232
			throw new ExitException(400);
233
		}
234
		if (!Event::instance()->fire(
235
			'admin/System/components/plugins/disable/before',
236
			[
237
				'name' => $plugin
238
			]
239
		)
240
		) {
241
			throw new ExitException(500);
242
		}
243
		unset($Config->components['plugins'][$plugin_index]);
244
		if (!$Config->save()) {
245
			throw new ExitException(500);
246
		}
247
		Event::instance()->fire(
248
			'admin/System/components/plugins/disable/after',
249
			[
250
				'name' => $plugin
251
			]
252
		);
253
		static::admin_plugins_cleanup();
254
	}
255
	/**
256
	 * Extract uploaded plugin
257
	 *
258
	 * @throws ExitException
259
	 */
260
	static function admin_plugins_extract () {
261
		$L            = Language::instance();
262
		$tmp_location = TEMP.'/System/admin/'.Session::instance()->get_id().'.phar';
263
		$tmp_dir      = "phar://$tmp_location";
264
		if (
265
			!file_exists($tmp_location) ||
266
			!file_exists("$tmp_dir/meta.json")
267
		) {
268
			throw new ExitException(400);
269
		}
270
		$new_meta = file_get_json("$tmp_dir/meta.json");
271
		if ($new_meta['category'] !== 'plugins') {
272
			throw new ExitException($L->this_is_not_plugin_installer_file, 400);
273
		}
274
		$plugin_dir = PLUGINS."/$new_meta[package]";
275
		if (
276
			!mkdir($plugin_dir, 0770) ||
277
			!Packages_manipulation::install_extract($plugin_dir, $tmp_location)
278
		) {
279
			throw new ExitException($L->plugin_files_unpacking_error, 500);
280
		}
281
	}
282
	/**
283
	 * Update plugin
284
	 *
285
	 * Provides next events:
286
	 *  admin/System/components/plugins/update/before
287
	 *  ['name' => plugin_name]
288
	 *
289
	 *  admin/System/components/plugins/update/after
290
	 *  ['name' => plugin_name]
291
	 *
292
	 * @param int[]    $route_ids
293
	 * @param string[] $route_path
294
	 *
295
	 * @throws ExitException
296
	 */
297
	static function admin_plugins_update ($route_ids, $route_path) {
298
		if (!isset($route_path[2])) {
299
			throw new ExitException(400);
300
		}
301
		$Config  = Config::instance();
302
		$L       = Language::instance();
303
		$plugin  = $route_path[2];
304
		$plugins = get_files_list(PLUGINS, false, 'd');
305
		if (!in_array($plugin, $plugins, true)) {
306
			throw new ExitException(404);
307
		}
308
		$tmp_location = TEMP.'/System/admin/'.Session::instance()->get_id().'.phar';
309
		$tmp_dir      = "phar://$tmp_location";
310
		$plugin_dir   = PLUGINS."/$plugin";
311
		if (
312
			!file_exists($tmp_location) ||
313
			!file_exists("$plugin_dir/meta.json") ||
314
			!file_exists("$tmp_dir/meta.json")
315
		) {
316
			throw new ExitException(400);
317
		}
318
		$existing_meta = file_get_json("$plugin_dir/meta.json");
319
		$new_meta      = file_get_json("$tmp_dir/meta.json");
320
		$active        = in_array($plugin, $Config->components['plugins']);
321
		// If plugin is currently enabled - disable it temporary
322
		if ($active) {
323
			static::admin_plugins_disable($route_ids, $route_path);
324
		}
325
		if (
326
			$new_meta['package'] !== $plugin ||
327
			$new_meta['category'] !== 'plugins'
328
		) {
329
			throw new ExitException($L->this_is_not_plugin_installer_file, 400);
330
		}
331
		if (!Event::instance()->fire(
332
			'admin/System/components/plugins/update/before',
333
			[
334
				'name' => $plugin
335
			]
336
		)
337
		) {
338
			throw new ExitException(500);
339
		}
340
		if (!is_writable($plugin_dir)) {
341
			throw new ExitException($L->cant_unpack_plugin_no_write_permissions, 500);
342
		}
343
		if (!Packages_manipulation::update_extract(PLUGINS."/$plugin", $tmp_location)) {
344
			throw new ExitException($L->plugin_files_unpacking_error, 500);
345
		}
346
		// Run PHP update scripts if any
347
		Packages_manipulation::update_php_sql(PLUGINS."/$plugin", $existing_meta['version']);
348
		Event::instance()->fire(
349
			'admin/System/components/plugins/update/after',
350
			[
351
				'name' => $plugin
352
			]
353
		);
354
		// If plugin was enabled before update - enable it back
355
		if ($active) {
356
			static::admin_plugins_enable($route_ids, $route_path);
357
		}
358
	}
359
	/**
360
	 * Delete plugin completely
361
	 *
362
	 * @param int[]    $route_ids
363
	 * @param string[] $route_path
364
	 *
365
	 * @throws ExitException
366
	 */
367
	static function admin_plugins_delete ($route_ids, $route_path) {
1 ignored issue
show
Unused Code introduced by
The parameter $route_ids is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
368
		if (!isset($route_path[2])) {
369
			throw new ExitException(400);
370
		}
371
		$plugin  = $route_path[2];
372
		$plugins = get_files_list(PLUGINS, false, 'd');
373
		$Config  = Config::instance();
374
		if (
375
			!in_array($plugin, $plugins, true) ||
376
			in_array($plugin, $Config->components['plugins'])
377
		) {
378
			throw new ExitException(400);
379
		}
380
		if (!rmdir_recursive(PLUGINS."/$plugin")) {
381
			throw new ExitException(500);
382
		}
383
	}
384
}
385