Skip to content
Snippets Groups Projects
Commit 9a786007 authored by Helmut Hummel's avatar Helmut Hummel Committed by Anja Leichsenring
Browse files

[FEATURE] Add possibility for extensions to register class maps

With the old class loader it was possible for extension authors
to register several classes in an ext_autoload.php file.

This possibility was completely removed with introduction of composer class loading.
In composer mode, one can fully benefit from composer and its class loading options.
However TYPO3 installations in non composer mode (extracted and symlinked
archive of sources), lack this functionality completely.

It could however be useful to have that for some edge cases or legacy code,
without completely relying on a full scan for classes in the complete extension
directory (when no new class loading info is found at all), which can be an issue
of its own.

With this change it is also possible to define a "classmap" section
in the composer.json or ext_emcomf.php file.

Resolves: #70078
Releases: master
Change-Id: I86f65fbb479eb46160ecef3a547a91e453ee5764
Reviewed-on: http://review.typo3.org/43523


Reviewed-by: default avatarNicole Cordes <typo3@cordes.co>
Reviewed-by: default avatarHelmut Hummel <helmut.hummel@typo3.org>
Tested-by: default avatarHelmut Hummel <helmut.hummel@typo3.org>
Tested-by: default avatarNicole Cordes <typo3@cordes.co>
Reviewed-by: default avatarAnja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: default avatarAnja Leichsenring <aleichsenring@ab-softlab.de>
parent 4c6ddcb3
No related branches found
No related tags found
No related merge requests found
......@@ -44,26 +44,34 @@ class ClassLoadingInformationGenerator {
$psr4 = array();
$packagePath = $package->getPackagePath();
$manifest = $this->getPackageManager()->getComposerManifest($package->getPackagePath());
if (!empty($manifest->autoload->{'psr-4'})) {
$psr4manifest = json_decode(json_encode($manifest->autoload->{'psr-4'}), TRUE);
if (is_array($psr4manifest)) {
foreach ($psr4manifest as $namespacePrefix => $path) {
$manifest = $this->getPackageManager()->getComposerManifest($packagePath);
if (empty($manifest->autoload)) {
// Legacy mode: Scan the complete extension directory for class files
$classMap = $this->createClassMap($packagePath, $useRelativePaths, TRUE);
} else {
$autoloadDefinition = json_decode(json_encode($manifest->autoload), TRUE);
if (!empty($autoloadDefinition['psr-4']) && is_array($autoloadDefinition['psr-4'])) {
$classLoaderPrefixesPsr4 = $this->getClassLoader()->getPrefixesPsr4();
foreach ($autoloadDefinition['psr-4'] as $namespacePrefix => $path) {
$namespacePath = $packagePath . $path;
if ($useRelativePaths) {
$psr4[$namespacePrefix] = $this->makePathRelative($namespacePath, realpath($namespacePath));
} else {
$psr4[$namespacePrefix] = $namespacePath;
}
if (!empty($this->getClassLoader()->getPrefixesPsr4()[$namespacePrefix])) {
if (!empty($classLoaderPrefixesPsr4[$namespacePrefix])) {
// The namespace prefix has been registered already, which means there also might be
// a class map which we need to override
$classMap = array_merge($classMap, $this->createClassMap($namespacePath, $useRelativePaths, FALSE, $namespacePrefix));
}
}
}
} else {
$classMap = $this->createClassMap($packagePath, $useRelativePaths, TRUE);
if (!empty($autoloadDefinition['classmap']) && is_array($autoloadDefinition['classmap'])) {
foreach ($autoloadDefinition['classmap'] as $path) {
$classMap = array_merge($classMap, $this->createClassMap($packagePath . $path, $useRelativePaths));
}
}
}
return array('classMap' => $classMap, 'psr-4' => $psr4);
......
=======================================================================
Feature: #68700 - Autoload definition can be provided in ext_emconf.php
=======================================================================
Description
===========
It is now possible for extensions to provide one or more PSR-4 definitions,
in the ext_emconf.php file.
While it was possible to define a psr-4 section in a composer.json before already, now it is also
possible to define an autoload/psr-4 section in the ext_emconf.php file as well, so that extension authors
do not need to provide a composer.json just for that any more.
This is the new recommended way to register classes for TYPO3.
Example ext_emconf.php:
.. code-block:: php
<?php
$EM_CONF[$_EXTKEY] = array (
'title' => 'Extension skeleton for TYPO3 7',
'description' => 'Description for ext',
'category' => 'Example Extensions',
'author' => 'Helmut Hummel',
'author_email' => 'info@helhum.io',
'author_company' => 'helhum.io',
'shy' => '',
'priority' => '',
'module' => '',
'state' => 'stable',
'internal' => '',
'uploadfolder' => '0',
'createDirs' => '',
'modify_tables' => '',
'clearCacheOnLoad' => 0,
'lockType' => '',
'version' => '0.0.1',
'constraints' =>
array (
'depends' =>
array (
'typo3' => '7.5.0-7.99.99',
),
'conflicts' =>
array (
),
'suggests' =>
array (
),
),
'autoload' =>
array(
'psr-4' =>
array(
'Helhum\\ExtScaffold\\' => 'Classes'
)
)
);
Impact
======
Without providing an autoload section, TYPO3 scans the complete extension directory for PHP class files and registers them all.
This includes test classes or classes of third party libraries, which might lead to unexpected results.
Therefore it is recommended to provide such an autoload section in an extension. It will be ignored in older TYPO3 versions, so
there will be no issue with backwards compatibility.
\ No newline at end of file
======================================================================
Feature: #70078 - Extensions can provide a class map for class loading
======================================================================
Description
===========
With the old class loader it was possible for extension authors
to register several classes in an ext_autoload.php file.
This possibility was completely removed with introduction of composer class loading.
In composer mode, one can fully benefit from composer and its class loading options.
However TYPO3 installations in non composer mode (extracted and symlinked
archive of sources), lack this functionality completely.
Now it is possible to provide a class map section in either the composer.json file
or the ext_emconf.php file. This section will be evaluated and used also in non composer mode.
Example ext_emconf.php file:
.. code-block:: php
<?php
$EM_CONF[$_EXTKEY] = array (
'title' => 'Extension skeleton for TYPO3 7',
'description' => 'Description for ext',
'category' => 'Example Extensions',
'author' => 'Helmut Hummel',
'author_email' => 'info@helhum.io',
'author_company' => 'helhum.io',
'shy' => '',
'priority' => '',
'module' => '',
'state' => 'stable',
'internal' => '',
'uploadfolder' => '0',
'createDirs' => '',
'modify_tables' => '',
'clearCacheOnLoad' => 0,
'lockType' => '',
'version' => '0.0.1',
'constraints' =>
array (
'depends' =>
array (
'typo3' => '7.5.0-7.99.99',
),
'conflicts' =>
array (
),
'suggests' =>
array (
),
),
'autoload' =>
array(
'psr-4' =>
array(
'Helhum\\ExtScaffold\\' => 'Classes'
),
'classmap' =>
array(
'Resources/PHP/Libs'
)
)
);
In the example configuration the path ``Resources/PHP/Libs`` is parsed for PHP files which are automatically added
to the class loader.
Impact
======
Extensions that target TYPO3 6.2 LTS and 7 LTS can now provide a class map in ext_emconf.php which is only evaluated in
TYPO3 7 LTS and an ext_autoload.php which is only evaluated in 6.2 LTS for maximum flexibility and compatibility.
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment