public function dump(Config $config, InstalledRepositoryInterface $localRepo, PackageInterface $mainPackage, InstallationManager $installationManager, $targetDir, $scanPsr0Packages = false, $suffix = '') { $filesystem = new Filesystem(); $filesystem->ensureDirectoryExists($config->get('vendor-dir')); $basePath = $filesystem->normalizePath(getcwd()); $vendorPath = $filesystem->normalizePath(realpath($config->get('vendor-dir'))); $useGlobalIncludePath = (bool) $config->get('use-include-path'); $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; $packageMap = $this->buildPackageMap($installationManager, $mainPackage, $localRepo->getCanonicalPackages()); $autoloads = $this->parseAutoloads($packageMap, $mainPackage); 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} => "; if (count($exportedPaths) > 1) { $namespacesFile .= "array(" . implode(', ', $exportedPaths) . "),\n"; } else { $namespacesFile .= $exportedPaths[0] . ",\n"; } } $namespacesFile .= ");\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) { foreach ($autoloads['psr-0'] 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), strpos($namespace, '_') === false ? preg_quote(strtr($namespace, '\\', '/')) : ''); foreach (ClassMapGenerator::createMap($dir, $whitelist) as $class => $path) { if ('' === $namespace || 0 === strpos($class, $namespace)) { if (!isset($classMap[$class])) { $path = $this->getPathCode($filesystem, $basePath, $vendorPath, $path); $classMap[$class] = $path . ",\n"; } } } } } } $autoloads['classmap'] = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($autoloads['classmap'])); foreach ($autoloads['classmap'] as $dir) { foreach (ClassMapGenerator::createMap($dir) 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"; $filesCode = ""; $autoloads['files'] = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($autoloads['files'])); foreach ($autoloads['files'] as $functionFile) { $filesCode .= ' require ' . $this->getPathCode($filesystem, $basePath, $vendorPath, $functionFile) . ";\n"; } if (!$suffix) { $suffix = md5(uniqid('', true)); } file_put_contents($targetDir . '/autoload_namespaces.php', $namespacesFile); 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); } file_put_contents($vendorPath . '/autoload.php', $this->getAutoloadFile($vendorPathToTargetDirCode, $suffix)); file_put_contents($targetDir . '/autoload_real.php', $this->getAutoloadRealFile(true, true, (bool) $includePathFile, $targetDirLoader, $filesCode, $vendorPathCode, $appBaseDirCode, $suffix, $useGlobalIncludePath)); // 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->dispatch(ScriptEvents::POST_AUTOLOAD_DUMP); }