Completed
Push — improve/use-plan-icon-in-my-pl... ( 986e79...6cc615 )
by
unknown
34:39 queued 25:39
created

AutoloadProcessor   A

Complexity

Total Complexity 28

Size/Duplication

Total Lines 161
Duplicated Lines 19.25 %

Coupling/Cohesion

Components 1
Dependencies 0

Importance

Changes 0
Metric Value
dl 31
loc 161
rs 10
c 0
b 0
f 0
wmc 28
lcom 1
cbo 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
D processClassmap() 31 69 18
B processPsr4Packages() 0 23 6
A processFiles() 0 16 3

How to fix   Duplicated Code   

Duplicated Code

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 // phpcs:ignore WordPress.Files.FileName
2
/**
3
 * Autoload Processor.
4
 *
5
 * @package automattic/jetpack-autoloader
6
 */
7
8
// phpcs:disable WordPress.Files.FileName.InvalidClassFileName
9
// phpcs:disable WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid
10
// phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
11
// phpcs:disable WordPress.NamingConventions.ValidVariableName.InterpolatedVariableNotSnakeCase
12
// phpcs:disable WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
13
// phpcs:disable WordPress.NamingConventions.ValidVariableName.PropertyNotSnakeCase
14
15
namespace Automattic\Jetpack\Autoloader;
16
17
use Composer\Util\Filesystem;
18
19
/**
20
 * Class AutoloadProcessor.
21
 */
22
class AutoloadProcessor {
23
24
	/**
25
	 * A callable for scanning a directory for all of its classes.
26
	 *
27
	 * @var callable
28
	 */
29
	private $classmapScanner;
30
31
	/**
32
	 * A callable for transforming a path into one to be used in code.
33
	 *
34
	 * @var callable
35
	 */
36
	private $pathCodeTransformer;
37
38
	/**
39
	 * The constructor.
40
	 *
41
	 * @param callable $classmapScanner A callable for scanning a directory for all of its classes.
42
	 * @param callable $pathCodeTransformer A callable for transforming a path into one to be used in code.
43
	 */
44
	public function __construct( $classmapScanner, $pathCodeTransformer ) {
45
		$this->classmapScanner     = $classmapScanner;
46
		$this->pathCodeTransformer = $pathCodeTransformer;
47
	}
48
49
	/**
50
	 * Processes the classmap autoloads into a relative path format including the version for each file.
51
	 *
52
	 * @param array $autoloads The autoloads we are processing.
53
	 * @param bool  $scanPsrPackages Whether or not PSR packages should be converted to a classmap.
54
	 *
55
	 * @return array $processed
56
	 */
57
	public function processClassmap( $autoloads, $scanPsrPackages ) {
58
		// We can't scan PSR packages if we don't actually have any.
59
		if ( empty( $autoloads['psr-4'] ) ) {
60
			$scanPsrPackages = false;
61
		}
62
63
		if ( empty( $autoloads['classmap'] ) && ! $scanPsrPackages ) {
64
			return null;
65
		}
66
67
		$excludedClasses = null;
68
		if ( ! empty( $autoloads['exclude-from-classmap'] ) ) {
69
			$excludedClasses = '{(' . implode( '|', $autoloads['exclude-from-classmap'] ) . ')}';
70
		}
71
72
		$processed = array();
73
74 View Code Duplication
		if ( $scanPsrPackages ) {
75
			foreach ( $autoloads['psr-4'] as $namespace => $sources ) {
76
				$namespace = empty( $namespace ) ? null : $namespace;
77
78
				foreach ( $sources as $source ) {
79
					$classmap = call_user_func( $this->classmapScanner, $source['path'], $excludedClasses, $namespace );
80
81
					foreach ( $classmap as $class => $path ) {
82
						$processed[ $class ] = array(
83
							'version' => $source['version'],
84
							'path'    => call_user_func( $this->pathCodeTransformer, $path ),
85
						);
86
					}
87
				}
88
			}
89
		}
90
91
		/*
92
		 * PSR-0 namespaces are converted to classmaps for both optimized and unoptimized autoloaders because any new
93
		 * development should use classmap or PSR-4 autoloading.
94
		 */
95 View Code Duplication
		if ( ! empty( $autoloads['psr-0'] ) ) {
96
			foreach ( $autoloads['psr-0'] as $namespace => $sources ) {
97
				$namespace = empty( $namespace ) ? null : $namespace;
98
99
				foreach ( $sources as $source ) {
100
					$classmap = call_user_func( $this->classmapScanner, $source['path'], $excludedClasses, $namespace );
101
					foreach ( $classmap as $class => $path ) {
102
						$processed[ $class ] = array(
103
							'version' => $source['version'],
104
							'path'    => call_user_func( $this->pathCodeTransformer, $path ),
105
						);
106
					}
107
				}
108
			}
109
		}
110
111
		if ( ! empty( $autoloads['classmap'] ) ) {
112
			foreach ( $autoloads['classmap'] as $package ) {
113
				$classmap = call_user_func( $this->classmapScanner, $package['path'], $excludedClasses, null );
114
115
				foreach ( $classmap as $class => $path ) {
116
					$processed[ $class ] = array(
117
						'version' => $package['version'],
118
						'path'    => call_user_func( $this->pathCodeTransformer, $path ),
119
					);
120
				}
121
			}
122
		}
123
124
		return $processed;
125
	}
126
127
	/**
128
	 * Processes the PSR-4 autoloads into a relative path format including the version for each file.
129
	 *
130
	 * @param array $autoloads The autoloads we are processing.
131
	 * @param bool  $scanPsrPackages Whether or not PSR packages should be converted to a classmap.
132
	 *
133
	 * @return array $processed
134
	 */
135
	public function processPsr4Packages( $autoloads, $scanPsrPackages ) {
136
		if ( $scanPsrPackages || empty( $autoloads['psr-4'] ) ) {
137
			return null;
138
		}
139
140
		$processed = array();
141
142
		foreach ( $autoloads['psr-4'] as $namespace => $packages ) {
143
			$namespace = empty( $namespace ) ? null : $namespace;
144
			$paths     = array();
145
146
			foreach ( $packages as $package ) {
147
				$paths[] = call_user_func( $this->pathCodeTransformer, $package['path'] );
148
			}
149
150
			$processed[ $namespace ] = array(
151
				'version' => $package['version'],
0 ignored issues
show
Bug introduced by
The variable $package seems to be defined by a foreach iteration on line 146. Are you sure the iterator is never empty, otherwise this variable is not defined?

It seems like you are relying on a variable being defined by an iteration:

foreach ($a as $b) {
}

// $b is defined here only if $a has elements, for example if $a is array()
// then $b would not be defined here. To avoid that, we recommend to set a
// default value for $b.


// Better
$b = 0; // or whatever default makes sense in your context
foreach ($a as $b) {
}

// $b is now guaranteed to be defined here.
Loading history...
152
				'path'    => $paths,
153
			);
154
		}
155
156
		return $processed;
157
	}
158
159
	/**
160
	 * Processes the file autoloads into a relative format including the version for each file.
161
	 *
162
	 * @param array $autoloads The autoloads we are processing.
163
	 *
164
	 * @return array|null $processed
165
	 */
166
	public function processFiles( $autoloads ) {
167
		if ( empty( $autoloads['files'] ) ) {
168
			return null;
169
		}
170
171
		$processed = array();
172
173
		foreach ( $autoloads['files'] as $file_id => $package ) {
174
			$processed[ $file_id ] = array(
175
				'version' => $package['version'],
176
				'path'    => call_user_func( $this->pathCodeTransformer, $package['path'] ),
177
			);
178
		}
179
180
		return $processed;
181
	}
182
}
183