1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
|
4
|
|
|
namespace TheCodingMachine\Discovery; |
5
|
|
|
|
6
|
|
|
use Seld\JsonLint\JsonParser; |
7
|
|
|
use Seld\JsonLint\ParsingException; |
8
|
|
|
use TheCodingMachine\Discovery\Utils\IOException; |
9
|
|
|
use TheCodingMachine\Discovery\Utils\JsonException; |
10
|
|
|
|
11
|
|
|
/** |
12
|
|
|
* Class in charge of loading a discovery.json file. |
13
|
|
|
*/ |
14
|
|
|
class DiscoveryFileLoader |
15
|
|
|
{ |
16
|
|
|
/** |
17
|
|
|
* Returns an array of array of asset operations indexed by asset type. |
18
|
|
|
* |
19
|
|
|
* @param \SplFileInfo $file |
20
|
|
|
* @return AssetOperation[][] |
21
|
|
|
* @throws JsonException |
22
|
|
|
*/ |
23
|
|
|
public function loadDiscoveryFile(\SplFileInfo $file, string $package, string $packageDir) : array |
24
|
|
|
{ |
25
|
|
|
$jsonParser = new JsonParser(); |
26
|
|
|
try { |
27
|
|
|
$result = $jsonParser->parse($this->getContents($file), JsonParser::PARSE_TO_ASSOC); |
28
|
|
|
} catch (ParsingException $e) { |
29
|
|
|
throw new JsonException(sprintf('Invalid JSON in file "%s": %s', $file->getPath(), $e->getMessage()), 0, $e); |
30
|
|
|
} |
31
|
|
|
|
32
|
|
|
if (!is_array($result) || !$this->isAssoc($result)) { |
33
|
|
|
throw new JsonException(sprintf('File "%s" should contain a JSON object.', $file->getPath())); |
34
|
|
|
} |
35
|
|
|
|
36
|
|
|
$assetTypes = []; |
37
|
|
|
|
38
|
|
|
foreach ($result as $type => $array) { |
39
|
|
|
if (!is_array($array)) { |
40
|
|
|
$array = [$array]; |
41
|
|
|
} |
42
|
|
|
foreach ($array as $value) { |
43
|
|
|
$assetTypes[$type][] = $this->toAssetOperation($value, $package, $packageDir); |
44
|
|
|
} |
45
|
|
|
} |
46
|
|
|
return $assetTypes; |
47
|
|
|
} |
48
|
|
|
|
49
|
|
|
/** |
50
|
|
|
* Returns false if the array is numerically indexed, starting at 0. |
51
|
|
|
* |
52
|
|
|
* @param array $arr |
53
|
|
|
* @return bool |
54
|
|
|
*/ |
55
|
|
|
private function isAssoc(array $arr) |
56
|
|
|
{ |
57
|
|
|
if (array() === $arr) { |
58
|
|
|
return true; |
59
|
|
|
} |
60
|
|
|
return array_keys($arr) !== range(0, count($arr) - 1); |
61
|
|
|
} |
62
|
|
|
|
63
|
|
|
/** |
64
|
|
|
* Returns the contents of the file. |
65
|
|
|
* |
66
|
|
|
* @param \SplFileInfo $file |
67
|
|
|
* @return string the contents of the file |
68
|
|
|
* |
69
|
|
|
*/ |
70
|
|
|
private function getContents(\SplFileInfo $file) |
71
|
|
|
{ |
72
|
|
|
$level = error_reporting(0); |
73
|
|
|
$content = file_get_contents($file->getPathname()); |
74
|
|
|
error_reporting($level); |
75
|
|
|
if (false === $content) { |
76
|
|
|
$error = error_get_last(); |
77
|
|
|
throw new IOException($error['message']); |
78
|
|
|
} |
79
|
|
|
return $content; |
80
|
|
|
} |
81
|
|
|
|
82
|
|
|
/** |
83
|
|
|
* Transforms a value string into a value array. |
84
|
|
|
* Also, if a value array is passed, checks it contains valid data. |
85
|
|
|
* |
86
|
|
|
* @param mixed $value |
87
|
|
|
* @return AssetOperation |
88
|
|
|
*/ |
89
|
|
|
private function toAssetOperation($value, string $package, string $packageDir) : AssetOperation |
90
|
|
|
{ |
91
|
|
|
if (is_array($value)) { |
92
|
|
|
return AssetOperation::buildFromArray($value, $package, $packageDir); |
93
|
|
|
} else { |
94
|
|
|
return AssetOperation::buildFromString((string) $value, $package, $packageDir); |
95
|
|
|
} |
96
|
|
|
} |
97
|
|
|
} |
98
|
|
|
|