joomla/joomla-cms — pull request #5189 by nikosdion (2014-11-24 15:31:19+00:00)
Title: Apply on-the-fly class aliases, even for Composer packages

Fixes gh-5179

# Technical description

The libraries/classmap.php file registers class aliases with JLoader. This works fine when a developer creates an object using the old class name (e.g. JRegistry) instead of the new class (e.g. Joomla\Registry\Registry). However, this causes an issue when PHP doesn't try to autoload a class, e.g. when the old class name is in the right hand side of instanceof. Example:

```$foo = new \Joomla\Registry\Registry();
var_dump($foo instanceof \Joomla\Registry\Registry); // returns true
var_dump($foo instanceof JRegistry); // returns false```

However, if you have forced the autoloader to run you have no problem. Example:

```$foo = new \Joomla\Registry\Registry();
class_exists('JRegistry', true); // Dummy line just to force the autoloader to run
var_dump($foo instanceof \Joomla\Registry\Registry); // returns true
var_dump($foo instanceof JRegistry); // returns true now!!!```

We can't use static `class_alias()` calls because PHP needs to load the original class, causing memory and performance issues. Instead, we need a way to create the aliases on-the-fly, when either then old class is loaded (via the dynamic alias set in JLoader) or through the new namespaced class name (through Composer).

This patch uses a fork of the `\Composer\Autoload\ClassLoader` class which calls `JLoader::applyAliasFor($class)` when loading a class. This allows us to register class aliases on the fly, when the new, namespaced class is being loaded. Moreover, the same trick is applied to all of the JLoader autoloaders. This results in perfect backwards compatibility while we are proceeding with the namespacing of the core code.

# Backwards compatibility

This patch actually *fixes* backwards compatibility :)

# Performance impact

I could not measure performance impact, not because of lack or try or incompetence but because of variance. Therefore I conclude that the performance impact is statistically not important. In layman's terms: it's so small you can't even separate it from the variance in page load times added by external factors such as filesystem caches, code caches, web server thread management etc.

As for the memory impact, it is about 0.2Kb per aliased class. Even with hundreds of classes the memory impact is miniscule compared to the core code memory footprint.