187 lines
6.0 KiB
PHP
187 lines
6.0 KiB
PHP
<?php
|
|
|
|
/*
|
|
* This file is part of Composer.
|
|
*
|
|
* (c) Nils Adermann <naderman@naderman.de>
|
|
* Jordi Boggiano <j.boggiano@seld.be>
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE
|
|
* file that was distributed with this source code.
|
|
*/
|
|
|
|
namespace Composer\Autoload;
|
|
|
|
use Composer\Installer\InstallationManager;
|
|
use Composer\Json\JsonFile;
|
|
use Composer\Package\Loader\JsonLoader;
|
|
use Composer\Package\PackageInterface;
|
|
use Composer\Repository\RepositoryInterface;
|
|
use Composer\Util\Filesystem;
|
|
|
|
/**
|
|
* @author Igor Wiedler <igor@wiedler.ch>
|
|
* @author Jordi Boggiano <j.boggiano@seld.be>
|
|
*/
|
|
class AutoloadGenerator
|
|
{
|
|
public function dump(RepositoryInterface $localRepo, PackageInterface $mainPackage, InstallationManager $installationManager, $targetDir)
|
|
{
|
|
$autoloadFile = <<<'EOF'
|
|
<?php
|
|
|
|
// autoload.php generated by Composer
|
|
if (!class_exists('Composer\\Autoload\\ClassLoader', false)) {
|
|
require __DIR__.'/ClassLoader.php';
|
|
}
|
|
|
|
$__composer_autoload_init = function() {
|
|
$loader = new \Composer\Autoload\ClassLoader();
|
|
|
|
$map = require __DIR__.'/autoload_namespaces.php';
|
|
|
|
foreach ($map as $namespace => $path) {
|
|
$loader->add($namespace, $path);
|
|
}
|
|
|
|
$loader->register();
|
|
|
|
return $loader;
|
|
};
|
|
|
|
return $__composer_autoload_init();
|
|
EOF;
|
|
|
|
$filesystem = new Filesystem();
|
|
$vendorPath = strtr(realpath($installationManager->getVendorPath()), '\\', '/');
|
|
$relVendorPath = $filesystem->findShortestPath(getcwd(), $vendorPath);
|
|
$vendorDirCode = $filesystem->findShortestPathCode(realpath($targetDir), $vendorPath, true);
|
|
|
|
$namespacesFile = <<<EOF
|
|
<?php
|
|
|
|
// autoload_namespace.php generated by Composer
|
|
|
|
\$vendorDir = $vendorDirCode;
|
|
|
|
return array(
|
|
|
|
EOF;
|
|
|
|
$packageMap = $this->buildPackageMap($installationManager, $mainPackage, $localRepo->getPackages());
|
|
$autoloads = $this->parseAutoloads($packageMap);
|
|
|
|
$appBaseDir = $filesystem->findShortestPathCode($vendorPath, getcwd(), true);
|
|
$appBaseDir = str_replace('__DIR__', '$vendorDir', $appBaseDir);
|
|
|
|
if (isset($autoloads['psr-0'])) {
|
|
foreach ($autoloads['psr-0'] as $namespace => $paths) {
|
|
$exportedPaths = array();
|
|
foreach ($paths as $path) {
|
|
$path = strtr($path, '\\', '/');
|
|
$baseDir = '';
|
|
if (!$filesystem->isAbsolutePath($path)) {
|
|
// vendor dir == working dir
|
|
if (preg_match('{^(\./?)?$}', $relVendorPath)) {
|
|
$path = '/'.$path;
|
|
$baseDir = '$vendorDir . ';
|
|
} elseif (strpos($path, $relVendorPath) === 0) {
|
|
// path starts with vendor dir
|
|
$path = substr($path, strlen($relVendorPath));
|
|
$baseDir = '$vendorDir . ';
|
|
} else {
|
|
$path = '/'.$path;
|
|
$baseDir = $appBaseDir . ' . ';
|
|
}
|
|
} elseif (strpos($path, $vendorPath) === 0) {
|
|
$path = substr($path, strlen($vendorPath));
|
|
$baseDir = '$vendorDir . ';
|
|
}
|
|
$exportedPaths[] = $baseDir.var_export($path, true);
|
|
}
|
|
$exportedPrefix = var_export($namespace, true);
|
|
$namespacesFile .= " $exportedPrefix => ";
|
|
if (count($exportedPaths) > 1) {
|
|
$namespacesFile .= "array(".implode(', ',$exportedPaths)."),\n";
|
|
} else {
|
|
$namespacesFile .= $exportedPaths[0].",\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
$namespacesFile .= ");\n";
|
|
|
|
file_put_contents($targetDir.'/autoload.php', $autoloadFile);
|
|
file_put_contents($targetDir.'/autoload_namespaces.php', $namespacesFile);
|
|
copy(__DIR__.'/ClassLoader.php', $targetDir.'/ClassLoader.php');
|
|
}
|
|
|
|
public function buildPackageMap(InstallationManager $installationManager, PackageInterface $mainPackage, array $packages)
|
|
{
|
|
// build package => install path map
|
|
$packageMap = array();
|
|
|
|
// add main package
|
|
$packageMap[] = array($mainPackage, '');
|
|
|
|
foreach ($packages as $package) {
|
|
$packageMap[] = array(
|
|
$package,
|
|
$installationManager->getInstallPath($package)
|
|
);
|
|
}
|
|
|
|
return $packageMap;
|
|
}
|
|
|
|
/**
|
|
* Compiles an ordered list of namespace => path mappings
|
|
*
|
|
* @param array $packageMap array of array(package, installDir-relative-to-composer.json)
|
|
* @return array array('psr-0' => array('Ns\\Foo' => array('installDir')))
|
|
*/
|
|
public function parseAutoloads(array $packageMap)
|
|
{
|
|
$autoloads = array();
|
|
foreach ($packageMap as $item) {
|
|
list($package, $installPath) = $item;
|
|
|
|
if (null !== $package->getTargetDir()) {
|
|
$installPath = substr($installPath, 0, -strlen('/'.$package->getTargetDir()));
|
|
}
|
|
|
|
foreach ($package->getAutoload() as $type => $mapping) {
|
|
foreach ($mapping as $namespace => $path) {
|
|
$autoloads[$type][$namespace][] = empty($installPath) ? $path : $installPath.'/'.$path;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
foreach ($autoloads as $type => $maps) {
|
|
krsort($autoloads[$type]);
|
|
}
|
|
|
|
return $autoloads;
|
|
}
|
|
|
|
/**
|
|
* Registers an autoloader based on an autoload map returned by parseAutoloads
|
|
*
|
|
* @param array $autoloads see parseAutoloads return value
|
|
* @return ClassLoader
|
|
*/
|
|
public function createLoader(array $autoloads)
|
|
{
|
|
$loader = new ClassLoader();
|
|
|
|
if (isset($autoloads['psr-0'])) {
|
|
foreach ($autoloads['psr-0'] as $namespace => $path) {
|
|
$loader->add($namespace, $path);
|
|
}
|
|
}
|
|
|
|
return $loader;
|
|
}
|
|
}
|