Completed
Push — master ( 67d50f...8a7d08 )
by Nazar
04:56
created

Builder::core()   C

Complexity

Conditions 7
Paths 16

Size

Total Lines 124
Code Lines 64

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 51
CRAP Score 7.0003

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
eloc 64
c 1
b 0
f 0
nc 16
nop 3
dl 0
loc 124
ccs 51
cts 52
cp 0.9808
crap 7.0003
rs 6.4589

How to fix   Long Method   

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