/
ConfigHashNormalizer.php
108 lines (88 loc) 路 2.68 KB
/
ConfigHashNormalizer.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
<?php
declare(strict_types=1);
/**
* Copyright (c) 2018-2022 Andreas M枚ller
*
* For the full copyright and license information, please view
* the LICENSE.md file that was distributed with this source code.
*
* @see https://github.com/ergebnis/json-normalizer
*/
namespace Ergebnis\Json\Normalizer\Vendor\Composer;
use Ergebnis\Json\Normalizer\Json;
use Ergebnis\Json\Normalizer\Normalizer;
final class ConfigHashNormalizer implements Normalizer
{
private const PROPERTIES_THAT_SHOULD_BE_SORTED = [
'config',
'extra',
'scripts-descriptions',
];
/**
* @see https://getcomposer.org/doc/06-config.md#allow-plugins
* @see https://getcomposer.org/doc/06-config.md#preferred-install
*/
private const PROPERTY_PATHS_THAT_SHOULD_NOT_BE_SORTED = [
'config.allow-plugins',
'config.preferred-install',
];
public function normalize(Json $json): Json
{
$decoded = $json->decoded();
if (!\is_object($decoded)) {
return $json;
}
$objectPropertiesThatShouldBeNormalized = \array_intersect_key(
\get_object_vars($decoded),
\array_flip(self::PROPERTIES_THAT_SHOULD_BE_SORTED),
);
if ([] === $objectPropertiesThatShouldBeNormalized) {
return $json;
}
foreach ($objectPropertiesThatShouldBeNormalized as $name => $value) {
$decoded->{$name} = self::sortByKey(
$name,
$value,
);
}
/** @var string $encoded */
$encoded = \json_encode($decoded);
return Json::fromEncoded($encoded);
}
/**
* @param null|array|bool|false|object|string $value
*
* @return null|array|bool|false|object|string
*/
private static function sortByKey(
string $propertyPath,
$value
) {
if (\in_array($propertyPath, self::PROPERTY_PATHS_THAT_SHOULD_NOT_BE_SORTED, true)) {
return $value;
}
if (!\is_object($value)) {
return $value;
}
/** @var array<string, mixed> $sorted */
$sorted = (array) $value;
if ([] === $sorted) {
return $value;
}
\ksort($sorted);
$names = \array_keys($sorted);
return \array_combine(
$names,
\array_map(static function ($value, string $name) use ($propertyPath) {
return self::sortByKey(
\sprintf(
'%s.%s',
$propertyPath,
$name,
),
$value,
);
}, $sorted, $names),
);
}
}