PageRenderTime 48ms CodeModel.GetById 10ms app.highlight 28ms RepoModel.GetById 2ms app.codeStats 0ms

/wp-content/plugins/wordpress-seo/vendor/xrstf/composer-php52/lib/xrstf/Composer52/AutoloadGenerator.php

https://bitbucket.org/carloskikea/helpet
PHP | 346 lines | 213 code | 86 blank | 47 comment | 24 complexity | f7641acbeb0d28763a60fd4ee8fc0a03 MD5 | raw file
  1<?php
  2/*
  3 * Copyright (c) 2013, Christoph Mewes, http://www.xrstf.de
  4 *
  5 * This file is released under the terms of the MIT license. You can find the
  6 * complete text in the attached LICENSE file or online at:
  7 *
  8 * http://www.opensource.org/licenses/mit-license.php
  9 *
 10 * --------------------------------------------------------------------------
 11 *
 12 * 99% of this is copied as-is from the original Composer source code and is
 13 * released under MIT license as well. Copyright goes to:
 14 *
 15 * - Igor Wiedler <igor@wiedler.ch>
 16 * - Jordi Boggiano <j.boggiano@seld.be>
 17 */
 18
 19namespace xrstf\Composer52;
 20
 21use Composer\Autoload\AutoloadGenerator as BaseGenerator;
 22use Composer\Autoload\ClassMapGenerator;
 23use Composer\Config;
 24use Composer\Installer\InstallationManager;
 25use Composer\Package\AliasPackage;
 26use Composer\Package\PackageInterface;
 27use Composer\Repository\InstalledRepositoryInterface;
 28use Composer\Util\Filesystem;
 29
 30class AutoloadGenerator extends BaseGenerator {
 31
 32	/**
 33	 * @var bool
 34	 */
 35	private $classMapAuthoritative = false;
 36
 37	public function __construct() {
 38		// do nothing (but keep this constructor so we can build an instance without the need for an event dispatcher)
 39	}
 40
 41	/**
 42	 * Whether or not generated autoloader considers the class map
 43	 * authoritative.
 44	 *
 45	 * @param bool $classMapAuthoritative
 46	 */
 47	public function setClassMapAuthoritative($classMapAuthoritative)
 48	{
 49		$this->classMapAuthoritative = (boolean) $classMapAuthoritative;
 50	}
 51
 52	public function dump(Config $config, InstalledRepositoryInterface $localRepo, PackageInterface $mainPackage, InstallationManager $installationManager, $targetDir, $scanPsr0Packages = false, $suffix = '') {
 53		if ($this->classMapAuthoritative) {
 54			// Force scanPsr0Packages when classmap is authoritative
 55			$scanPsr0Packages = true;
 56		}
 57
 58		$filesystem = new Filesystem();
 59		$filesystem->ensureDirectoryExists($config->get('vendor-dir'));
 60
 61		$cwd        = getcwd();
 62		$basePath   = $filesystem->normalizePath($cwd);
 63		$vendorPath = $filesystem->normalizePath(realpath($config->get('vendor-dir')));
 64		$targetDir  = $vendorPath.'/'.$targetDir;
 65		$filesystem->ensureDirectoryExists($targetDir);
 66
 67		$useGlobalIncludePath  = (bool) $config->get('use-include-path');
 68		$prependAutoloader     = $config->get('prepend-autoloader') === false ? 'false' : 'true';
 69		$classMapAuthoritative = $config->get('classmap-authoritative');
 70
 71		$vendorPathCode            = $filesystem->findShortestPathCode(realpath($targetDir), $vendorPath, true);
 72		$vendorPathToTargetDirCode = $filesystem->findShortestPathCode($vendorPath, realpath($targetDir), true);
 73
 74		$appBaseDirCode = $filesystem->findShortestPathCode($vendorPath, $basePath, true);
 75		$appBaseDirCode = str_replace('__DIR__', '$vendorDir', $appBaseDirCode);
 76
 77		// add 5.2 compat
 78		$vendorPathCode            = str_replace('__DIR__', 'dirname(__FILE__)', $vendorPathCode);
 79		$vendorPathToTargetDirCode = str_replace('__DIR__', 'dirname(__FILE__)', $vendorPathToTargetDirCode);
 80
 81		$packageMap = $this->buildPackageMap($installationManager, $mainPackage, $localRepo->getCanonicalPackages());
 82		$autoloads = $this->parseAutoloads($packageMap, $mainPackage);
 83
 84		// add custom psr-0 autoloading if the root package has a target dir
 85		$targetDirLoader = null;
 86		$mainAutoload = $mainPackage->getAutoload();
 87		if ($mainPackage->getTargetDir() && !empty($mainAutoload['psr-0'])) {
 88			$levels   = count(explode('/', $filesystem->normalizePath($mainPackage->getTargetDir())));
 89			$prefixes = implode(', ', array_map(function ($prefix) {
 90				return var_export($prefix, true);
 91			}, array_keys($mainAutoload['psr-0'])));
 92
 93			$baseDirFromTargetDirCode = $filesystem->findShortestPathCode($targetDir, $basePath, true);
 94
 95			$targetDirLoader = <<<EOF
 96
 97	public static function autoload(\$class) {
 98		\$dir      = $baseDirFromTargetDirCode.'/';
 99		\$prefixes = array($prefixes);
100
101		foreach (\$prefixes as \$prefix) {
102			if (0 !== strpos(\$class, \$prefix)) {
103				continue;
104			}
105
106			\$path = explode(DIRECTORY_SEPARATOR, self::getClassPath(\$class));
107			\$path = \$dir.implode('/', array_slice(\$path, $levels));
108
109			if (!\$path = self::resolveIncludePath(\$path)) {
110				return false;
111			}
112
113			require \$path;
114			return true;
115		}
116	}
117
118EOF;
119		}
120
121		$filesCode = "";
122		$autoloads['files'] = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($autoloads['files']));
123		foreach ($autoloads['files'] as $functionFile) {
124			// don't include file if it is using PHP 5.3+ syntax
125			// https://bitbucket.org/xrstf/composer-php52/issue/4
126			if ($this->isPHP53($functionFile)) {
127				$filesCode .= '//		require '.$this->getPathCode($filesystem, $basePath, $vendorPath, $functionFile)."; // disabled because of PHP 5.3 syntax\n";
128			}
129			else {
130				$filesCode .= '		require '.$this->getPathCode($filesystem, $basePath, $vendorPath, $functionFile).";\n";
131			}
132		}
133
134		if (!$suffix) {
135			$suffix = md5(uniqid('', true));
136		}
137
138		$includePathFile = $this->getIncludePathsFile($packageMap, $filesystem, $basePath, $vendorPath, $vendorPathCode, $appBaseDirCode);
139
140		file_put_contents($vendorPath.'/autoload_52.php', $this->getAutoloadFile($vendorPathToTargetDirCode, $suffix));
141		file_put_contents($targetDir.'/autoload_real_52.php', $this->getAutoloadRealFile(true, (bool) $includePathFile, $targetDirLoader, $filesCode, $vendorPathCode, $appBaseDirCode, $suffix, $useGlobalIncludePath, $prependAutoloader));
142
143		// use stream_copy_to_stream instead of copy
144		// to work around https://bugs.php.net/bug.php?id=64634
145		$sourceLoader = fopen(__DIR__.'/ClassLoader.php', 'r');
146		$targetLoader = fopen($targetDir.'/ClassLoader52.php', 'w+');
147		stream_copy_to_stream($sourceLoader, $targetLoader);
148		fclose($sourceLoader);
149		fclose($targetLoader);
150		unset($sourceLoader, $targetLoader);
151	}
152
153	protected function isPHP53($file) {
154		$tokens = token_get_all(file_get_contents($file));
155		$php53  = array(T_DIR, T_GOTO, T_NAMESPACE, T_NS_C, T_NS_SEPARATOR, T_USE);
156
157		// PHP 5.4+
158		if (defined('T_TRAIT')) {
159			$php53[] = T_TRAIT;
160			$php53[] = T_TRAIT_C;
161			$php53[] = T_TRAIT_C;
162		}
163
164		// PHP 5.5+
165		if (defined('T_FINALLY')) {
166			$php53[] = T_FINALLY;
167			$php53[] = T_YIELD;
168		}
169
170		foreach ($tokens as $token) {
171			if (is_array($token) && in_array($token[0], $php53)) {
172				return true;
173			}
174		}
175
176		return false;
177	}
178
179	protected function getIncludePathsFile(array $packageMap, Filesystem $filesystem, $basePath, $vendorPath, $vendorPathCode, $appBaseDirCode) {
180		$includePaths = array();
181
182		foreach ($packageMap as $item) {
183			list($package, $installPath) = $item;
184
185			if (null !== $package->getTargetDir() && strlen($package->getTargetDir()) > 0) {
186				$installPath = substr($installPath, 0, -strlen('/'.$package->getTargetDir()));
187			}
188
189			foreach ($package->getIncludePaths() as $includePath) {
190				$includePath = trim($includePath, '/');
191				$includePaths[] = empty($installPath) ? $includePath : $installPath.'/'.$includePath;
192			}
193		}
194
195		if (!$includePaths) {
196			return;
197		}
198
199		$includePathsFile = <<<EOF
200<?php
201
202// include_paths_52.php generated by xrstf/composer-php52
203
204\$vendorDir = $vendorPathCode;
205\$baseDir = $appBaseDirCode;
206
207return array(
208
209EOF;
210
211		foreach ($includePaths as $path) {
212			$includePathsFile .= "\t" . $this->getPathCode($filesystem, $basePath, $vendorPath, $path) . ",\n";
213		}
214
215		return $includePathsFile . ");\n";
216	}
217
218	protected function getAutoloadFile($vendorPathToTargetDirCode, $suffix) {
219		return <<<AUTOLOAD
220<?php
221
222// autoload_52.php generated by xrstf/composer-php52
223
224require_once $vendorPathToTargetDirCode.'/autoload_real_52.php';
225
226return ComposerAutoloaderInit$suffix::getLoader();
227
228AUTOLOAD;
229	}
230
231	protected function getAutoloadRealFile($useClassMap, $useIncludePath, $targetDirLoader, $filesCode, $vendorPathCode, $appBaseDirCode, $suffix, $useGlobalIncludePath, $prependAutoloader, $staticPhpVersion = 70000) {
232		// TODO the class ComposerAutoloaderInit should be revert to a closure
233		// when APC has been fixed:
234		// - https://github.com/composer/composer/issues/959
235		// - https://bugs.php.net/bug.php?id=52144
236		// - https://bugs.php.net/bug.php?id=61576
237		// - https://bugs.php.net/bug.php?id=59298
238
239		if ($filesCode) {
240				$filesCode = "\n\n".rtrim($filesCode);
241		}
242
243		$file = <<<HEADER
244<?php
245
246// autoload_real_52.php generated by xrstf/composer-php52
247
248class ComposerAutoloaderInit$suffix {
249	private static \$loader;
250
251	public static function loadClassLoader(\$class) {
252		if ('xrstf_Composer52_ClassLoader' === \$class) {
253			require dirname(__FILE__).'/ClassLoader52.php';
254		}
255	}
256
257	/**
258	 * @return xrstf_Composer52_ClassLoader
259	 */
260	public static function getLoader() {
261		if (null !== self::\$loader) {
262			return self::\$loader;
263		}
264
265		spl_autoload_register(array('ComposerAutoloaderInit$suffix', 'loadClassLoader'), true /*, true */);
266		self::\$loader = \$loader = new xrstf_Composer52_ClassLoader();
267		spl_autoload_unregister(array('ComposerAutoloaderInit$suffix', 'loadClassLoader'));
268
269		\$vendorDir = $vendorPathCode;
270		\$baseDir   = $appBaseDirCode;
271		\$dir       = dirname(__FILE__);
272
273
274HEADER;
275
276		if ($useIncludePath) {
277			$file .= <<<'INCLUDE_PATH'
278		$includePaths = require $dir.'/include_paths.php';
279		array_push($includePaths, get_include_path());
280		set_include_path(implode(PATH_SEPARATOR, $includePaths));
281
282
283INCLUDE_PATH;
284		}
285
286		$file .= <<<'PSR0'
287		$map = require $dir.'/autoload_namespaces.php';
288		foreach ($map as $namespace => $path) {
289			$loader->add($namespace, $path);
290		}
291
292
293PSR0;
294
295		if ($useClassMap) {
296			$file .= <<<'CLASSMAP'
297		$classMap = require $dir.'/autoload_classmap.php';
298		if ($classMap) {
299			$loader->addClassMap($classMap);
300		}
301
302
303CLASSMAP;
304		}
305
306		if ($this->classMapAuthoritative) {
307			$file .= <<<'CLASSMAPAUTHORITATIVE'
308		$loader->setClassMapAuthoritative(true);
309
310CLASSMAPAUTHORITATIVE;
311		}
312
313		if ($useGlobalIncludePath) {
314			$file .= <<<'INCLUDEPATH'
315		$loader->setUseIncludePath(true);
316
317
318INCLUDEPATH;
319		}
320
321		if ($targetDirLoader) {
322			$file .= <<<REGISTER_AUTOLOAD
323		spl_autoload_register(array('ComposerAutoloaderInit$suffix', 'autoload'), true);
324
325
326REGISTER_AUTOLOAD;
327
328		}
329
330		$file .= <<<METHOD_FOOTER
331		\$loader->register($prependAutoloader);{$filesCode}
332
333		return \$loader;
334	}
335
336METHOD_FOOTER;
337
338		$file .= $targetDirLoader;
339
340		return $file . <<<FOOTER
341}
342
343FOOTER;
344
345	}
346}