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.