Completed
Push — master ( 0bf5b1...11b1ce )
by Nazar
04:22
created

Builder::generic_package_creation()   C

Complexity

Conditions 12
Paths 193

Size

Total Lines 66
Code Lines 54

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 66
rs 5.4065
cc 12
eloc 54
nc 193
nop 2

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * @package    CleverStyle CMS
4
 * @subpackage Builder
5
 * @author     Nazar Mokrynskyi <[email protected]>
6
 * @copyright  Copyright (c) 2011-2016, Nazar Mokrynskyi
7
 * @license    MIT License, see license.txt
8
 */
9
namespace cs;
10
use
11
	h,
12
	Phar;
13
14
class Builder {
15
	/**
16
	 * @var string
17
	 */
18
	protected $root;
19
	/**
20
	 * @var string
21
	 */
22
	protected $target;
23
	/**
24
	 * @param string $root
25
	 * @param string $target
26
	 */
27
	function __construct ($root, $target) {
28
		$this->root   = $root;
29
		$this->target = $target;
30
		@mkdir($target);
31
	}
32
	/**
33
	 * @param string[]    $modules
34
	 * @param string[]    $plugins
35
	 * @param string[]    $themes
36
	 * @param null|string $suffix
37
	 *
38
	 * @return string
39
	 */
40
	function core ($modules = [], $plugins = [], $themes = [], $suffix = null) {
41
		$suffix      = $suffix ? "_$suffix" : '';
42
		$version     = file_get_json("$this->root/components/modules/System/meta.json")['version'];
43
		$target_file = "$this->target/CleverStyle_CMS_$version$suffix.phar.php";
44
		if (file_exists($target_file)) {
45
			unlink($target_file);
46
		}
47
		$phar = new Phar($target_file);
48
		unset($target_file);
49
		$phar->startBuffering();
50
		$length = strlen("$this->root/");
51
		foreach (get_files_list("$this->root/install", false, 'f', true, true) as $file) {
52
			$phar->addFile($file, substr($file, $length));
53
		}
54
		unset($file);
55
		$phar->addFile("$this->root/includes/img/logo.svg", 'logo.svg');
56
		/**
57
		 * Core files to be included into installation package
58
		 */
59
		$core_files = $this->get_core_files();
60
		/**
61
		 * Add modules that should be built-in into package
62
		 */
63
		$components_files = [];
64
		$modules          = $this->filter_and_add_components("$this->root/components/modules", $modules, $components_files);
65
		$phar->addFromString('modules.json', _json_encode($modules));
66
		/**
67
		 * Add plugins that should be built-in into package
68
		 */
69
		$plugins = $this->filter_and_add_components("$this->root/components/plugins", $plugins, $components_files);
70
		$phar->addFromString('plugins.json', _json_encode($plugins));
71
		/**
72
		 * Add themes that should be built-in into package
73
		 */
74
		$themes = $this->filter_and_add_components("$this->root/themes", $themes, $components_files);
75
		$phar->addFromString('themes.json', _json_encode($themes));
76
		/**
77
		 * Joining system and components files
78
		 */
79
		$core_files = array_merge($core_files, $components_files);
80
		/**
81
		 * Addition of files into package
82
		 */
83
		foreach ($core_files as $index => &$file) {
84
			$phar->addFile($file, "fs/$index");
85
			$file = substr($file, $length);
86
		}
87
		unset($index, $file);
88
		/**
89
		 * Addition of separate files into package
90
		 */
91
		$phar->addFromString(
92
			'languages.json',
93
			_json_encode(
94
				array_merge(
95
					_substr(get_files_list("$this->root/core/languages", '/^.*?\.php$/i', 'f'), 0, -4) ?: [],
96
					_substr(get_files_list("$this->root/core/languages", '/^.*?\.json$/i', 'f'), 0, -5) ?: []
97
				)
98
			)
99
		);
100
		$phar->addFromString(
101
			'db_engines.json',
102
			_json_encode(
103
				_substr(get_files_list("$this->root/core/engines/DB", '/^[^_].*?\.php$/i', 'f'), 0, -4)
104
			)
105
		);
106
		/**
107
		 * Fixation of system files list (without components files), it is needed for future system updating
108
		 */
109
		$phar->addFromString(
110
			'fs/'.count($core_files),
111
			_json_encode(
112
				array_values(
113
					array_diff(
114
						$core_files,
115
						_substr($components_files, $length)
116
					)
117
				)
118
			)
119
		);
120
		$core_files[] = 'core/fs.json';
121
		unset($components_files, $length);
122
		/**
123
		 * Addition of files, that are needed only for installation
124
		 */
125
		$phar->addFromString('fs/'.count($core_files), $this->get_htaccess());
126
		$core_files[] = '.htaccess';
127
		$phar->addFile("$this->root/config/main.php", 'fs/'.count($core_files));
128
		$core_files[] = 'config/main.php';
129
		$phar->addFile("$this->root/favicon.ico", 'fs/'.count($core_files));
130
		$core_files[] = 'favicon.ico';
131
		$phar->addFile("$this->root/.gitignore", 'fs/'.count($core_files));
132
		$core_files[] = '.gitignore';
133
		/**
134
		 * Flip array to have direct access to files by name during extracting and installation, and fixing of files list for installation
135
		 */
136
		$phar->addFromString(
137
			'fs.json',
138
			_json_encode(
139
				array_flip($core_files)
140
			)
141
		);
142
		unset($core_files);
143
		/**
144
		 * Addition of supplementary files, that are needed directly for installation process: installer with GUI interface, readme, license, some additional
145
		 * information about available languages, themes, current version of system
146
		 */
147
		$phar->addFile("$this->root/install.php", 'install.php');
148
		$phar->addFile("$this->root/license.txt", 'license.txt');
149
		$phar->addFile("$this->root/components/modules/System/meta.json", 'meta.json');
150
		$phar->setStub(
151
			<<<STUB
152
<?php
153
if (PHP_SAPI == 'cli') {
154
	Phar::mapPhar('cleverstyle_cms.phar');
155
	include 'phar://cleverstyle_cms.phar/install.php';
156
} else {
157
	Phar::webPhar(null, 'install.php');
158
}
159
__HALT_COMPILER();
160
STUB
161
		);
162
		$phar->stopBuffering();
163
		return "Done! CleverStyle CMS $version";
164
	}
165
	/**
166
	 * Get array of files
167
	 *
168
	 * @return string[]
169
	 */
170
	protected function get_core_files () {
171
		$files_to_include = [
172
			"$this->root/components/modules/System",
173
			"$this->root/components/blocks/.gitkept",
174
			"$this->root/components/plugins/.gitkept",
175
			"$this->root/core",
176
			"$this->root/custom",
177
			"$this->root/includes",
178
			"$this->root/templates",
179
			"$this->root/themes/CleverStyle",
180
			"$this->root/bower.json",
181
			"$this->root/cli",
182
			"$this->root/composer.json",
183
			"$this->root/composer.lock",
184
			"$this->root/index.php",
185
			"$this->root/license.txt",
186
			"$this->root/package.json",
187
			"$this->root/Storage.php"
188
		];
189
		$files            = [];
190
		foreach ($files_to_include as $s) {
191
			if (is_file($s)) {
192
				$files[] = $s;
193
			} elseif (is_dir($s)) {
194
				/** @noinspection SlowArrayOperationsInLoopInspection */
195
				$files = array_merge(
196
					$files,
197
					get_files_list($s, false, 'f', true, true, false, false, true)
198
				);
199
			}
200
		}
201
		return $files;
202
	}
203
	/**
204
	 * @param string   $dir
205
	 * @param string[] $components
206
	 * @param string[] $components_files
207
	 *
208
	 * @return string[]
209
	 */
210
	protected function filter_and_add_components ($dir, $components, &$components_files) {
211
		$components = array_filter(
212
			$components,
213
			function ($component) use ($dir, &$components_files) {
214
				return $this->get_component_files("$dir/$component", $components_files);
215
			}
216
		);
217
		sort($components);
218
		return $components;
219
	}
220
	/**
221
	 * @param string   $component_root
222
	 * @param string[] $files Array, where new files will be appended
223
	 *
224
	 * @return bool
225
	 */
226
	protected function get_component_files ($component_root, &$files) {
227
		/**
228
		 * Do not allow building System module and CleverStyle theme
229
		 */
230
		if (in_array(basename($component_root), ['System', 'CleverStyle'])) {
231
			return false;
232
		}
233
		/**
234
		 * Components without meta.json also not allowed
235
		 */
236
		if (!file_exists("$component_root/meta.json")) {
237
			return false;
238
		}
239
		@unlink("$component_root/fs.json");
240
		$local_files = get_files_list($component_root, false, 'f', true, true, false, false, true);
241
		$files       = array_merge($files, $local_files);
242
		file_put_json(
243
			"$component_root/fs.json",
244
			array_values(
245
				_substr(
246
					$local_files,
247
					strlen("$component_root/")
248
				)
249
			)
250
		);
251
		$files[] = "$component_root/fs.json";
252
		return true;
253
	}
254
	/**
255
	 * @return string
256
	 */
257
	protected function get_htaccess () {
258
		/** @lang ApacheConfig */
259
		return <<<HTACCESS
260
AddDefaultCharset utf-8
261
Options -Indexes -Multiviews +FollowSymLinks
262
IndexIgnore *.php *.pl *.cgi *.htaccess *.htpasswd
263
264
RewriteEngine On
265
RewriteBase /
266
267
<FilesMatch ".*/.*">
268
	Options -FollowSymLinks
269
</FilesMatch>
270
<FilesMatch "\.(css|js|gif|jpg|jpeg|png|ico|svg|svgz|ttc|ttf|otf|woff|woff2|eot)$">
271
	RewriteEngine Off
272
</FilesMatch>
273
<Files license.txt>
274
	RewriteEngine Off
275
</Files>
276
#<Files Storage.php>
277
#	RewriteEngine Off
278
#</Files>
279
280
RewriteRule .* index.php
281
HTACCESS;
282
	}
283
	/**
284
	 * @param string      $module
285
	 * @param null|string $suffix
286
	 *
287
	 * @return string
288
	 */
289
	function module ($module, $suffix = null) {
290
		if ($module == 'System') {
291
			return "Can't build module, System module is a part of core, it is not necessary to build it as separate module";
292
		}
293
		return $this->generic_package_creation("$this->root/components/modules/$module", $suffix);
294
	}
295
	/**
296
	 * @param string      $plugin
297
	 * @param null|string $suffix
298
	 *
299
	 * @return string
300
	 */
301
	function plugin ($plugin, $suffix = null) {
302
		return $this->generic_package_creation("$this->root/components/plugins/$plugin", $suffix);
303
	}
304
	/**
305
	 * @param string      $theme
306
	 * @param null|string $suffix
307
	 *
308
	 * @return string
309
	 */
310
	function theme ($theme, $suffix = null) {
311
		if ($theme == 'CleverStyle') {
312
			return "Can't build theme, CleverStyle theme is a part of core, it is not necessary to build it as separate theme";
313
		}
314
		return $this->generic_package_creation("$this->root/themes/$theme", $suffix);
315
	}
316
	protected function generic_package_creation ($source_dir, $suffix = null) {
317
		if (!file_exists("$source_dir/meta.json")) {
318
			$component = basename($source_dir);
319
			return "Can't build $component, meta information (meta.json) not found";
320
		}
321
		$meta = file_get_json("$source_dir/meta.json");
322
		$type = '';
323
		$Type = '';
324
		switch ($meta['category']) {
325
			case 'modules':
326
				$type = 'module_';
327
				$Type = 'Module';
328
				break;
329
			case 'plugins':
330
				$type = 'plugins_';
331
				$Type = 'Plugin';
332
				break;
333
			case 'themes':
334
				$type = 'theme_';
335
				$Type = 'Theme';
336
				break;
337
		}
338
		$suffix      = $suffix ? "_$suffix" : '';
339
		$target_file = "$this->target/$type$meta[package]_$meta[version]$suffix.phar.php";
340
		if (file_exists($target_file)) {
341
			unlink($target_file);
342
		}
343
		$phar = new Phar($target_file);
344
		unset($target_file);
345
		$phar->startBuffering();
346
		@unlink("$source_dir/fs.json");
347
		$files  = get_files_list($source_dir, false, 'f', true, true, false, false, true);
348
		$length = strlen("$source_dir/");
349
		foreach ($files as $index => &$file) {
350
			$phar->addFile($file, "fs/$index");
351
			$file = substr($file, $length);
352
		}
353
		unset($index, $file, $length);
354
		/**
355
		 * Flip array to have direct access to files by name during extraction
356
		 */
357
		$phar->addFromString(
358
			'fs.json',
359
			_json_encode(
360
				array_flip($files)
361
			)
362
		);
363
		unset($files);
364
		$phar->addFile("$source_dir/meta.json", 'meta.json');
365
		$readme = false;
366
		if (file_exists("$source_dir/readme.html")) {
367
			$phar->addFile("$source_dir/readme.html", 'readme.html');
368
			$readme = 'readme.html';
369
		} elseif (file_exists("$source_dir/readme.txt")) {
370
			$phar->addFile("$source_dir/readme.txt", 'readme.txt');
371
			$readme = 'readme.txt';
372
		}
373
		if ($readme) {
374
			$phar->setStub("<?php Phar::webPhar(null, '$readme'); __HALT_COMPILER();");
375
		} else {
376
			$phar->addFromString('index.html', isset($meta['description']) ? $meta['description'] : $meta['package']);
377
			$phar->setStub("<?php Phar::webPhar(null, 'index.html'); __HALT_COMPILER();");
378
		}
379
		$phar->stopBuffering();
380
		return "Done! $Type $meta[package] $meta[version]";
381
	}
382
}
383