Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
1 | <?php |
||
27 | final class AutoloadPrefixer |
||
28 | { |
||
29 | /** |
||
30 | * @param stdClass $contents Decoded JSON |
||
31 | * @param string $prefix |
||
32 | * |
||
33 | * @return stdClass Prefixed decoded JSON |
||
34 | */ |
||
35 | 9 | public static function prefixPackageAutoloadStatements(stdClass $contents, string $prefix, Whitelist $whitelist): stdClass |
|
36 | { |
||
37 | 9 | if (isset($contents->autoload)) { |
|
38 | 9 | $contents->autoload = self::prefixAutoloadStatements($contents->autoload, $prefix, $whitelist); |
|
39 | } |
||
40 | |||
41 | 9 | if (isset($contents->{'autoload-dev'})) { |
|
42 | 3 | $contents->{'autoload-dev'} = self::prefixAutoloadStatements($contents->{'autoload-dev'}, $prefix, $whitelist); |
|
43 | } |
||
44 | |||
45 | 9 | if (isset($contents->extra, $contents->extra->laravel, $contents->extra->laravel->providers)) { |
|
46 | 1 | $contents->extra->laravel->providers = self::prefixLaravelProviders($contents->extra->laravel->providers, $prefix, $whitelist); |
|
47 | } |
||
48 | |||
49 | 9 | return $contents; |
|
50 | } |
||
51 | |||
52 | 9 | private static function prefixAutoloadStatements(stdClass $autoload, string $prefix, Whitelist $whitelist): stdClass |
|
53 | { |
||
54 | 9 | if (false === isset($autoload->{'psr-4'}) && false === isset($autoload->{'psr-0'})) { |
|
55 | 1 | return $autoload; |
|
56 | } |
||
57 | |||
58 | 8 | if (isset($autoload->{'psr-0'})) { |
|
59 | 5 | $autoload->{'psr-4'} = self::mergePSR0And4( |
|
60 | 5 | (array) $autoload->{'psr-0'}, |
|
61 | 5 | (array) ($autoload->{'psr-4'} ?? new stdClass()) |
|
62 | ); |
||
63 | } |
||
64 | 8 | unset($autoload->{'psr-0'}); |
|
65 | |||
66 | 8 | if (isset($autoload->{'psr-4'})) { |
|
67 | 8 | $autoload->{'psr-4'} = self::prefixAutoload((array) $autoload->{'psr-4'}, $prefix, $whitelist); |
|
68 | } |
||
69 | |||
70 | 8 | return $autoload; |
|
71 | } |
||
72 | |||
73 | 8 | private static function prefixAutoload(array $autoload, string $prefix, Whitelist $whitelist): array |
|
74 | { |
||
75 | 8 | $loader = []; |
|
76 | |||
77 | 8 | foreach ($autoload as $namespace => $paths) { |
|
78 | 8 | $newNamespace = $whitelist->belongsToWhitelistedNamespace($namespace) |
|
79 | ? $namespace |
||
80 | 8 | : sprintf('%s\\%s', $prefix, $namespace) |
|
81 | ; |
||
82 | |||
83 | 8 | $loader[$newNamespace] = $paths; |
|
84 | } |
||
85 | |||
86 | 8 | return $loader; |
|
87 | } |
||
88 | |||
89 | /** |
||
90 | * @param (string|string[])[] $psr0 |
||
91 | * @param (string|string[])[] $psr4 |
||
92 | * |
||
93 | * @return (string|string[])[] |
||
94 | */ |
||
95 | 5 | private static function mergePSR0And4(array $psr0, array $psr4): array |
|
115 | |||
116 | /** |
||
117 | * @param string|string[] $path |
||
118 | * |
||
119 | * @return string|string[] |
||
120 | */ |
||
121 | 5 | private static function updatePSR0Path($path, string $namespace) |
|
146 | |||
147 | /** |
||
148 | * Deals with the 4 possible scenarios: |
||
149 | * PSR0 | PSR4 |
||
150 | * array | |
||
151 | * string | |
||
152 | * or simply the namespace not existing as a psr-4 entry. |
||
153 | * |
||
154 | * @param string $psr0Namespace |
||
155 | * @param string|string[] $psr0Path |
||
156 | * @param (string|string[])[] $psr4 |
||
157 | * |
||
158 | * @return string|string[] |
||
159 | */ |
||
160 | 3 | private static function mergeNamespaces(string $psr0Namespace, $psr0Path, array $psr4) |
|
187 | |||
188 | 1 | private static function prefixLaravelProviders(array $providers, string $prefix, Whitelist $whitelist): array |
|
200 | } |
||
201 |
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.