public function dump(Config $config, InstalledRepositoryInterface $localRepo, PackageInterface $mainPackage, InstallationManager $installationManager, $targetDir, $scanPsr0Packages = false, $suffix = '') { if ($this->classMapAuthoritative) { // Force scanPsr0Packages when classmap is authoritative $scanPsr0Packages = true; } $this->eventDispatcher->dispatchScript(ScriptEvents::PRE_AUTOLOAD_DUMP, $this->devMode, array(), array('optimize' => (bool) $scanPsr0Packages)); $filesystem = new Filesystem(); $filesystem->ensureDirectoryExists($config->get('vendor-dir')); $basePath = $filesystem->normalizePath(realpath(getcwd())); $vendorPath = $filesystem->normalizePath(realpath($config->get('vendor-dir'))); $useGlobalIncludePath = (bool) $config->get('use-include-path'); $prependAutoloader = $config->get('prepend-autoloader') === false ? 'false' : 'true'; $targetDir = $vendorPath . '/' . $targetDir; $filesystem->ensureDirectoryExists($targetDir); $vendorPathCode = $filesystem->findShortestPathCode(realpath($targetDir), $vendorPath, true); $vendorPathCode52 = str_replace('__DIR__', 'dirname(__FILE__)', $vendorPathCode); $vendorPathToTargetDirCode = $filesystem->findShortestPathCode($vendorPath, realpath($targetDir), true); $appBaseDirCode = $filesystem->findShortestPathCode($vendorPath, $basePath, true); $appBaseDirCode = str_replace('__DIR__', '$vendorDir', $appBaseDirCode); $namespacesFile = <<<EOF <?php // autoload_namespaces.php @generated by Composer \$vendorDir = {$vendorPathCode52}; \$baseDir = {$appBaseDirCode}; return array( EOF; $psr4File = <<<EOF <?php // autoload_psr4.php @generated by Composer \$vendorDir = {$vendorPathCode52}; \$baseDir = {$appBaseDirCode}; return array( EOF; // Collect information from all packages. $packageMap = $this->buildPackageMap($installationManager, $mainPackage, $localRepo->getCanonicalPackages()); $autoloads = $this->parseAutoloads($packageMap, $mainPackage); // Process the 'psr-0' base directories. foreach ($autoloads['psr-0'] as $namespace => $paths) { $exportedPaths = array(); foreach ($paths as $path) { $exportedPaths[] = $this->getPathCode($filesystem, $basePath, $vendorPath, $path); } $exportedPrefix = var_export($namespace, true); $namespacesFile .= " {$exportedPrefix} => "; $namespacesFile .= "array(" . implode(', ', $exportedPaths) . "),\n"; } $namespacesFile .= ");\n"; // Process the 'psr-4' base directories. foreach ($autoloads['psr-4'] as $namespace => $paths) { $exportedPaths = array(); foreach ($paths as $path) { $exportedPaths[] = $this->getPathCode($filesystem, $basePath, $vendorPath, $path); } $exportedPrefix = var_export($namespace, true); $psr4File .= " {$exportedPrefix} => "; $psr4File .= "array(" . implode(', ', $exportedPaths) . "),\n"; } $psr4File .= ");\n"; $classmapFile = <<<EOF <?php // autoload_classmap.php @generated by Composer \$vendorDir = {$vendorPathCode52}; \$baseDir = {$appBaseDirCode}; return array( EOF; // add custom psr-0 autoloading if the root package has a target dir $targetDirLoader = null; $mainAutoload = $mainPackage->getAutoload(); if ($mainPackage->getTargetDir() && !empty($mainAutoload['psr-0'])) { $levels = count(explode('/', $filesystem->normalizePath($mainPackage->getTargetDir()))); $prefixes = implode(', ', array_map(function ($prefix) { return var_export($prefix, true); }, array_keys($mainAutoload['psr-0']))); $baseDirFromTargetDirCode = $filesystem->findShortestPathCode($targetDir, $basePath, true); $targetDirLoader = <<<EOF public static function autoload(\$class) { \$dir = {$baseDirFromTargetDirCode} . '/'; \$prefixes = array({$prefixes}); foreach (\$prefixes as \$prefix) { if (0 !== strpos(\$class, \$prefix)) { continue; } \$path = \$dir . implode('/', array_slice(explode('\\\\', \$class), {$levels})).'.php'; if (!\$path = stream_resolve_include_path(\$path)) { return false; } require \$path; return true; } } EOF; } $blacklist = null; if (!empty($autoloads['exclude-from-classmap'])) { $blacklist = '{(' . implode('|', $autoloads['exclude-from-classmap']) . ')}'; } // flatten array $classMap = array(); if ($scanPsr0Packages) { $namespacesToScan = array(); // Scan the PSR-0/4 directories for class files, and add them to the class map foreach (array('psr-0', 'psr-4') as $psrType) { foreach ($autoloads[$psrType] as $namespace => $paths) { $namespacesToScan[$namespace][] = array('paths' => $paths, 'type' => $psrType); } } krsort($namespacesToScan); foreach ($namespacesToScan as $namespace => $groups) { foreach ($groups as $group) { $psrType = $group['type']; foreach ($group['paths'] as $dir) { $dir = $filesystem->normalizePath($filesystem->isAbsolutePath($dir) ? $dir : $basePath . '/' . $dir); if (!is_dir($dir)) { continue; } // $whitelist = sprintf( // '{%s/%s.+$}', // preg_quote($dir), // ($psrType === 'psr-0' && strpos($namespace, '_') === false) ? preg_quote(strtr($namespace, '\\', '/')) : '' // ); $namespaceFilter = $namespace === '' ? null : $namespace; $classMap = $this->addClassMapCode($filesystem, $basePath, $vendorPath, $dir, $blacklist, $namespaceFilter, $classMap); } } } } foreach ($autoloads['classmap'] as $dir) { $classMap = $this->addClassMapCode($filesystem, $basePath, $vendorPath, $dir, $blacklist, null, $classMap); } ksort($classMap); foreach ($classMap as $class => $code) { $classmapFile .= ' ' . var_export($class, true) . ' => ' . $code; } $classmapFile .= ");\n"; if (!$suffix) { if (!$config->get('autoloader-suffix') && is_readable($vendorPath . '/autoload.php')) { $content = file_get_contents($vendorPath . '/autoload.php'); if (preg_match('{ComposerAutoloaderInit([^:\\s]+)::}', $content, $match)) { $suffix = $match[1]; } } if (!$suffix) { $suffix = $config->get('autoloader-suffix') ?: md5(uniqid('', true)); } } file_put_contents($targetDir . '/autoload_namespaces.php', $namespacesFile); file_put_contents($targetDir . '/autoload_psr4.php', $psr4File); file_put_contents($targetDir . '/autoload_classmap.php', $classmapFile); $includePathFilePath = $targetDir . '/include_paths.php'; if ($includePathFileContents = $this->getIncludePathsFile($packageMap, $filesystem, $basePath, $vendorPath, $vendorPathCode52, $appBaseDirCode)) { file_put_contents($includePathFilePath, $includePathFileContents); } elseif (file_exists($includePathFilePath)) { unlink($includePathFilePath); } $includeFilesFilePath = $targetDir . '/autoload_files.php'; if ($includeFilesFileContents = $this->getIncludeFilesFile($autoloads['files'], $filesystem, $basePath, $vendorPath, $vendorPathCode52, $appBaseDirCode)) { file_put_contents($includeFilesFilePath, $includeFilesFileContents); } elseif (file_exists($includeFilesFilePath)) { unlink($includeFilesFilePath); } file_put_contents($vendorPath . '/autoload.php', $this->getAutoloadFile($vendorPathToTargetDirCode, $suffix)); file_put_contents($targetDir . '/autoload_real.php', $this->getAutoloadRealFile(true, (bool) $includePathFileContents, $targetDirLoader, (bool) $includeFilesFileContents, $vendorPathCode, $appBaseDirCode, $suffix, $useGlobalIncludePath, $prependAutoloader)); $this->safeCopy(__DIR__ . '/ClassLoader.php', $targetDir . '/ClassLoader.php'); $this->safeCopy(__DIR__ . '/../../../LICENSE', $targetDir . '/LICENSE'); $this->eventDispatcher->dispatchScript(ScriptEvents::POST_AUTOLOAD_DUMP, $this->devMode, array(), array('optimize' => (bool) $scanPsr0Packages)); }
public function dump(Config $config, InstalledRepositoryInterface $localRepo, PackageInterface $mainPackage, InstallationManager $installationManager, $targetDir, $scanPsr0Packages = false, $suffix = '') { $this->eventDispatcher->dispatchScript(ScriptEvents::PRE_AUTOLOAD_DUMP, $this->devMode); $filesystem = new Filesystem(); $filesystem->ensureDirectoryExists($config->get('vendor-dir')); $basePath = $filesystem->normalizePath(realpath(getcwd())); $vendorPath = $filesystem->normalizePath(realpath($config->get('vendor-dir'))); $useGlobalIncludePath = (bool) $config->get('use-include-path'); $prependAutoloader = $config->get('prepend-autoloader') === false ? 'false' : 'true'; $targetDir = $vendorPath . '/' . $targetDir; $filesystem->ensureDirectoryExists($targetDir); $vendorPathCode = $filesystem->findShortestPathCode(realpath($targetDir), $vendorPath, true); $vendorPathCode52 = str_replace('__DIR__', 'dirname(__FILE__)', $vendorPathCode); $vendorPathToTargetDirCode = $filesystem->findShortestPathCode($vendorPath, realpath($targetDir), true); $appBaseDirCode = $filesystem->findShortestPathCode($vendorPath, $basePath, true); $appBaseDirCode = str_replace('__DIR__', '$vendorDir', $appBaseDirCode); $namespacesFile = <<<EOF <?php // autoload_namespaces.php @generated by Composer \$vendorDir = {$vendorPathCode52}; \$baseDir = {$appBaseDirCode}; return array( EOF; $psr4File = <<<EOF <?php // autoload_psr4.php @generated by Composer \$vendorDir = {$vendorPathCode52}; \$baseDir = {$appBaseDirCode}; return array( EOF; // Collect information from all packages. $packageMap = $this->buildPackageMap($installationManager, $mainPackage, $localRepo->getCanonicalPackages()); $autoloads = $this->parseAutoloads($packageMap, $mainPackage); // Process the 'psr-0' base directories. foreach ($autoloads['psr-0'] as $namespace => $paths) { $exportedPaths = array(); foreach ($paths as $path) { $exportedPaths[] = $this->getPathCode($filesystem, $basePath, $vendorPath, $path); } $exportedPrefix = var_export($namespace, true); $namespacesFile .= " {$exportedPrefix} => "; $namespacesFile .= "array(" . implode(', ', $exportedPaths) . "),\n"; } $namespacesFile .= ");\n"; // Process the 'psr-4' base directories. foreach ($autoloads['psr-4'] as $namespace => $paths) { $exportedPaths = array(); foreach ($paths as $path) { $exportedPaths[] = $this->getPathCode($filesystem, $basePath, $vendorPath, $path); } $exportedPrefix = var_export($namespace, true); $psr4File .= " {$exportedPrefix} => "; $psr4File .= "array(" . implode(', ', $exportedPaths) . "),\n"; } $psr4File .= ");\n"; $classmapFile = <<<EOF <?php // autoload_classmap.php @generated by Composer \$vendorDir = {$vendorPathCode52}; \$baseDir = {$appBaseDirCode}; return array( EOF; // add custom psr-0 autoloading if the root package has a target dir $targetDirLoader = null; $mainAutoload = $mainPackage->getAutoload(); if ($mainPackage->getTargetDir() && !empty($mainAutoload['psr-0'])) { $levels = count(explode('/', $filesystem->normalizePath($mainPackage->getTargetDir()))); $prefixes = implode(', ', array_map(function ($prefix) { return var_export($prefix, true); }, array_keys($mainAutoload['psr-0']))); $baseDirFromTargetDirCode = $filesystem->findShortestPathCode($targetDir, $basePath, true); $targetDirLoader = <<<EOF public static function autoload(\$class) { \$dir = {$baseDirFromTargetDirCode} . '/'; \$prefixes = array({$prefixes}); foreach (\$prefixes as \$prefix) { if (0 !== strpos(\$class, \$prefix)) { continue; } \$path = \$dir . implode('/', array_slice(explode('\\\\', \$class), {$levels})).'.php'; if (!\$path = stream_resolve_include_path(\$path)) { return false; } require \$path; return true; } } EOF; } // flatten array $classMap = array(); if ($scanPsr0Packages) { // Scan the PSR-0/4 directories for class files, and add them to the class map foreach (array('psr-0', 'psr-4') as $psrType) { foreach ($autoloads[$psrType] as $namespace => $paths) { foreach ($paths as $dir) { $dir = $filesystem->normalizePath($filesystem->isAbsolutePath($dir) ? $dir : $basePath . '/' . $dir); if (!is_dir($dir)) { continue; } $whitelist = sprintf('{%s/%s.+(?<!(?<!/)Test\\.php)$}', preg_quote($dir), $psrType === 'psr-0' && strpos($namespace, '_') === false ? preg_quote(strtr($namespace, '\\', '/')) : ''); $namespaceFilter = $namespace === '' ? null : $namespace; foreach (ClassMapGenerator::createMap($dir, $whitelist, $this->io, $namespaceFilter) as $class => $path) { if (!isset($classMap[$class])) { $path = $this->getPathCode($filesystem, $basePath, $vendorPath, $path); $classMap[$class] = $path . ",\n"; } } } } } } foreach ($autoloads['classmap'] as $dir) { foreach (ClassMapGenerator::createMap($dir, null, $this->io) as $class => $path) { $path = $this->getPathCode($filesystem, $basePath, $vendorPath, $path); $classMap[$class] = $path . ",\n"; } } ksort($classMap); foreach ($classMap as $class => $code) { $classmapFile .= ' ' . var_export($class, true) . ' => ' . $code; } $classmapFile .= ");\n"; if (!$suffix) { $suffix = $config->get('autoloader-suffix') ?: md5(uniqid('', true)); } file_put_contents($targetDir . '/autoload_namespaces.php', $namespacesFile); file_put_contents($targetDir . '/autoload_psr4.php', $psr4File); file_put_contents($targetDir . '/autoload_classmap.php', $classmapFile); if ($includePathFile = $this->getIncludePathsFile($packageMap, $filesystem, $basePath, $vendorPath, $vendorPathCode52, $appBaseDirCode)) { file_put_contents($targetDir . '/include_paths.php', $includePathFile); } if ($includeFilesFile = $this->getIncludeFilesFile($autoloads['files'], $filesystem, $basePath, $vendorPath, $vendorPathCode52, $appBaseDirCode)) { file_put_contents($targetDir . '/autoload_files.php', $includeFilesFile); } file_put_contents($vendorPath . '/autoload.php', $this->getAutoloadFile($vendorPathToTargetDirCode, $suffix)); file_put_contents($targetDir . '/autoload_real.php', $this->getAutoloadRealFile(true, (bool) $includePathFile, $targetDirLoader, (bool) $includeFilesFile, $vendorPathCode, $appBaseDirCode, $suffix, $useGlobalIncludePath, $prependAutoloader)); // use stream_copy_to_stream instead of copy // to work around https://bugs.php.net/bug.php?id=64634 $sourceLoader = fopen(__DIR__ . '/ClassLoader.php', 'r'); $targetLoader = fopen($targetDir . '/ClassLoader.php', 'w+'); stream_copy_to_stream($sourceLoader, $targetLoader); fclose($sourceLoader); fclose($targetLoader); unset($sourceLoader, $targetLoader); $this->eventDispatcher->dispatchScript(ScriptEvents::POST_AUTOLOAD_DUMP, $this->devMode); }
public function dump(Config $config, InstalledRepositoryInterface $localRepo, PackageInterface $mainPackage, InstallationManager $installationManager, $targetDir, $scanPsr0Packages = false, $suffix = '') { if ($this->classMapAuthoritative) { // Force scanPsr0Packages when classmap is authoritative $scanPsr0Packages = true; } $filesystem = new Filesystem(); $filesystem->ensureDirectoryExists($config->get('vendor-dir')); $cwd = getcwd(); $basePath = $filesystem->normalizePath($cwd); $vendorPath = $filesystem->normalizePath(realpath($config->get('vendor-dir'))); $targetDir = $vendorPath . '/' . $targetDir; $filesystem->ensureDirectoryExists($targetDir); $useGlobalIncludePath = (bool) $config->get('use-include-path'); $prependAutoloader = $config->get('prepend-autoloader') === false ? 'false' : 'true'; $classMapAuthoritative = $config->get('classmap-authoritative'); $vendorPathCode = $filesystem->findShortestPathCode(realpath($targetDir), $vendorPath, true); $vendorPathToTargetDirCode = $filesystem->findShortestPathCode($vendorPath, realpath($targetDir), true); $appBaseDirCode = $filesystem->findShortestPathCode($vendorPath, $basePath, true); $appBaseDirCode = str_replace('__DIR__', '$vendorDir', $appBaseDirCode); // add 5.2 compat $vendorPathCode = str_replace('__DIR__', 'dirname(__FILE__)', $vendorPathCode); $vendorPathToTargetDirCode = str_replace('__DIR__', 'dirname(__FILE__)', $vendorPathToTargetDirCode); $packageMap = $this->buildPackageMap($installationManager, $mainPackage, $localRepo->getCanonicalPackages()); $autoloads = $this->parseAutoloads($packageMap, $mainPackage); // add custom psr-0 autoloading if the root package has a target dir $targetDirLoader = null; $mainAutoload = $mainPackage->getAutoload(); if ($mainPackage->getTargetDir() && !empty($mainAutoload['psr-0'])) { $levels = count(explode('/', $filesystem->normalizePath($mainPackage->getTargetDir()))); $prefixes = implode(', ', array_map(function ($prefix) { return var_export($prefix, true); }, array_keys($mainAutoload['psr-0']))); $baseDirFromTargetDirCode = $filesystem->findShortestPathCode($targetDir, $basePath, true); $targetDirLoader = <<<EOF \tpublic static function autoload(\$class) { \t\t\$dir = {$baseDirFromTargetDirCode}.'/'; \t\t\$prefixes = array({$prefixes}); \t\tforeach (\$prefixes as \$prefix) { \t\t\tif (0 !== strpos(\$class, \$prefix)) { \t\t\t\tcontinue; \t\t\t} \t\t\t\$path = explode(DIRECTORY_SEPARATOR, self::getClassPath(\$class)); \t\t\t\$path = \$dir.implode('/', array_slice(\$path, {$levels})); \t\t\tif (!\$path = self::resolveIncludePath(\$path)) { \t\t\t\treturn false; \t\t\t} \t\t\trequire \$path; \t\t\treturn true; \t\t} \t} EOF; } $filesCode = ""; $autoloads['files'] = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($autoloads['files'])); foreach ($autoloads['files'] as $functionFile) { // don't include file if it is using PHP 5.3+ syntax // https://bitbucket.org/xrstf/composer-php52/issue/4 if ($this->isPHP53($functionFile)) { $filesCode .= '// require ' . $this->getPathCode($filesystem, $basePath, $vendorPath, $functionFile) . "; // disabled because of PHP 5.3 syntax\n"; } else { $filesCode .= ' require ' . $this->getPathCode($filesystem, $basePath, $vendorPath, $functionFile) . ";\n"; } } if (!$suffix) { $suffix = md5(uniqid('', true)); } $includePathFile = $this->getIncludePathsFile($packageMap, $filesystem, $basePath, $vendorPath, $vendorPathCode, $appBaseDirCode); file_put_contents($vendorPath . '/autoload_52.php', $this->getAutoloadFile($vendorPathToTargetDirCode, $suffix)); file_put_contents($targetDir . '/autoload_real_52.php', $this->getAutoloadRealFile(true, (bool) $includePathFile, $targetDirLoader, $filesCode, $vendorPathCode, $appBaseDirCode, $suffix, $useGlobalIncludePath, $prependAutoloader)); // use stream_copy_to_stream instead of copy // to work around https://bugs.php.net/bug.php?id=64634 $sourceLoader = fopen(__DIR__ . '/ClassLoader.php', 'r'); $targetLoader = fopen($targetDir . '/ClassLoader52.php', 'w+'); stream_copy_to_stream($sourceLoader, $targetLoader); fclose($sourceLoader); fclose($targetLoader); unset($sourceLoader, $targetLoader); }