Completed
Push — master ( 2b55e1...74d3c9 )
by Nazar
03:53
created

themes   B

Complexity

Total Complexity 45

Size/Duplication

Total Lines 278
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 278
rs 8.3673
c 1
b 0
f 0
wmc 45
lcom 1
cbo 7

10 Methods

Rating   Name   Duplication   Size   Complexity  
A check_theme_feature_availability() 0 12 3
B set_current_theme() 0 29 5
B admin_themes_extract() 0 18 5
A admin_themes_put() 0 14 3
A admin_themes_get() 0 18 3
C get_update_dependencies_for_theme() 0 30 7
A get_current_theme() 0 3 1
A get_themes_list() 0 23 3
C admin_themes_update() 0 47 10
B admin_themes_delete() 0 15 5

How to fix   Complexity   

Complex Class

Complex classes like themes often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use themes, and based on these observations, apply Extract Interface, too.

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