Completed
Push — master ( a2c8d4...3a88fc )
by Nazar
07:08
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 2
Bugs 0 Features 0
Metric Value
cc 7
eloc 64
c 2
b 0
f 0
nc 16
nop 3
dl 0
loc 124
rs 6.4589
ccs 51
cts 52
cp 0.9808
crap 7.0003

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 11
	function __construct ($root, $target) {
27 11
		$this->root   = $root;
28 11
		$this->target = $target;
29 11
		@mkdir($target);
30 11
	}
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/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/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/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/modules/System",
170 4
			"$this->root/blocks/.gitkept",
171 4
			"$this->root/core",
172 4
			"$this->root/custom",
173 4
			"$this->root/includes",
174 4
			"$this->root/themes/CleverStyle",
175 4
			"$this->root/bower.json",
176 4
			"$this->root/cli",
177 4
			"$this->root/composer.json",
178 4
			"$this->root/composer.lock",
179 4
			"$this->root/index.php",
180 4
			"$this->root/license.txt",
181 4
			"$this->root/package.json",
182 4
			"$this->root/Storage.php"
183
		];
184 4
		$files            = [];
185 4
		foreach ($files_to_include as $s) {
186 4
			if (is_file($s)) {
187 4
				$files[] = $s;
188 4
			} elseif (is_dir($s)) {
189
				/** @noinspection SlowArrayOperationsInLoopInspection */
190 4
				$files = array_merge(
191
					$files,
192 4
					get_files_list($s, false, 'f', true, true, false, false, true)
193
				);
194
			}
195
		}
196 4
		return $files;
197
	}
198
	/**
199
	 * @param string   $dir
200
	 * @param string[] $components
201
	 * @param string[] $components_files
202
	 *
203
	 * @return string[]
204
	 */
205 4
	protected function filter_and_add_components ($dir, $components, &$components_files) {
206 4
		$components = array_filter(
207
			$components,
208 4
			function ($component) use ($dir, &$components_files) {
209
				return $this->get_component_files("$dir/$component", $components_files);
210 4
			}
211
		);
212 4
		sort($components);
213 4
		return $components;
214
	}
215
	/**
216
	 * @param string   $component_root
217
	 * @param string[] $files Array, where new files will be appended
218
	 *
219
	 * @return bool
220
	 */
221
	protected function get_component_files ($component_root, &$files) {
222
		/**
223
		 * Do not allow building System module and CleverStyle theme
224
		 */
225
		if (in_array(basename($component_root), ['System', 'CleverStyle'])) {
226
			return false;
227
		}
228
		/**
229
		 * Components without meta.json also not allowed
230
		 */
231
		if (!file_exists("$component_root/meta.json")) {
232
			return false;
233
		}
234
		@unlink("$component_root/fs.json");
235
		$local_files = get_files_list($component_root, false, 'f', true, true, false, false, true);
236
		$files       = array_merge($files, $local_files);
237
		file_put_json(
238
			"$component_root/fs.json",
239
			array_values(
240
				_substr(
241
					$local_files,
242
					strlen("$component_root/")
243
				)
244
			)
245
		);
246
		$files[] = "$component_root/fs.json";
247
		return true;
248
	}
249
	/**
250
	 * @return string
251
	 */
252 4
	protected function get_htaccess () {
253
		/** @lang ApacheConfig */
254
		return <<<HTACCESS
255
AddDefaultCharset utf-8
256
Options -Indexes -Multiviews +FollowSymLinks
257
IndexIgnore *.php *.pl *.cgi *.htaccess *.htpasswd
258
259
RewriteEngine On
260
RewriteBase /
261
262
<FilesMatch ".*/.*">
263
	Options -FollowSymLinks
264
</FilesMatch>
265
<FilesMatch "\.(css|js|gif|jpg|jpeg|png|ico|svg|svgz|ttc|ttf|otf|woff|woff2|eot)$">
266
	RewriteEngine Off
267
</FilesMatch>
268
<Files license.txt>
269
	RewriteEngine Off
270
</Files>
271
#<Files Storage.php>
272
#	RewriteEngine Off
273
#</Files>
274
275 4
RewriteRule .* index.php
276
HTACCESS;
277
	}
278
	/**
279
	 * @param string      $module
280
	 * @param null|string $suffix
281
	 *
282
	 * @return string
283
	 */
284
	function module ($module, $suffix = null) {
285
		if ($module == 'System') {
286
			return "Can't build module, System module is a part of core, it is not necessary to build it as separate module";
287
		}
288
		return $this->generic_package_creation("$this->root/modules/$module", $suffix);
289
	}
290
	/**
291
	 * @param string      $theme
292
	 * @param null|string $suffix
293
	 *
294
	 * @return string
295
	 */
296
	function theme ($theme, $suffix = null) {
297
		if ($theme == 'CleverStyle') {
298
			return "Can't build theme, CleverStyle theme is a part of core, it is not necessary to build it as separate theme";
299
		}
300
		return $this->generic_package_creation("$this->root/themes/$theme", $suffix);
301
	}
302
	protected function generic_package_creation ($source_dir, $suffix = null) {
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
303
		if (!file_exists("$source_dir/meta.json")) {
304
			$component = basename($source_dir);
305
			return "Can't build $component, meta information (meta.json) not found";
306
		}
307
		$meta = file_get_json("$source_dir/meta.json");
308
		$type = '';
309
		$Type = '';
310
		switch ($meta['category']) {
311
			case 'modules':
312
				$type = 'module_';
313
				$Type = 'Module';
314
				break;
315
			case 'themes':
316
				$type = 'theme_';
317
				$Type = 'Theme';
318
				break;
319
		}
320
		$suffix      = $suffix ? "_$suffix" : '';
321
		$target_file = "$this->target/$type$meta[package]_$meta[version]$suffix.phar.php";
322
		if (file_exists($target_file)) {
323
			unlink($target_file);
324
		}
325
		$phar = new Phar($target_file);
326
		unset($target_file);
327
		$phar->startBuffering();
328
		@unlink("$source_dir/fs.json");
329
		$files  = get_files_list($source_dir, false, 'f', true, true, false, false, true);
330
		$length = strlen("$source_dir/");
331
		foreach ($files as $index => &$file) {
332
			$phar->addFile($file, "fs/$index");
333
			$file = substr($file, $length);
334
		}
335
		unset($index, $file, $length);
336
		/**
337
		 * Flip array to have direct access to files by name during extraction
338
		 */
339
		$phar->addFromString(
340
			'fs.json',
341
			_json_encode(
342
				array_flip($files)
343
			)
344
		);
345
		unset($files);
346
		$phar->addFile("$source_dir/meta.json", 'meta.json');
347
		$readme = false;
348
		if (file_exists("$source_dir/readme.html")) {
349
			$phar->addFile("$source_dir/readme.html", 'readme.html');
350
			$readme = 'readme.html';
351
		} elseif (file_exists("$source_dir/readme.txt")) {
352
			$phar->addFile("$source_dir/readme.txt", 'readme.txt');
353
			$readme = 'readme.txt';
354
		}
355
		if ($readme) {
356
			$phar->setStub("<?php Phar::webPhar(null, '$readme'); __HALT_COMPILER();");
357
		} else {
358
			$phar->addFromString('index.html', isset($meta['description']) ? $meta['description'] : $meta['package']);
359
			$phar->setStub("<?php Phar::webPhar(null, 'index.html'); __HALT_COMPILER();");
360
		}
361
		$phar->stopBuffering();
362
		return "Done! $Type $meta[package] $meta[version]";
363
	}
364
}
365