Completed
Push — master ( 59445a...e38094 )
by Nazar
11:05
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 5
Bugs 2 Features 2
Metric Value
cc 7
eloc 64
c 5
b 2
f 2
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 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 7
	function core ($modules = [], $themes = [], $suffix = null) {
39 7
		$suffix      = $suffix ? "_$suffix" : '';
40 7
		$version     = file_get_json("$this->root/modules/System/meta.json")['version'];
41 7
		$target_file = "$this->target/CleverStyle_Framework_$version$suffix.phar.php";
42 7
		if (file_exists($target_file)) {
43
			unlink($target_file);
44
		}
45 7
		$phar = new Phar($target_file);
46 7
		unset($target_file);
47 7
		$phar->startBuffering();
48 7
		$length = strlen("$this->root/");
49 7
		foreach (get_files_list("$this->root/install", false, 'f', '', true) as $file) {
50 7
			$phar->addFile("$this->root/install/$file", $file);
51
		}
52 7
		unset($file);
53 7
		$phar->addFile("$this->root/includes/img/logo.svg", 'logo.svg');
54
		/**
55
		 * Core files to be included into installation package
56
		 */
57 7
		$core_files = $this->get_core_files();
58
		/**
59
		 * Add modules that should be built-in into package
60
		 */
61 7
		$components_files = [];
62 7
		$modules          = $this->filter_and_add_components("$this->root/modules", $modules, $components_files);
63 7
		$phar->addFromString('modules.json', _json_encode($modules));
64
		/**
65
		 * Add themes that should be built-in into package
66
		 */
67 7
		$themes = $this->filter_and_add_components("$this->root/themes", $themes, $components_files);
68 7
		$phar->addFromString('themes.json', _json_encode($themes));
69
		/**
70
		 * Joining system and components files
71
		 */
72 7
		$core_files = array_merge($core_files, $components_files);
73
		/**
74
		 * Addition of files into package
75
		 */
76 7
		foreach ($core_files as $index => &$file) {
77 7
			$phar->addFile($file, "fs/$index");
78 7
			$file = substr($file, $length);
79
		}
80 7
		unset($index, $file);
81
		/**
82
		 * Addition of separate files into package
83
		 */
84 7
		$phar->addFromString(
85 7
			'languages.json',
86
			_json_encode(
87
				array_merge(
88 7
					_substr(get_files_list("$this->root/core/languages", '/^.*?\.php$/i', 'f'), 0, -4) ?: [],
89 7
					_substr(get_files_list("$this->root/core/languages", '/^.*?\.json$/i', 'f'), 0, -5) ?: []
90
				)
91
			)
92
		);
93 7
		$phar->addFromString(
94 7
			'db_engines.json',
95
			_json_encode(
96 7
				_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 7
		$phar->addFromString(
103 7
			'fs.json',
104
			_json_encode(
105
				array_flip(
106
					array_diff(
107
						$core_files,
108
						_substr($components_files, $length)
109
					)
110
				)
111
			)
112
		);
113 7
		unset($components_files, $length);
114
		/**
115
		 * Addition of files, that are needed only for installation
116
		 */
117 7
		$phar->addFromString('fs/'.count($core_files), $this->get_htaccess());
118 7
		$core_files[] = '.htaccess';
119 7
		$phar->addFile("$this->root/config/main.php", 'fs/'.count($core_files));
120 7
		$core_files[] = 'config/main.php';
121 7
		$phar->addFile("$this->root/favicon.ico", 'fs/'.count($core_files));
122 7
		$core_files[] = 'favicon.ico';
123 7
		$phar->addFile("$this->root/.gitignore", 'fs/'.count($core_files));
124 7
		$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 7
		$phar->addFromString(
129 7
			'fs_installer.json',
130
			_json_encode(
131
				array_flip($core_files)
132
			)
133
		);
134 7
		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 7
		$phar->addFile("$this->root/license.txt", 'license.txt');
140 7
		$phar->addFile("$this->root/modules/System/meta.json", 'meta.json');
141 7
		$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 7
__HALT_COMPILER();
157
STUB
158
		);
159 7
		$phar->stopBuffering();
160 7
		return "Done! CleverStyle Framework $version";
161
	}
162
	/**
163
	 * Get array of files
164
	 *
165
	 * @return string[]
166
	 */
167 7
	protected function get_core_files () {
168
		$files_to_include = [
169 7
			"$this->root/modules/System",
170 7
			"$this->root/blocks/.gitkept",
171 7
			"$this->root/core",
172 7
			"$this->root/custom",
173 7
			"$this->root/includes",
174 7
			"$this->root/storage/.htaccess",
175 7
			"$this->root/storage/pcache/.htaccess",
176 7
			"$this->root/storage/public/.htaccess",
177 7
			"$this->root/storage/temp/.htaccess",
178 7
			"$this->root/themes/CleverStyle",
179 7
			"$this->root/bower.json",
180 7
			"$this->root/cli",
181 7
			"$this->root/composer.json",
182 7
			"$this->root/composer.lock",
183 7
			"$this->root/index.php",
184 7
			"$this->root/license.txt",
185 7
			"$this->root/package.json"
186
		];
187 7
		$files            = [];
188 7
		foreach ($files_to_include as $s) {
189 7
			if (is_file($s)) {
190 7
				$files[] = $s;
191 7
			} elseif (is_dir($s)) {
192
				/** @noinspection SlowArrayOperationsInLoopInspection */
193 7
				$files = array_merge(
194
					$files,
195 7
					get_files_list($s, false, 'f', true, true, false, false, true)
196
				);
197
			}
198
		}
199 7
		return $files;
200
	}
201
	/**
202
	 * @param string   $dir
203
	 * @param string[] $components
204
	 * @param string[] $components_files
205
	 *
206
	 * @return string[]
207
	 */
208 7
	protected function filter_and_add_components ($dir, $components, &$components_files) {
209 7
		$components = array_filter(
210
			$components,
211 7
			function ($component) use ($dir, &$components_files) {
212 1
				return $this->get_component_files("$dir/$component", $components_files);
213 7
			}
214
		);
215 7
		sort($components);
216 7
		return $components;
217
	}
218
	/**
219
	 * @param string   $component_root
220
	 * @param string[] $files Array, where new files will be appended
221
	 *
222
	 * @return bool
223
	 */
224 1
	protected function get_component_files ($component_root, &$files) {
225
		/**
226
		 * Do not allow building System module and CleverStyle theme
227
		 */
228 1
		if (in_array(basename($component_root), ['System', 'CleverStyle'])) {
229
			return false;
230
		}
231
		/**
232
		 * Components without meta.json also not allowed
233
		 */
234 1
		if (!file_exists("$component_root/meta.json")) {
235
			return false;
236
		}
237 1
		@unlink("$component_root/fs.json");
238 1
		$local_files = get_files_list($component_root, false, 'f', true, true, false, false, true);
239 1
		$files       = array_merge($files, $local_files);
240 1
		file_put_json(
241 1
			"$component_root/fs.json",
242
			array_values(
243
				_substr(
244
					$local_files,
245 1
					strlen("$component_root/")
246
				)
247
			)
248
		);
249 1
		$files[] = "$component_root/fs.json";
250 1
		return true;
251
	}
252
	/**
253
	 * @return string
254
	 */
255 7
	protected function get_htaccess () {
256
		/** @lang ApacheConfig */
257
		return <<<HTACCESS
258
AddDefaultCharset utf-8
259
Options -Indexes -Multiviews +FollowSymLinks
260
IndexIgnore *.php *.pl *.cgi *.htaccess *.htpasswd
261
FileETag None
262
263
RewriteEngine On
264
RewriteBase /
265
266
<FilesMatch ".*/.*">
267
	Options -FollowSymLinks
268
</FilesMatch>
269
<FilesMatch "\.(css|js|gif|jpg|jpeg|png|ico|svg|svgz|ttc|ttf|otf|woff|woff2|eot)$">
270
	RewriteEngine Off
271
</FilesMatch>
272
<FilesMatch "\.(css|js|gif|jpg|jpeg|png|ico|svg|svgz|ttc|ttf|otf|woff|woff2|eot|html)$">
273
	<ifModule mod_expires.c>
274
		ExpiresActive On
275
		ExpiresDefault "access plus 1 month"
276
	</ifModule>
277
	<ifModule mod_headers.c>
278
		Header set Cache-Control "max-age=2592000, public"
279
	</ifModule>
280
</FilesMatch>
281
<Files license.txt>
282
	RewriteEngine Off
283
</Files>
284
285 7
RewriteRule .* index.php
286
HTACCESS;
287
	}
288
	/**
289
	 * @param string      $module
290
	 * @param null|string $suffix
291
	 *
292
	 * @return string
293
	 */
294 2
	function module ($module, $suffix = null) {
295 2
		if ($module == 'System') {
296
			return "Can't build module, System module is a part of core, it is not necessary to build it as separate module";
297
		}
298 2
		return $this->generic_package_creation("$this->root/modules/$module", $suffix);
299
	}
300
	/**
301
	 * @param string      $theme
302
	 * @param null|string $suffix
303
	 *
304
	 * @return string
305
	 */
306 2
	function theme ($theme, $suffix = null) {
307 2
		if ($theme == 'CleverStyle') {
308
			return "Can't build theme, CleverStyle theme is a part of core, it is not necessary to build it as separate theme";
309
		}
310 2
		return $this->generic_package_creation("$this->root/themes/$theme", $suffix);
311
	}
312 4
	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...
313 4
		if (!file_exists("$source_dir/meta.json")) {
314
			$component = basename($source_dir);
315
			return "Can't build $component, meta information (meta.json) not found";
316
		}
317 4
		$meta = file_get_json("$source_dir/meta.json");
318 4
		$type = '';
319 4
		$Type = '';
320 4
		switch ($meta['category']) {
321 4
			case 'modules':
322 2
				$type = 'module_';
323 2
				$Type = 'Module';
324 2
				break;
325 2
			case 'themes':
326 2
				$type = 'theme_';
327 2
				$Type = 'Theme';
328 2
				break;
329
		}
330 4
		$suffix      = $suffix ? "_$suffix" : '';
331 4
		$target_file = "$this->target/$type$meta[package]_$meta[version]$suffix.phar.php";
332 4
		if (file_exists($target_file)) {
333
			unlink($target_file);
334
		}
335 4
		$phar = new Phar($target_file);
336 4
		unset($target_file);
337 4
		$phar->startBuffering();
338 4
		@unlink("$source_dir/fs.json");
339 4
		$files  = get_files_list($source_dir, false, 'f', true, true, false, false, true);
340 4
		$length = strlen("$source_dir/");
341 4
		foreach ($files as $index => &$file) {
342 4
			$phar->addFile($file, "fs/$index");
343 4
			$file = substr($file, $length);
344
		}
345 4
		unset($index, $file, $length);
346
		/**
347
		 * Flip array to have direct access to files by name during extraction
348
		 */
349 4
		$phar->addFromString(
350 4
			'fs.json',
351
			_json_encode(
352
				array_flip($files)
353
			)
354
		);
355 4
		unset($files);
356 4
		$phar->addFile("$source_dir/meta.json", 'meta.json');
357 4
		$readme = false;
358 4
		if (file_exists("$source_dir/readme.html")) {
359
			$phar->addFile("$source_dir/readme.html", 'readme.html');
360
			$readme = 'readme.html';
361 4
		} elseif (file_exists("$source_dir/readme.txt")) {
362
			$phar->addFile("$source_dir/readme.txt", 'readme.txt');
363
			$readme = 'readme.txt';
364
		}
365 4
		if ($readme) {
366
			$phar->setStub("<?php Phar::webPhar(null, '$readme'); __HALT_COMPILER();");
367
		} else {
368 4
			$phar->addFromString('index.html', isset($meta['description']) ? $meta['description'] : $meta['package']);
369 4
			$phar->setStub("<?php Phar::webPhar(null, 'index.html'); __HALT_COMPILER();");
370
		}
371 4
		$phar->stopBuffering();
372 4
		return "Done! $Type $meta[package] $meta[version]";
373
	}
374
}
375