AutoloadGenerator to support PSR-4. Tests included.
parent
2c98813431
commit
bbf6278905
|
@ -69,9 +69,23 @@ return array(
|
||||||
|
|
||||||
EOF;
|
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());
|
$packageMap = $this->buildPackageMap($installationManager, $mainPackage, $localRepo->getCanonicalPackages());
|
||||||
$autoloads = $this->parseAutoloads($packageMap, $mainPackage);
|
$autoloads = $this->parseAutoloads($packageMap, $mainPackage);
|
||||||
|
|
||||||
|
// Process the 'psr-0' base directories.
|
||||||
foreach ($autoloads['psr-0'] as $namespace => $paths) {
|
foreach ($autoloads['psr-0'] as $namespace => $paths) {
|
||||||
$exportedPaths = array();
|
$exportedPaths = array();
|
||||||
foreach ($paths as $path) {
|
foreach ($paths as $path) {
|
||||||
|
@ -83,6 +97,21 @@ EOF;
|
||||||
}
|
}
|
||||||
$namespacesFile .= ");\n";
|
$namespacesFile .= ");\n";
|
||||||
|
|
||||||
|
// Process the 'psr-4' base directories.
|
||||||
|
foreach ($autoloads['psr-4'] as $namespace => $paths) {
|
||||||
|
if ('\\' !== $namespace[strlen($namespace) - 1]) {
|
||||||
|
throw new \Exception("PSR-4 namespaces must end with a namespace separator. '$namespace' does not.");
|
||||||
|
}
|
||||||
|
$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
|
$classmapFile = <<<EOF
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
@ -131,6 +160,8 @@ EOF;
|
||||||
// flatten array
|
// flatten array
|
||||||
$classMap = array();
|
$classMap = array();
|
||||||
if ($scanPsr0Packages) {
|
if ($scanPsr0Packages) {
|
||||||
|
// Scan the PSR-0 directories for class files, and add them to the
|
||||||
|
// class map.
|
||||||
foreach ($autoloads['psr-0'] as $namespace => $paths) {
|
foreach ($autoloads['psr-0'] as $namespace => $paths) {
|
||||||
foreach ($paths as $dir) {
|
foreach ($paths as $dir) {
|
||||||
$dir = $filesystem->normalizePath($filesystem->isAbsolutePath($dir) ? $dir : $basePath.'/'.$dir);
|
$dir = $filesystem->normalizePath($filesystem->isAbsolutePath($dir) ? $dir : $basePath.'/'.$dir);
|
||||||
|
@ -152,6 +183,29 @@ EOF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Scan the PSR-4 directories for class files, and add them to the
|
||||||
|
// class map.
|
||||||
|
foreach ($autoloads['psr-4'] 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']));
|
$autoloads['classmap'] = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($autoloads['classmap']));
|
||||||
|
@ -173,6 +227,7 @@ EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
file_put_contents($targetDir.'/autoload_namespaces.php', $namespacesFile);
|
file_put_contents($targetDir.'/autoload_namespaces.php', $namespacesFile);
|
||||||
|
file_put_contents($targetDir.'/autoload_psr4.php', $psr4File);
|
||||||
file_put_contents($targetDir.'/autoload_classmap.php', $classmapFile);
|
file_put_contents($targetDir.'/autoload_classmap.php', $classmapFile);
|
||||||
if ($includePathFile = $this->getIncludePathsFile($packageMap, $filesystem, $basePath, $vendorPath, $vendorPathCode52, $appBaseDirCode)) {
|
if ($includePathFile = $this->getIncludePathsFile($packageMap, $filesystem, $basePath, $vendorPath, $vendorPathCode52, $appBaseDirCode)) {
|
||||||
file_put_contents($targetDir.'/include_paths.php', $includePathFile);
|
file_put_contents($targetDir.'/include_paths.php', $includePathFile);
|
||||||
|
@ -181,7 +236,7 @@ EOF;
|
||||||
file_put_contents($targetDir.'/autoload_files.php', $includeFilesFile);
|
file_put_contents($targetDir.'/autoload_files.php', $includeFilesFile);
|
||||||
}
|
}
|
||||||
file_put_contents($vendorPath.'/autoload.php', $this->getAutoloadFile($vendorPathToTargetDirCode, $suffix));
|
file_put_contents($vendorPath.'/autoload.php', $this->getAutoloadFile($vendorPathToTargetDirCode, $suffix));
|
||||||
file_put_contents($targetDir.'/autoload_real.php', $this->getAutoloadRealFile(true, true, (bool) $includePathFile, $targetDirLoader, (bool) $includeFilesFile, $vendorPathCode, $appBaseDirCode, $suffix, $useGlobalIncludePath, $prependAutoloader));
|
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
|
// use stream_copy_to_stream instead of copy
|
||||||
// to work around https://bugs.php.net/bug.php?id=64634
|
// to work around https://bugs.php.net/bug.php?id=64634
|
||||||
|
@ -229,12 +284,14 @@ EOF;
|
||||||
array_unshift($packageMap, $mainPackageMap);
|
array_unshift($packageMap, $mainPackageMap);
|
||||||
|
|
||||||
$psr0 = $this->parseAutoloadsType($packageMap, 'psr-0', $mainPackage);
|
$psr0 = $this->parseAutoloadsType($packageMap, 'psr-0', $mainPackage);
|
||||||
|
$psr4 = $this->parseAutoloadsType($packageMap, 'psr-4', $mainPackage);
|
||||||
$classmap = $this->parseAutoloadsType($sortedPackageMap, 'classmap', $mainPackage);
|
$classmap = $this->parseAutoloadsType($sortedPackageMap, 'classmap', $mainPackage);
|
||||||
$files = $this->parseAutoloadsType($sortedPackageMap, 'files', $mainPackage);
|
$files = $this->parseAutoloadsType($sortedPackageMap, 'files', $mainPackage);
|
||||||
|
|
||||||
krsort($psr0);
|
krsort($psr0);
|
||||||
|
krsort($psr4);
|
||||||
|
|
||||||
return array('psr-0' => $psr0, 'classmap' => $classmap, 'files' => $files);
|
return array('psr-0' => $psr0, 'psr-4' => $psr4, 'classmap' => $classmap, 'files' => $files);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -366,7 +423,7 @@ return ComposerAutoloaderInit$suffix::getLoader();
|
||||||
AUTOLOAD;
|
AUTOLOAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getAutoloadRealFile($usePSR0, $useClassMap, $useIncludePath, $targetDirLoader, $useIncludeFiles, $vendorPathCode, $appBaseDirCode, $suffix, $useGlobalIncludePath, $prependAutoloader)
|
protected function getAutoloadRealFile($useClassMap, $useIncludePath, $targetDirLoader, $useIncludeFiles, $vendorPathCode, $appBaseDirCode, $suffix, $useGlobalIncludePath, $prependAutoloader)
|
||||||
{
|
{
|
||||||
// TODO the class ComposerAutoloaderInit should be revert to a closure
|
// TODO the class ComposerAutoloaderInit should be revert to a closure
|
||||||
// when APC has been fixed:
|
// when APC has been fixed:
|
||||||
|
@ -417,8 +474,7 @@ HEADER;
|
||||||
INCLUDE_PATH;
|
INCLUDE_PATH;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($usePSR0) {
|
$file .= <<<'PSR0'
|
||||||
$file .= <<<'PSR0'
|
|
||||||
$map = require __DIR__ . '/autoload_namespaces.php';
|
$map = require __DIR__ . '/autoload_namespaces.php';
|
||||||
foreach ($map as $namespace => $path) {
|
foreach ($map as $namespace => $path) {
|
||||||
$loader->set($namespace, $path);
|
$loader->set($namespace, $path);
|
||||||
|
@ -426,8 +482,16 @@ INCLUDE_PATH;
|
||||||
|
|
||||||
|
|
||||||
PSR0;
|
PSR0;
|
||||||
|
|
||||||
|
$file .= <<<'PSR4'
|
||||||
|
$map = require __DIR__ . '/autoload_psr4.php';
|
||||||
|
foreach ($map as $namespace => $path) {
|
||||||
|
$loader->setPsr4($namespace, $path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PSR4;
|
||||||
|
|
||||||
if ($useClassMap) {
|
if ($useClassMap) {
|
||||||
$file .= <<<'CLASSMAP'
|
$file .= <<<'CLASSMAP'
|
||||||
$classMap = require __DIR__ . '/autoload_classmap.php';
|
$classMap = require __DIR__ . '/autoload_classmap.php';
|
||||||
|
|
|
@ -95,7 +95,14 @@ class AutoloadGeneratorTest extends TestCase
|
||||||
{
|
{
|
||||||
$package = new Package('a', '1.0', '1.0');
|
$package = new Package('a', '1.0', '1.0');
|
||||||
$package->setAutoload(array(
|
$package->setAutoload(array(
|
||||||
'psr-0' => array('Main' => 'src/', 'Lala' => array('src/', 'lib/')),
|
'psr-0' => array(
|
||||||
|
'Main' => 'src/',
|
||||||
|
'Lala' => array('src/', 'lib/'),
|
||||||
|
),
|
||||||
|
'psr-4' => array(
|
||||||
|
'Acme\Fruit\\' => 'src-fruit/',
|
||||||
|
'Acme\Cake\\' => array('src-cake/', 'lib-cake/'),
|
||||||
|
),
|
||||||
'classmap' => array('composersrc/'),
|
'classmap' => array('composersrc/'),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -107,11 +114,22 @@ class AutoloadGeneratorTest extends TestCase
|
||||||
$this->fs->ensureDirectoryExists($this->workingDir.'/src');
|
$this->fs->ensureDirectoryExists($this->workingDir.'/src');
|
||||||
$this->fs->ensureDirectoryExists($this->workingDir.'/lib');
|
$this->fs->ensureDirectoryExists($this->workingDir.'/lib');
|
||||||
|
|
||||||
|
$this->fs->ensureDirectoryExists($this->workingDir.'/src-fruit');
|
||||||
|
$this->fs->ensureDirectoryExists($this->workingDir.'/src-cake');
|
||||||
|
$this->fs->ensureDirectoryExists($this->workingDir.'/lib-cake');
|
||||||
|
|
||||||
$this->fs->ensureDirectoryExists($this->workingDir.'/composersrc');
|
$this->fs->ensureDirectoryExists($this->workingDir.'/composersrc');
|
||||||
file_put_contents($this->workingDir.'/composersrc/foo.php', '<?php class ClassMapFoo {}');
|
file_put_contents($this->workingDir.'/composersrc/foo.php', '<?php class ClassMapFoo {}');
|
||||||
|
|
||||||
$this->generator->dump($this->config, $this->repository, $package, $this->im, 'composer', false, '_1');
|
$this->generator->dump($this->config, $this->repository, $package, $this->im, 'composer', false, '_1');
|
||||||
|
|
||||||
|
// Assert that autoload_namespaces.php was correctly generated.
|
||||||
$this->assertAutoloadFiles('main', $this->vendorDir.'/composer');
|
$this->assertAutoloadFiles('main', $this->vendorDir.'/composer');
|
||||||
|
|
||||||
|
// Assert that autoload_psr4.php was correctly generated.
|
||||||
|
$this->assertAutoloadFiles('psr4', $this->vendorDir.'/composer', 'psr4');
|
||||||
|
|
||||||
|
// Assert that autoload_classmap.php was correctly generated.
|
||||||
$this->assertAutoloadFiles('classmap', $this->vendorDir.'/composer', 'classmap');
|
$this->assertAutoloadFiles('classmap', $this->vendorDir.'/composer', 'classmap');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,6 +140,10 @@ class AutoloadGeneratorTest extends TestCase
|
||||||
$package = new Package('a', '1.0', '1.0');
|
$package = new Package('a', '1.0', '1.0');
|
||||||
$package->setAutoload(array(
|
$package->setAutoload(array(
|
||||||
'psr-0' => array('Main' => 'src/', 'Lala' => 'src/'),
|
'psr-0' => array('Main' => 'src/', 'Lala' => 'src/'),
|
||||||
|
'psr-4' => array(
|
||||||
|
'Acme\Fruit\\' => 'src-fruit/',
|
||||||
|
'Acme\Cake\\' => array('src-cake/', 'lib-cake/'),
|
||||||
|
),
|
||||||
'classmap' => array('composersrc/'),
|
'classmap' => array('composersrc/'),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -138,6 +160,7 @@ class AutoloadGeneratorTest extends TestCase
|
||||||
|
|
||||||
$this->generator->dump($this->config, $this->repository, $package, $this->im, 'composer', true, '_2');
|
$this->generator->dump($this->config, $this->repository, $package, $this->im, 'composer', true, '_2');
|
||||||
$this->assertAutoloadFiles('main3', $this->vendorDir.'/composer');
|
$this->assertAutoloadFiles('main3', $this->vendorDir.'/composer');
|
||||||
|
$this->assertAutoloadFiles('psr4_3', $this->vendorDir.'/composer', 'psr4');
|
||||||
$this->assertAutoloadFiles('classmap3', $this->vendorDir.'/composer', 'classmap');
|
$this->assertAutoloadFiles('classmap3', $this->vendorDir.'/composer', 'classmap');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,6 +169,10 @@ class AutoloadGeneratorTest extends TestCase
|
||||||
$package = new Package('a', '1.0', '1.0');
|
$package = new Package('a', '1.0', '1.0');
|
||||||
$package->setAutoload(array(
|
$package->setAutoload(array(
|
||||||
'psr-0' => array('Main' => 'src/', 'Lala' => 'src/'),
|
'psr-0' => array('Main' => 'src/', 'Lala' => 'src/'),
|
||||||
|
'psr-4' => array(
|
||||||
|
'Acme\Fruit\\' => 'src-fruit/',
|
||||||
|
'Acme\Cake\\' => array('src-cake/', 'lib-cake/'),
|
||||||
|
),
|
||||||
'classmap' => array('composersrc/'),
|
'classmap' => array('composersrc/'),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -162,6 +189,7 @@ class AutoloadGeneratorTest extends TestCase
|
||||||
file_put_contents($this->workingDir.'/composersrc/foo.php', '<?php class ClassMapFoo {}');
|
file_put_contents($this->workingDir.'/composersrc/foo.php', '<?php class ClassMapFoo {}');
|
||||||
$this->generator->dump($this->config, $this->repository, $package, $this->im, 'composer', false, '_3');
|
$this->generator->dump($this->config, $this->repository, $package, $this->im, 'composer', false, '_3');
|
||||||
$this->assertAutoloadFiles('main2', $this->vendorDir.'/composer');
|
$this->assertAutoloadFiles('main2', $this->vendorDir.'/composer');
|
||||||
|
$this->assertAutoloadFiles('psr4_2', $this->vendorDir.'/composer', 'psr4');
|
||||||
$this->assertAutoloadFiles('classmap2', $this->vendorDir.'/composer', 'classmap');
|
$this->assertAutoloadFiles('classmap2', $this->vendorDir.'/composer', 'classmap');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,6 +198,10 @@ class AutoloadGeneratorTest extends TestCase
|
||||||
$package = new Package('a', '1.0', '1.0');
|
$package = new Package('a', '1.0', '1.0');
|
||||||
$package->setAutoload(array(
|
$package->setAutoload(array(
|
||||||
'psr-0' => array('Main\\Foo' => '', 'Main\\Bar' => ''),
|
'psr-0' => array('Main\\Foo' => '', 'Main\\Bar' => ''),
|
||||||
|
'psr-4' => array(
|
||||||
|
'Acme\Fruit\\' => 'src-fruit/',
|
||||||
|
'Acme\Cake\\' => array('src-cake/', 'lib-cake/'),
|
||||||
|
),
|
||||||
'classmap' => array('Main/Foo/src', 'lib'),
|
'classmap' => array('Main/Foo/src', 'lib'),
|
||||||
'files' => array('foo.php', 'Main/Foo/bar.php'),
|
'files' => array('foo.php', 'Main/Foo/bar.php'),
|
||||||
));
|
));
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// autoload_psr4.php @generated by Composer
|
||||||
|
|
||||||
|
$vendorDir = dirname(dirname(__FILE__));
|
||||||
|
$baseDir = dirname($vendorDir);
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'Acme\\Fruit\\' => array($baseDir . '/src-fruit'),
|
||||||
|
'Acme\\Cake\\' => array($baseDir . '/src-cake', $baseDir . '/lib-cake'),
|
||||||
|
);
|
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// autoload_psr4.php @generated by Composer
|
||||||
|
|
||||||
|
$vendorDir = dirname(dirname(__FILE__));
|
||||||
|
$baseDir = dirname(dirname($vendorDir));
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'Acme\\Fruit\\' => array($baseDir . '/src-fruit'),
|
||||||
|
'Acme\\Cake\\' => array($baseDir . '/src-cake', $baseDir . '/lib-cake'),
|
||||||
|
);
|
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// autoload_psr4.php @generated by Composer
|
||||||
|
|
||||||
|
$vendorDir = dirname(dirname(__FILE__));
|
||||||
|
$baseDir = $vendorDir;
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'Acme\\Fruit\\' => array($vendorDir . '/src-fruit'),
|
||||||
|
'Acme\\Cake\\' => array($vendorDir . '/src-cake', $vendorDir . '/lib-cake'),
|
||||||
|
);
|
|
@ -31,6 +31,11 @@ class ComposerAutoloaderInitFilesAutoloadOrder
|
||||||
$loader->set($namespace, $path);
|
$loader->set($namespace, $path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$map = require __DIR__ . '/autoload_psr4.php';
|
||||||
|
foreach ($map as $namespace => $path) {
|
||||||
|
$loader->setPsr4($namespace, $path);
|
||||||
|
}
|
||||||
|
|
||||||
$classMap = require __DIR__ . '/autoload_classmap.php';
|
$classMap = require __DIR__ . '/autoload_classmap.php';
|
||||||
if ($classMap) {
|
if ($classMap) {
|
||||||
$loader->addClassMap($classMap);
|
$loader->addClassMap($classMap);
|
||||||
|
|
|
@ -31,6 +31,11 @@ class ComposerAutoloaderInitFilesAutoload
|
||||||
$loader->set($namespace, $path);
|
$loader->set($namespace, $path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$map = require __DIR__ . '/autoload_psr4.php';
|
||||||
|
foreach ($map as $namespace => $path) {
|
||||||
|
$loader->setPsr4($namespace, $path);
|
||||||
|
}
|
||||||
|
|
||||||
$classMap = require __DIR__ . '/autoload_classmap.php';
|
$classMap = require __DIR__ . '/autoload_classmap.php';
|
||||||
if ($classMap) {
|
if ($classMap) {
|
||||||
$loader->addClassMap($classMap);
|
$loader->addClassMap($classMap);
|
||||||
|
|
|
@ -31,6 +31,11 @@ class ComposerAutoloaderInitIncludePath
|
||||||
$loader->set($namespace, $path);
|
$loader->set($namespace, $path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$map = require __DIR__ . '/autoload_psr4.php';
|
||||||
|
foreach ($map as $namespace => $path) {
|
||||||
|
$loader->setPsr4($namespace, $path);
|
||||||
|
}
|
||||||
|
|
||||||
$classMap = require __DIR__ . '/autoload_classmap.php';
|
$classMap = require __DIR__ . '/autoload_classmap.php';
|
||||||
if ($classMap) {
|
if ($classMap) {
|
||||||
$loader->addClassMap($classMap);
|
$loader->addClassMap($classMap);
|
||||||
|
|
|
@ -31,6 +31,11 @@ class ComposerAutoloaderInitTargetDir
|
||||||
$loader->set($namespace, $path);
|
$loader->set($namespace, $path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$map = require __DIR__ . '/autoload_psr4.php';
|
||||||
|
foreach ($map as $namespace => $path) {
|
||||||
|
$loader->setPsr4($namespace, $path);
|
||||||
|
}
|
||||||
|
|
||||||
$classMap = require __DIR__ . '/autoload_classmap.php';
|
$classMap = require __DIR__ . '/autoload_classmap.php';
|
||||||
if ($classMap) {
|
if ($classMap) {
|
||||||
$loader->addClassMap($classMap);
|
$loader->addClassMap($classMap);
|
||||||
|
|
Loading…
Reference in New Issue