1
|
|
|
<?php |
2
|
|
|
declare(strict_types=1); |
3
|
|
|
|
4
|
|
|
namespace Webrouse\AssetMacro; |
5
|
|
|
|
6
|
|
|
|
7
|
|
|
use Nette\Utils\Json; |
8
|
|
|
use Nette\Utils\JsonException; |
9
|
|
|
use Nette\Utils\Strings; |
10
|
|
|
use Webrouse\AssetMacro\Exceptions\AssetNotFoundException; |
11
|
|
|
use Webrouse\AssetMacro\Exceptions\ManifestJsonException; |
12
|
|
|
use Webrouse\AssetMacro\Exceptions\RevisionNotFound; |
13
|
|
|
|
14
|
|
|
class Manifest |
15
|
|
|
{ |
16
|
|
|
/** @var Config */ |
17
|
|
|
private $config; |
18
|
|
|
|
19
|
|
|
/** @var string|null */ |
20
|
|
|
private $path; |
21
|
|
|
|
22
|
|
|
/** @var array */ |
23
|
|
|
private $data = []; |
24
|
|
|
|
25
|
|
|
|
26
|
1 |
|
public function __construct(Config $config, ?string $path, array $data = null) |
27
|
|
|
{ |
28
|
1 |
|
$this->config = $config; |
29
|
1 |
|
$this->path = $path; |
30
|
|
|
|
31
|
1 |
|
if ($data) { |
32
|
1 |
|
$raw = $data; |
33
|
|
|
} else { |
34
|
1 |
|
assert(file_exists($path)); |
35
|
|
|
try { |
36
|
1 |
|
$raw = Json::decode((string) file_get_contents($path), Json::FORCE_ARRAY); |
37
|
|
|
} catch (JsonException $e) { |
|
|
|
|
38
|
|
|
throw new ManifestJsonException('Invalid JSON in manifest.', 0, $e); |
39
|
|
|
} |
40
|
|
|
} |
41
|
|
|
|
42
|
|
|
// Strip optional leading / from source and target path (key and value) |
43
|
1 |
|
foreach ($raw as $key => $value) { |
44
|
1 |
|
$key = ltrim((string) $key, '/'); |
45
|
1 |
|
$value = ltrim((string) $value, '/'); |
46
|
1 |
|
$this->data[$key] = $value; |
47
|
|
|
} |
48
|
1 |
|
} |
49
|
|
|
|
50
|
|
|
|
51
|
|
|
/** |
52
|
|
|
* @param null|string|callable $filter regexp pattern or callable |
53
|
|
|
* @param bool $needed |
54
|
|
|
* @return array|Asset[] |
55
|
|
|
*/ |
56
|
1 |
|
public function getAll($filter = null, $needed = true): array |
57
|
|
|
{ |
58
|
1 |
|
assert($filter === null || is_string($filter) || is_callable($filter)); |
59
|
|
|
|
60
|
1 |
|
$out = []; |
61
|
1 |
|
foreach (array_keys($this->data) as $asset) { |
62
|
1 |
|
if (is_string($filter)) { |
63
|
1 |
|
if (!Strings::match($asset, $filter)) { |
64
|
1 |
|
continue; |
65
|
|
|
} |
66
|
1 |
|
} elseif (is_callable($filter)) { |
67
|
1 |
|
if (!$filter($asset)) { |
68
|
1 |
|
continue; |
69
|
|
|
} |
70
|
|
|
} |
71
|
1 |
|
$out[$asset] = $this->getAsset($asset, $needed); |
72
|
|
|
} |
73
|
|
|
|
74
|
1 |
|
return $out; |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
|
78
|
1 |
|
public function getAsset(string $path, bool $needed = true): ?Asset |
79
|
|
|
{ |
80
|
1 |
|
$revision = self::getRevision($path, $needed); |
81
|
|
|
|
82
|
1 |
|
if (!file_exists($revision->getAbsolutePath())) { |
83
|
1 |
|
Utils::throwError( |
84
|
1 |
|
new AssetNotFoundException(sprintf("Asset '%s' not found.", $revision->getAbsolutePath())), |
85
|
1 |
|
$this->config->getMissingAssetPolicy(), |
86
|
1 |
|
$needed |
87
|
|
|
); |
88
|
|
|
|
89
|
1 |
|
return null; |
90
|
|
|
} |
91
|
|
|
|
92
|
1 |
|
return new Asset($revision); |
93
|
|
|
} |
94
|
|
|
|
95
|
|
|
|
96
|
1 |
|
public function getRevision(string $path, bool $needed = true): Revision |
97
|
|
|
{ |
98
|
|
|
// Strip optional leading / from path |
99
|
1 |
|
$path = Utils::normalizePath(ltrim($path, '/')); |
100
|
1 |
|
$revision = isset($this->data[$path]) ? $this->data[$path] : null; |
101
|
|
|
|
102
|
|
|
// Throw error if revision not found in manifest |
103
|
1 |
|
if ($revision === null) { |
104
|
1 |
|
Utils::throwError( |
105
|
1 |
|
new RevisionNotFound(sprintf("Revision for asset '%s' not found in manifest %s.", $path, $this->path)), |
106
|
1 |
|
$this->config->getMissingRevisionPolicy(), |
107
|
1 |
|
$needed |
108
|
|
|
); |
109
|
|
|
} |
110
|
|
|
|
111
|
1 |
|
return new Revision($this->config, $path, $revision); |
112
|
|
|
} |
113
|
|
|
} |
114
|
|
|
|
Scrutinizer analyzes your
composer.json
/composer.lock
file if available to determine the classes, and functions that are defined by your dependencies.It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.