Completed
Push — try/custom-autoloader ( bd5514...741938 )
by
unknown
18:30 queued 10:28
created

AutoloadGenerator::addClassMapCode()   B

Complexity

Conditions 6
Paths 4

Size

Total Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
nc 4
nop 8
dl 0
loc 34
rs 8.7537
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
/**
3
 * Autoloader Generator.
4
 *
5
 * @package Automattic\Jetpack\Autoloader
6
 */
7
8
// phpcs:disable PHPCompatibility.Keywords.NewKeywords.t_useFound
9
// phpcs:disable PHPCompatibility.LanguageConstructs.NewLanguageConstructs.t_ns_separatorFound
10
// phpcs:disable PHPCompatibility.FunctionDeclarations.NewClosure.Found
11
// phpcs:disable PHPCompatibility.Keywords.NewKeywords.t_namespaceFound
12
// phpcs:disable PHPCompatibility.Keywords.NewKeywords.t_dirFound
13
// phpcs:disable WordPress.Files.FileName.InvalidClassFileName
14
// phpcs:disable WordPress.Files.FileName.NotHyphenatedLowercase
15
// phpcs:disable WordPress.Files.FileName.InvalidClassFileName
16
// phpcs:disable WordPress.PHP.DevelopmentFunctions.error_log_var_export
17
// phpcs:disable WordPress.WP.AlternativeFunctions.file_system_read_file_put_contents
18
// phpcs:disable WordPress.WP.AlternativeFunctions.file_system_read_fopen
19
// phpcs:disable WordPress.WP.AlternativeFunctions.file_system_read_fwrite
20
// phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
21
// phpcs:disable WordPress.NamingConventions.ValidVariableName.InterpolatedVariableNotSnakeCase
22
// phpcs:disable WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
23
// phpcs:disable WordPress.NamingConventions.ValidVariableName.PropertyNotSnakeCase
24
25
26
namespace Automattic\Jetpack\Autoloader;
27
28
use Composer\Autoload\AutoloadGenerator as BaseGenerator;
29
use Composer\Autoload\ClassMapGenerator;
30
use Composer\Config;
31
use Composer\Installer\InstallationManager;
32
use Composer\IO\IOInterface;
33
use Composer\Package\PackageInterface;
34
use Composer\Repository\InstalledRepositoryInterface;
35
use Composer\Util\Filesystem;
36
37
/**
38
 * Class AutoloadGenerator.
39
 */
40
class AutoloadGenerator extends BaseGenerator {
41
42
	/**
43
	 * Instantiate an AutoloadGenerator object.
44
	 *
45
	 * @param IOInterface $io IO object.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $io not be null|IOInterface?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
46
	 */
47
	public function __construct( IOInterface $io = null ) {
48
		$this->io = $io;
49
	}
50
51
	/**
52
	 * Dump the autoloader.
53
	 *
54
	 * @param Config                       $config Config object.
55
	 * @param InstalledRepositoryInterface $localRepo Installed Reposetories object.
56
	 * @param PackageInterface             $mainPackage Main Package object.
57
	 * @param InstallationManager          $installationManager Manager for installing packages.
58
	 * @param string                       $targetDir Path to the current target directory.
59
	 * @param bool                         $scanPsr0Packages Whether to search for packages. Currently hard coded to always be false.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $scanPsr0Packages not be boolean|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
60
	 * @param string                       $suffix The autoloader suffix, ignored since we want our autoloader to only be included once.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $suffix not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
61
	 */
62
	public function dump(
63
		Config $config,
64
		InstalledRepositoryInterface $localRepo,
65
		PackageInterface $mainPackage,
66
		InstallationManager $installationManager,
67
		$targetDir,
68
		$scanPsr0Packages = null, // Not used we always optimize.
69
		$suffix = null
70
	) {
71
72
		$filesystem = new Filesystem();
73
		$filesystem->ensureDirectoryExists( $config->get( 'vendor-dir' ) );
74
75
		$basePath   = $filesystem->normalizePath( realpath( getcwd() ) );
76
		$vendorPath = $filesystem->normalizePath( realpath( $config->get( 'vendor-dir' ) ) );
77
		$targetDir  = $vendorPath . '/' . $targetDir;
78
		$filesystem->ensureDirectoryExists( $targetDir );
79
80
		$packageMap = $this->buildPackageMap( $installationManager, $mainPackage, $localRepo->getCanonicalPackages() );
81
		$autoloads  = $this->parseAutoloads( $packageMap, $mainPackage );
82
83
		$classMap = $this->getClassMap( $autoloads, $filesystem, $vendorPath, $basePath );
84
85
		// Generate the files.
86
		file_put_contents( $targetDir . '/autoload_classmap_package.php', $this->getAutoloadPackagesClassmapFile( $classMap ) );
87
		$this->io->writeError( '<info>Generated autoload_classmap_package.php</info>', true );
88
89
		file_put_contents( $vendorPath . '/autoload_packages.php', $this->getAutoloadPackageFile( $suffix ) );
90
		$this->io->writeError( '<info>Generated autoload_packages.php</info>', true );
91
92
	}
93
94
	/**
95
	 * Takes a classMap and returns the array string representation.
96
	 *
97
	 * @param array $classMap Map of all the package classes and paths and versions.
98
	 *
99
	 * @return string
100
	 */
101
	private function classMapToPHPArrayString( array $classMap ) {
102
		$classmapString = ' array( ';
103
		// ksort( $classMap );
104
		foreach ( $classMap as $class => $code ) {
105
			$classmapString .= ' ' . var_export( $class, true ) . ' => ' . $code;
106
		}
107
		$classmapString .= ");\n";
108
		return $classmapString;
109
	}
110
111
	/**
112
	 * This function differs from the composer parseAutoloadsType in that beside returning the path.
113
	 * It also return the path and the version of a package.
114
	 *
115
	 * @param array            $packageMap Map of all the packages.
116
	 * @param string           $type Type of autoloader to use, currently not used, since we only support psr-4.
117
	 * @param PackageInterface $mainPackage Instance of the Package Object.
118
	 *
119
	 * @return array
120
	 */
121
	protected function parseAutoloadsType( array $packageMap, $type, PackageInterface $mainPackage ) {
122
		$autoloads = array();
123
		foreach ( $packageMap as $item ) {
124
			list($package, $installPath) = $item;
125
			$autoload                    = $package->getAutoload();
126
127
			if ( $package === $mainPackage ) {
128
				$autoload = array_merge_recursive( $autoload, $package->getDevAutoload() );
129
			}
130
131
			// Skip packages that are not 'psr-4' since we only support them for now.
132
			if ( ! isset( $autoload['psr-4'] ) || ! is_array( $autoload['psr-4'] ) ) {
133
				continue;
134
			}
135
136
			if ( null !== $package->getTargetDir() && $package !== $mainPackage ) {
137
				$installPath = substr( $installPath, 0, -strlen( '/' . $package->getTargetDir() ) );
138
			}
139
			foreach ( $autoload['psr-4'] as $namespace => $paths ) {
140
				foreach ( (array) $paths as $path ) {
141
					$relativePath              = empty( $installPath ) ? ( empty( $path ) ? '.' : $path ) : $installPath . '/' . $path;
142
					$autoloads[ $namespace ][] = array(
143
						'path'    => $relativePath,
144
						'version' => $package->getVersion(), // Version of the class comes from the package - should we try to parse it?
145
					);
146
				}
147
			}
148
		}
149
		return $autoloads;
150
	}
151
152
	/**
153
	 * Take the autoloads array and return the classMap that contains the path and the version for each namespace.
154
	 *
155
	 * @param array      $autoloads Array of autoload settings defined defined by the packages.
156
	 * @param Filesystem $filesystem Filesystem class instance.
157
	 * @param string     $vendorPath Path to the vendor directory.
158
	 * @param string     $basePath Base Path.
159
	 *
160
	 * @return array $classMap
161
	 */
162
	private function getClassMap( array $autoloads, Filesystem $filesystem, $vendorPath, $basePath ) {
163
		$classMap = array();
164
		$blacklist        = null; // not supported for now.
165
166
		// Scan the PSR-4 directories for class files, and add them to the class map.
167
		foreach ( $autoloads['psr-4'] as $namespace => $packages_info ) {
168
			foreach ( $packages_info as $package ) {
169
				$dir = $filesystem->normalizePath( $filesystem->isAbsolutePath( $package['path'] )
170
					? $package['path']
171
					: $basePath . '/' . $package['path']
172
				);
173
				$map = ClassMapGenerator::createMap( $dir, $blacklist, $this->io, $namespace );
174
175
				foreach ( $map as $class => $path ) {
176
					$classMap[ $class ] = "array( 'path' => " . $this->getPathCode( $filesystem, $basePath, $vendorPath, $path ) . ", 'version'=>'" . $package['version'] . "' ),\n";
177
				}
178
			}
179
		}
180
181
		return $classMap;
182
	}
183
184
	/**
185
	 *
186
	 * @param $classMap
187
	 *
188
	 * @return string
189
	 */
190
	private function getAutoloadPackagesClassmapFile( $classMap ) {
191
192
		return <<<INCLUDE_CLASSMAP
193
<?php
194
195
// This file `autoload_classmap_packages.php` was auto generated by automattic/jetpack-autoloader.
196
197
\$vendorDir = dirname(__DIR__);
198
199
return $classMap
200
201
INCLUDE_CLASSMAP;
202
	}
203
204
	/**
205
	 * Generate the PHP that will be used in the autoload_packages.php files.
206
	 *
207
	 * @param string $suffix  Unique suffix added to the jetpack_enqueue_packages function.
208
	 *
209
	 * @return string
210
	 */
211
	private function getAutoloadPackageFile( $suffix ) {
212
		$sourceLoader   = fopen( __DIR__ . '/autoload.php', 'r' );
213
		$file_contents  = stream_get_contents( $sourceLoader );
214
		$file_contents .= <<<INCLUDE_FILES
215
/**
216
 * Prepare all the classes for autoloading.
217
 */
218
function enqueue_packages_$suffix() {
219
	\$class_map = require_once dirname( __FILE__ ) . '/composer/autoload_classmap_package.php';
220
	foreach ( \$class_map as \$class_name => \$class_info ) {
221
		enqueue_package_class( \$class_name, \$class_info['version'], \$class_info['path'] );
222
	}
223
}
224
225
enqueue_packages_$suffix();
226
		
227
INCLUDE_FILES;
228
229
		return $file_contents;
230
	}
231
}
232