PluginProbe ʕ •ᴥ•ʔ
Hostinger Reach – AI-Powered Email Marketing for WordPress / 1.7.0
Hostinger Reach – AI-Powered Email Marketing for WordPress v1.7.0
1.7.2 1.7.1 1.7.0 1.6.0 1.5.9 1.5.8 1.5.7 1.5.6 1.5.5 1.5.4 1.5.3 1.5.2 1.5.1 1.5.0 1.4.12 1.4.11 1.4.10 1.4.9 1.4.8 1.4.7 trunk 1.0.1 1.0.10 1.0.11 1.0.12 1.0.13 1.0.14 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6
hostinger-reach / vendor / automattic / jetpack-autoloader / src / AutoloadGenerator.php
hostinger-reach / vendor / automattic / jetpack-autoloader / src Last commit date
AutoloadFileWriter.php 7 months ago AutoloadGenerator.php 1 month ago AutoloadProcessor.php 1 year ago CustomAutoloaderPlugin.php 1 month ago ManifestGenerator.php 1 year ago autoload.php 1 year ago class-autoloader-handler.php 1 year ago class-autoloader-locator.php 1 year ago class-autoloader.php 1 year ago class-container.php 1 year ago class-hook-manager.php 1 year ago class-latest-autoloader-guard.php 1 year ago class-manifest-reader.php 1 year ago class-path-processor.php 1 year ago class-php-autoloader.php 1 year ago class-plugin-locator.php 1 year ago class-plugins-handler.php 1 year ago class-shutdown-handler.php 1 year ago class-version-loader.php 1 year ago class-version-selector.php 1 year ago
AutoloadGenerator.php
404 lines
1 <?php
2 /**
3 * Autoloader Generator.
4 *
5 * @package automattic/jetpack-autoloader
6 */
7
8 namespace Automattic\Jetpack\Autoloader;
9
10 use Composer\Composer;
11 use Composer\Config;
12 use Composer\Installer\InstallationManager;
13 use Composer\IO\IOInterface;
14 use Composer\Package\PackageInterface;
15 use Composer\Repository\InstalledRepositoryInterface;
16 use Composer\Util\Filesystem;
17 use Composer\Util\PackageSorter;
18
19 /**
20 * Class AutoloadGenerator.
21 */
22 class AutoloadGenerator {
23
24 const VERSION = '5.0.20';
25
26 /**
27 * IO object.
28 *
29 * @var IOInterface IO object.
30 */
31 private $io;
32
33 /**
34 * The filesystem utility.
35 *
36 * @var Filesystem
37 */
38 private $filesystem;
39
40 /**
41 * Instantiate an AutoloadGenerator object.
42 *
43 * @param IOInterface $io IO object.
44 */
45 public function __construct( IOInterface $io ) {
46 $this->io = $io;
47 $this->filesystem = new Filesystem();
48 }
49
50 /**
51 * Dump the Jetpack autoloader files.
52 *
53 * @param Composer $composer The Composer object.
54 * @param Config $config Config object.
55 * @param InstalledRepositoryInterface $localRepo Installed Repository 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 $scanPsrPackages Whether or not PSR packages should be converted to a classmap.
60 * @param string $suffix The autoloader suffix.
61 */
62 public function dump(
63 Composer $composer,
64 Config $config,
65 InstalledRepositoryInterface $localRepo,
66 PackageInterface $mainPackage,
67 InstallationManager $installationManager,
68 $targetDir,
69 $scanPsrPackages = false,
70 $suffix = null
71 ) {
72 $this->filesystem->ensureDirectoryExists( $config->get( 'vendor-dir' ) );
73
74 $packageMap = $composer->getAutoloadGenerator()->buildPackageMap( $installationManager, $mainPackage, $localRepo->getCanonicalPackages() );
75 $autoloads = $this->parseAutoloads( $packageMap, $mainPackage );
76
77 // Convert the autoloads into a format that the manifest generator can consume more easily.
78 $basePath = $this->filesystem->normalizePath( realpath( getcwd() ) );
79 $vendorPath = $this->filesystem->normalizePath( realpath( $config->get( 'vendor-dir' ) ) );
80 $processedAutoloads = $this->processAutoloads( $autoloads, $scanPsrPackages, $vendorPath, $basePath );
81 unset( $packageMap, $autoloads );
82
83 // Make sure none of the legacy files remain that can lead to problems with the autoloader.
84 $this->removeLegacyFiles( $vendorPath );
85
86 // Write all of the files now that we're done.
87 $this->writeAutoloaderFiles( $vendorPath . '/jetpack-autoloader/', $suffix );
88 $this->writeManifests( $vendorPath . '/' . $targetDir, $processedAutoloads );
89
90 if ( ! $scanPsrPackages ) {
91 $this->io->writeError( '<warning>You are generating an unoptimized autoloader. If this is a production build, consider using the -o option.</warning>' );
92 }
93 }
94
95 /**
96 * Compiles an ordered list of namespace => path mappings
97 *
98 * @param array $packageMap Array of array(package, installDir-relative-to-composer.json).
99 * @param PackageInterface $mainPackage Main package instance.
100 *
101 * @return array The list of path mappings.
102 */
103 public function parseAutoloads( array $packageMap, PackageInterface $mainPackage ) {
104 $rootPackageMap = array_shift( $packageMap );
105
106 $sortedPackageMap = $this->sortPackageMap( $packageMap );
107 $sortedPackageMap[] = $rootPackageMap;
108 array_unshift( $packageMap, $rootPackageMap );
109
110 $psr0 = $this->parseAutoloadsType( $packageMap, 'psr-0', $mainPackage );
111 $psr4 = $this->parseAutoloadsType( $packageMap, 'psr-4', $mainPackage );
112 $classmap = $this->parseAutoloadsType( array_reverse( $sortedPackageMap ), 'classmap', $mainPackage );
113 $files = $this->parseAutoloadsType( $sortedPackageMap, 'files', $mainPackage );
114
115 krsort( $psr0 );
116 krsort( $psr4 );
117
118 return array(
119 'psr-0' => $psr0,
120 'psr-4' => $psr4,
121 'classmap' => $classmap,
122 'files' => $files,
123 );
124 }
125
126 /**
127 * Sorts packages by dependency weight
128 *
129 * Packages of equal weight retain the original order
130 *
131 * @param array $packageMap The package map.
132 *
133 * @return array
134 */
135 protected function sortPackageMap( array $packageMap ) {
136 $packages = array();
137 $paths = array();
138
139 foreach ( $packageMap as $item ) {
140 list( $package, $path ) = $item;
141 $name = $package->getName();
142 $packages[ $name ] = $package;
143 $paths[ $name ] = $path;
144 }
145
146 $sortedPackages = PackageSorter::sortPackages( $packages );
147
148 $sortedPackageMap = array();
149
150 foreach ( $sortedPackages as $package ) {
151 $name = $package->getName();
152 $sortedPackageMap[] = array( $packages[ $name ], $paths[ $name ] );
153 }
154
155 return $sortedPackageMap;
156 }
157
158 /**
159 * Returns the file identifier.
160 *
161 * @param PackageInterface $package The package instance.
162 * @param string $path The path.
163 */
164 protected function getFileIdentifier( PackageInterface $package, $path ) {
165 return md5( $package->getName() . ':' . $path );
166 }
167
168 /**
169 * Returns the path code for the given path.
170 *
171 * @param Filesystem $filesystem The filesystem instance.
172 * @param string $basePath The base path.
173 * @param string $vendorPath The vendor path.
174 * @param string $path The path.
175 *
176 * @return string The path code.
177 */
178 protected function getPathCode( Filesystem $filesystem, $basePath, $vendorPath, $path ) {
179 if ( ! $filesystem->isAbsolutePath( $path ) ) {
180 $path = $basePath . '/' . $path;
181 }
182 $path = $filesystem->normalizePath( $path );
183
184 $baseDir = '';
185 if ( 0 === strpos( $path . '/', $vendorPath . '/' ) ) {
186 $path = substr( $path, strlen( $vendorPath ) );
187 $baseDir = '$vendorDir';
188
189 if ( false !== $path ) {
190 $baseDir .= ' . ';
191 }
192 } else {
193 $path = $filesystem->normalizePath( $filesystem->findShortestPath( $basePath, $path, true ) );
194 if ( ! $filesystem->isAbsolutePath( $path ) ) {
195 $baseDir = '$baseDir . ';
196 $path = '/' . $path;
197 }
198 }
199
200 if ( strpos( $path, '.phar' ) !== false ) {
201 $baseDir = "'phar://' . " . $baseDir;
202 }
203
204 // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_var_export
205 return $baseDir . ( ( false !== $path ) ? var_export( $path, true ) : '' );
206 }
207
208 /**
209 * This function differs from the composer parseAutoloadsType in that beside returning the path.
210 * It also return the path and the version of a package.
211 *
212 * Supports PSR-4, PSR-0, and classmap parsing.
213 *
214 * @param array $packageMap Map of all the packages.
215 * @param string $type Type of autoloader to use.
216 * @param PackageInterface $mainPackage Instance of the Package Object.
217 *
218 * @return array
219 */
220 protected function parseAutoloadsType( array $packageMap, $type, PackageInterface $mainPackage ) {
221 $autoloads = array();
222
223 foreach ( $packageMap as $item ) {
224 list($package, $installPath) = $item;
225 $autoload = $package->getAutoload();
226 $version = $package->getVersion(); // Version of the class comes from the package - should we try to parse it?
227
228 // Store our own actual package version, not "dev-trunk" or whatever.
229 if ( $package->getName() === 'automattic/jetpack-autoloader' ) {
230 $version = self::VERSION;
231 }
232
233 if ( $package === $mainPackage ) {
234 $autoload = array_merge_recursive( $autoload, $package->getDevAutoload() );
235 }
236
237 if ( null !== $package->getTargetDir() && $package !== $mainPackage ) {
238 $installPath = substr( $installPath, 0, -strlen( '/' . $package->getTargetDir() ) );
239 }
240
241 if ( in_array( $type, array( 'psr-4', 'psr-0' ), true ) && isset( $autoload[ $type ] ) && is_array( $autoload[ $type ] ) ) {
242 foreach ( $autoload[ $type ] as $namespace => $paths ) {
243 $paths = is_array( $paths ) ? $paths : array( $paths );
244 foreach ( $paths as $path ) {
245 $relativePath = empty( $installPath ) ? ( empty( $path ) ? '.' : $path ) : $installPath . '/' . $path;
246 $autoloads[ $namespace ][] = array(
247 'path' => $relativePath,
248 'version' => $version,
249 );
250 }
251 }
252 }
253
254 if ( 'classmap' === $type && isset( $autoload['classmap'] ) && is_array( $autoload['classmap'] ) ) {
255 foreach ( $autoload['classmap'] as $paths ) {
256 $paths = is_array( $paths ) ? $paths : array( $paths );
257 foreach ( $paths as $path ) {
258 $relativePath = empty( $installPath ) ? ( empty( $path ) ? '.' : $path ) : $installPath . '/' . $path;
259 $autoloads[] = array(
260 'path' => $relativePath,
261 'version' => $version,
262 );
263 }
264 }
265 }
266 if ( 'files' === $type && isset( $autoload['files'] ) && is_array( $autoload['files'] ) ) {
267 foreach ( $autoload['files'] as $paths ) {
268 $paths = is_array( $paths ) ? $paths : array( $paths );
269 foreach ( $paths as $path ) {
270 $relativePath = empty( $installPath ) ? ( empty( $path ) ? '.' : $path ) : $installPath . '/' . $path;
271 $autoloads[ $this->getFileIdentifier( $package, $path ) ] = array(
272 'path' => $relativePath,
273 'version' => $version,
274 );
275 }
276 }
277 }
278 }
279
280 return $autoloads;
281 }
282
283 /**
284 * Given Composer's autoloads this will convert them to a version that we can use to generate the manifests.
285 *
286 * When the $scanPsrPackages argument is true, PSR-4 namespaces are converted to classmaps. When $scanPsrPackages
287 * is false, PSR-4 namespaces are not converted to classmaps.
288 *
289 * PSR-0 namespaces are always converted to classmaps.
290 *
291 * @param array $autoloads The autoloads we want to process.
292 * @param bool $scanPsrPackages Whether or not PSR-4 packages should be converted to a classmap.
293 * @param string $vendorPath The path to the vendor directory.
294 * @param string $basePath The path to the current directory.
295 *
296 * @return array $processedAutoloads
297 */
298 private function processAutoloads( $autoloads, $scanPsrPackages, $vendorPath, $basePath ) {
299 $processor = new AutoloadProcessor(
300 function ( $path, $excludedClasses, $namespace ) use ( $basePath ) {
301 $dir = $this->filesystem->normalizePath(
302 $this->filesystem->isAbsolutePath( $path ) ? $path : $basePath . '/' . $path
303 );
304
305 // Composer 2.4 changed the name of the class.
306 if ( class_exists( \Composer\ClassMapGenerator\ClassMapGenerator::class ) ) {
307 if ( ! is_dir( $dir ) && ! is_file( $dir ) ) {
308 return array();
309 }
310 $generator = new \Composer\ClassMapGenerator\ClassMapGenerator();
311 $generator->scanPaths( $dir, $excludedClasses, 'classmap', empty( $namespace ) ? null : $namespace );
312 return $generator->getClassMap()->getMap();
313 }
314
315 return \Composer\Autoload\ClassMapGenerator::createMap(
316 $dir,
317 $excludedClasses,
318 null, // Don't pass the IOInterface since the normal autoload generation will have reported already.
319 empty( $namespace ) ? null : $namespace
320 );
321 },
322 function ( $path ) use ( $basePath, $vendorPath ) {
323 return $this->getPathCode( $this->filesystem, $basePath, $vendorPath, $path );
324 }
325 );
326
327 return array(
328 'psr-4' => $processor->processPsr4Packages( $autoloads, $scanPsrPackages ),
329 'classmap' => $processor->processClassmap( $autoloads, $scanPsrPackages ),
330 'files' => $processor->processFiles( $autoloads ),
331 );
332 }
333
334 /**
335 * Removes all of the legacy autoloader files so they don't cause any problems.
336 *
337 * @param string $outDir The directory legacy files are written to.
338 */
339 private function removeLegacyFiles( $outDir ) {
340 $files = array(
341 'autoload_functions.php',
342 'class-autoloader-handler.php',
343 'class-classes-handler.php',
344 'class-files-handler.php',
345 'class-plugins-handler.php',
346 'class-version-selector.php',
347 );
348 foreach ( $files as $file ) {
349 $this->filesystem->remove( $outDir . '/' . $file );
350 }
351 }
352
353 /**
354 * Writes all of the autoloader files to disk.
355 *
356 * @param string $outDir The directory to write to.
357 * @param string $suffix The unique autoloader suffix.
358 */
359 private function writeAutoloaderFiles( $outDir, $suffix ) {
360 $this->io->writeError( "<info>Generating jetpack autoloader ($outDir)</info>" );
361
362 // We will remove all autoloader files to generate this again.
363 $this->filesystem->emptyDirectory( $outDir );
364
365 // Write the autoloader files.
366 AutoloadFileWriter::copyAutoloaderFiles( $this->io, $outDir, $suffix );
367 }
368
369 /**
370 * Writes all of the manifest files to disk.
371 *
372 * @param string $outDir The directory to write to.
373 * @param array $processedAutoloads The processed autoloads.
374 */
375 private function writeManifests( $outDir, $processedAutoloads ) {
376 $this->io->writeError( "<info>Generating jetpack autoloader manifests ($outDir)</info>" );
377
378 $manifestFiles = array(
379 'classmap' => 'jetpack_autoload_classmap.php',
380 'psr-4' => 'jetpack_autoload_psr4.php',
381 'files' => 'jetpack_autoload_filemap.php',
382 );
383
384 foreach ( $manifestFiles as $key => $file ) {
385 // Make sure the file doesn't exist so it isn't there if we don't write it.
386 $this->filesystem->remove( $outDir . '/' . $file );
387 if ( empty( $processedAutoloads[ $key ] ) ) {
388 continue;
389 }
390
391 $content = ManifestGenerator::buildManifest( $key, $file, $processedAutoloads[ $key ] );
392 if ( empty( $content ) ) {
393 continue;
394 }
395
396 if ( file_put_contents( $outDir . '/' . $file, $content ) ) {
397 $this->io->writeError( " <info>Generated: $file</info>" );
398 } else {
399 $this->io->writeError( " <error>Error: $file</error>" );
400 }
401 }
402 }
403 }
404