Completed
Push — master ( 06acd3...66093a )
by Nazar
06:23
created

RequireJS::find_package_npm()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 8
nc 6
nop 2
dl 0
loc 13
rs 9.2
c 0
b 0
f 0
ccs 8
cts 8
cp 1
crap 4
1
<?php
2
/**
3
 * @package   CleverStyle Framework
4
 * @author    Nazar Mokrynskyi <[email protected]>
5
 * @copyright Copyright (c) 2014-2017, Nazar Mokrynskyi
6
 * @license   MIT License, see license.txt
7
 */
8
namespace cs\Page\Assets;
9
use
10
	cs\Config,
11
	cs\Event;
12
13
class RequireJS {
14
	/**
15
	 * @return string[]
16
	 */
17 6
	public static function get_config () {
18 6
		$Config                = Config::instance();
19 6
		$paths                 = [];
20 6
		$packages              = [];
21
		$directories_to_browse = [
22 6
			DIR.'/bower_components',
23 6
			DIR.'/node_modules'
24
		];
25 6
		Event::instance()->fire(
26 6
			'System/Page/requirejs',
27
			[
28 6
				'paths'                 => &$paths,
29 6
				'packages'              => &$packages,
30 6
				'directories_to_browse' => &$directories_to_browse
31
			]
32
		);
33 6
		foreach ($Config->components['modules'] as $module_name => $module_data) {
34 6
			if ($module_data['active'] == Config\Module_Properties::UNINSTALLED) {
35 2
				continue;
36
			}
37 6
			$paths += static::add_aliases(MODULES."/$module_name");
38
		}
39 6
		$allowed_extensions = $Config->core['cache_compress_js_css'] ? ['min.js', 'js'] : ['js'];
40 6
		foreach ($directories_to_browse as $dir) {
41 6
			foreach (get_files_list($dir, false, 'd', true) as $d) {
42 6
				$packages[] = static::find_package_main_path($d, $allowed_extensions);
43
			}
44
		}
45 6
		$paths    = _substr($paths, strlen(DIR));
46 6
		$packages = array_values(array_filter($packages));
47 6
		$hashes   = static::get_hashes($paths, $packages);
48
		return [
49 6
			'paths'    => $paths,
50 6
			'packages' => $packages,
51 6
			'hashes'   => $hashes
52
		];
53
	}
54
	/**
55
	 * @param string $dir
56
	 *
57
	 * @return string[]
58
	 */
59 6
	protected static function add_aliases ($dir) {
60 6
		$paths = [];
61 6
		if (is_dir("$dir/assets/js")) {
62 6
			$name         = basename($dir);
63 6
			$paths[$name] = "$dir/assets/js";
64 6
			foreach ((array)@file_get_json("$dir/meta.json")['provide'] as $p) {
65 6
				if (strpos($p, '/') === false) {
66 6
					$paths[$p] = $paths[$name];
67
				}
68
			}
69
		}
70 6
		return $paths;
71
	}
72
	/**
73
	 * @param string   $dir
74
	 * @param string[] $allowed_extensions
75
	 *
76
	 * @return string[]
77
	 */
78 2
	protected static function find_package_main_path ($dir, $allowed_extensions) {
79 2
		$path = static::find_package_bower($dir, $allowed_extensions) ?: static::find_package_npm($dir, $allowed_extensions);
80 2
		if (!$path) {
81 2
			return [];
82
		}
83
		return [
84 2
			'name'     => basename($dir),
85 2
			'main'     => substr($path, strlen($dir) + 1, -3),
86 2
			'location' => substr($dir, strlen(DIR))
87
		];
88
	}
89
	/**
90
	 * @param string   $dir
91
	 * @param string[] $allowed_extensions
92
	 *
93
	 * @return false|string
94
	 */
95 2
	protected static function find_package_bower ($dir, $allowed_extensions) {
96 2
		$bower = @file_get_json("$dir/bower.json");
97 2
		foreach (@(array)$bower['main'] as $main) {
98 2
			if (preg_match('/\.js$/', $main)) {
99 2
				$main = substr($main, 0, -3);
100 2
				$main = file_exists_with_extension("$dir/$main", $allowed_extensions);
101 2
				if ($main) {
102 2
					return $main;
103
				}
104
			}
105
		}
106 2
		return false;
107
	}
108
	/**
109
	 * @param string   $dir
110
	 * @param string[] $allowed_extensions
111
	 *
112
	 * @return false|string
113
	 */
114 2
	protected static function find_package_npm ($dir, $allowed_extensions) {
115 2
		$package = @file_get_json("$dir/package.json");
116
		// If we have browser-specific declaration - use it
117
		/** @noinspection NestedTernaryOperatorInspection */
118 2
		$main = $package['browser'] ?? ($package['jspm']['main'] ?? @$package['main']);
119 2
		if (preg_match('/\.js$/', $main)) {
120 2
			$main = substr($main, 0, -3);
121
		}
122 2
		if ($main) {
123 2
			return file_exists_with_extension("$dir/$main", $allowed_extensions) ?: file_exists_with_extension("$dir/dist/$main", $allowed_extensions);
124
		}
125 2
		return false;
126
	}
127
	/**
128
	 * @param string[] $paths
129
	 * @param array[]  $packages
130
	 *
131
	 * @return string[]
132
	 */
133 6
	protected static function get_hashes ($paths, $packages) {
134 6
		$hashes = [];
135 6
		foreach ($packages as $package) {
136 2
			$hashes[$package['location']] = static::hash_from_paths(
137 2
				DIR."/$package[location]/bower.json",
138 2
				DIR."/$package[location]/package.json",
139 2
				DIR."/$package[location]/$package[main].js"
140
			);
141
		}
142 6
		foreach ($paths as $path) {
143 6
			$hashes[$path] = static::hash_from_paths(
144 6
				DIR."/$path/bower.json",
145 6
				DIR."/$path/package.json",
146 6
				DIR."/$path/../../meta.json",
147 6
				DIR."/$path.js"
148
			);
149
		}
150 6
		return _substr($hashes, 0, 5);
151
	}
152
	/**
153
	 * @param string[] ...$paths
154
	 *
155
	 * @return string
156
	 */
157 6
	protected static function hash_from_paths (...$paths) {
158 6
		$hash = '';
159 6
		foreach ($paths as $path) {
160 6
			if (file_exists($path)) {
161 6
				$hash .= md5_file($path);
162
			}
163
		}
164 6
		return md5($hash);
165
	}
166
}
167