Completed
Push — master ( c78c55...a2ae2e )
by Nazar
04:43
created

themes::get_themes_list()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 24
Code Lines 14

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 24
rs 8.9713
cc 3
eloc 14
nc 3
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-2016, Nazar Mokrynskyi
8
 * @license    MIT License, see license.txt
9
 */
10
namespace cs\modules\System\api\Controller\admin;
11
use
12
	cs\Config,
13
	cs\Event,
14
	cs\ExitException,
15
	cs\Language,
16
	cs\Page,
17
	cs\Session,
18
	cs\modules\System\Packages_manipulation;
19
20
trait themes {
21
	/**
22
	 * @param \cs\Request $Request
23
	 *
24
	 * @throws ExitException
25
	 */
26
	static function admin_themes_get ($Request) {
27
		if ($Request->route_path(3) == 'update_dependencies') {
28
			/**
29
			 * Get dependencies for theme during update
30
			 */
31
			static::get_update_dependencies_for_theme($Request->route_path[2]);
32
		} elseif ($Request->route_path(2) == 'current') {
33
			/**
34
			 * Get current theme
35
			 */
36
			static::get_current_theme();
37
		} else {
38
			/**
39
			 * Get array of themes in extended form
40
			 */
41
			static::get_themes_list();
42
		}
43
	}
44
	/**
45
	 * @param string $theme
46
	 *
47
	 * @throws ExitException
48
	 */
49
	protected static function get_update_dependencies_for_theme ($theme) {
50
		$themes = get_files_list(THEMES, false, 'd');
51
		if (!in_array($theme, $themes, true)) {
52
			throw new ExitException(404);
53
		}
54
		$tmp_location = TEMP.'/System/admin/'.Session::instance()->get_id().'.phar';
55
		$tmp_dir      = "phar://$tmp_location";
56
		if (
57
			!file_exists(THEMES."/$theme/meta.json") ||
58
			!file_exists("$tmp_dir/meta.json")
59
		) {
60
			throw new ExitException(400);
61
		}
62
		$existing_meta = file_get_json(THEMES."/$theme/meta.json");
63
		$new_meta      = file_get_json("$tmp_dir/meta.json");
64
		if (
65
			$existing_meta['package'] !== $new_meta['package'] ||
66
			$existing_meta['category'] !== $new_meta['category']
67
		) {
68
			throw new ExitException(Language::instance()->this_is_not_theme_installer_file, 400);
69
		}
70
		$dependencies = [];
71
		if (version_compare($new_meta['version'], $existing_meta['version'], '<')) {
72
			$dependencies['update_older'] = [
73
				'from' => $existing_meta['version'],
74
				'to'   => $new_meta['version']
75
			];
76
		}
77
		Page::instance()->json($dependencies);
78
	}
79
	protected static function get_current_theme () {
80
		Page::instance()->json(
81
			Config::instance()->core['theme']
82
		);
83
	}
84
	protected static function get_themes_list () {
85
		$themes = get_files_list(THEMES, false, 'd');
86
		asort($themes);
87
		$themes_list = [];
88
		foreach ($themes as $theme_name) {
89
			$theme = [
90
				'name' => $theme_name
91
			];
92
			/**
93
			 * Check if readme available
94
			 */
95
			static::check_theme_feature_availability($theme, 'readme');
96
			/**
97
			 * Check if license available
98
			 */
99
			static::check_theme_feature_availability($theme, 'license');
100
			if (file_exists(THEMES."/$theme_name/meta.json")) {
101
				$theme['meta'] = file_get_json(THEMES."/$theme_name/meta.json");
102
			}
103
			$themes_list[] = $theme;
104
		}
105
		unset($theme_name, $theme);
106
		Page::instance()->json($themes_list);
107
	}
108
	/**
109
	 * @param array  $theme
110
	 * @param string $feature
111
	 */
112
	protected static function check_theme_feature_availability (&$theme, $feature) {
113
		/**
114
		 * Check if feature available
115
		 */
116
		$file = file_exists_with_extension(THEMES."/$theme[name]/$feature", ['txt', 'html']);
117
		if ($file) {
118
			$theme[$feature] = [
119
				'type'    => substr($file, -3) == 'txt' ? 'txt' : 'html',
120
				'content' => file_get_contents($file)
121
			];
122
		}
123
	}
124
	/**
125
	 * @param \cs\Request $Request
126
	 *
127
	 * @throws ExitException
128
	 */
129
	static function admin_themes_put ($Request) {
130
		if ($Request->route_path(2) == 'current') {
131
			if (!isset($_POST['theme'])) {
132
				throw new ExitException(400);
133
			}
134
			/**
135
			 * Set current theme
136
			 */
137
			static::set_current_theme($_POST['theme']);
138
		} else {
139
			throw new ExitException(400);
140
		}
141
	}
142
	/**
143
	 * Provides next events:
144
	 *  admin/System/components/themes/current/before
145
	 *  ['name' => theme_name]
146
	 *
147
	 *  admin/System/components/themes/current/after
148
	 *  ['name' => theme_name]
149
	 *
150
	 * @param string $theme
151
	 *
152
	 * @throws ExitException
153
	 */
154
	protected static function set_current_theme ($theme) {
155
		$Config = Config::instance();
156
		$themes = get_files_list(THEMES, false, 'd');
157
		if (!in_array($theme, $themes, true)) {
158
			throw new ExitException(404);
159
		}
160
		if ($theme == $Config->core['theme']) {
161
			throw new ExitException(400);
162
		}
163
		if (!Event::instance()->fire(
164
			'admin/System/components/themes/current/before',
165
			[
166
				'name' => $theme
167
			]
168
		)
169
		) {
170
			throw new ExitException(500);
171
		}
172
		$Config->core['theme'] = $theme;
173
		if (!$Config->save()) {
174
			throw new ExitException(500);
175
		}
176
		Event::instance()->fire(
177
			'admin/System/components/themes/current/after',
178
			[
179
				'name' => $theme
180
			]
181
		);
182
	}
183
	/**
184
	 * Extract uploaded theme
185
	 *
186
	 * @throws ExitException
187
	 */
188
	static function admin_themes_extract () {
189
		$L            = Language::instance();
190
		$tmp_location = TEMP.'/System/admin/'.Session::instance()->get_id().'.phar';
191
		$tmp_dir      = "phar://$tmp_location";
192
		if (
193
			!file_exists($tmp_location) ||
194
			!file_exists("$tmp_dir/meta.json")
195
		) {
196
			throw new ExitException(400);
197
		}
198
		$new_meta = file_get_json("$tmp_dir/meta.json");
199
		if ($new_meta['category'] !== 'themes') {
200
			throw new ExitException($L->this_is_not_theme_installer_file, 400);
201
		}
202
		if (!Packages_manipulation::install_extract(THEMES."/$new_meta[package]", $tmp_location)) {
203
			throw new ExitException($L->theme_files_unpacking_error, 500);
204
		}
205
	}
206
	/**
207
	 * Update theme
208
	 *
209
	 * Provides next events:
210
	 *  admin/System/components/themes/update/before
211
	 *  ['name' => theme_name]
212
	 *
213
	 *  admin/System/components/themes/update/after
214
	 *  ['name' => theme_name]
215
	 *
216
	 * @param \cs\Request $Request
217
	 *
218
	 * @throws ExitException
219
	 */
220
	static function admin_themes_update ($Request) {
221
		$L      = Language::instance();
222
		$theme  = $Request->route_path(2);
223
		$themes = get_files_list(THEMES, false, 'd');
224
		if (!in_array($theme, $themes, true)) {
225
			throw new ExitException(404);
226
		}
227
		$tmp_location = TEMP.'/System/admin/'.Session::instance()->get_id().'.phar';
228
		$tmp_dir      = "phar://$tmp_location";
229
		$theme_dir    = THEMES."/$theme";
230
		if (
231
			!file_exists($tmp_location) ||
232
			!file_exists("$theme_dir/meta.json") ||
233
			!file_exists("$tmp_dir/meta.json")
234
		) {
235
			throw new ExitException(400);
236
		}
237
		$new_meta = file_get_json("$tmp_dir/meta.json");
238
		if (
239
			$new_meta['package'] !== $theme ||
240
			$new_meta['category'] !== 'themes'
241
		) {
242
			throw new ExitException($L->this_is_not_theme_installer_file, 400);
243
		}
244
		if (!Event::instance()->fire(
245
			'admin/System/components/themes/update/before',
246
			[
247
				'name' => $theme
248
			]
249
		)
250
		) {
251
			throw new ExitException(500);
252
		}
253
		if (!is_writable($theme_dir)) {
254
			throw new ExitException($L->cant_unpack_theme_no_write_permissions, 500);
255
		}
256
		if (!Packages_manipulation::update_extract(THEMES."/$theme", $tmp_location)) {
257
			throw new ExitException($L->theme_files_unpacking_error, 500);
258
		}
259
		Event::instance()->fire(
260
			'admin/System/components/themes/update/after',
261
			[
262
				'name' => $theme
263
			]
264
		);
265
	}
266
	/**
267
	 * Delete theme completely
268
	 *
269
	 * @param \cs\Request $Request
270
	 *
271
	 * @throws ExitException
272
	 */
273
	static function admin_themes_delete ($Request) {
274
		$Config = Config::instance();
275
		$theme  = $Request->route_path(2);
276
		$themes = get_files_list(THEMES, false, 'd');
277
		if (
278
			$theme == Config::SYSTEM_THEME ||
279
			$Config->core['theme'] == $theme ||
280
			!in_array($theme, $themes, true)
281
		) {
282
			throw new ExitException(400);
283
		}
284
		if (!rmdir_recursive(THEMES."/$theme")) {
285
			throw new ExitException(500);
286
		}
287
	}
288
}
289