? ? Success

User tests: Successful: Unsuccessful:

avatar nikosdion
nikosdion
24 Nov 2014

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.

avatar nikosdion nikosdion - open - 24 Nov 2014
avatar jissues-bot jissues-bot - change - 24 Nov 2014
Labels Added: ?
avatar zero-24
zero-24 - comment - 24 Nov 2014

@nikosdion
can you have a look into Travis?
https://travis-ci.org/joomla/joomla-cms/jobs/41976583

FILE: /home/travis/build/joomla/joomla-cms/libraries/composer_autoload.php
--------------------------------------------------------------------------------
FOUND 5 ERROR(S) AFFECTING 5 LINE(S)
--------------------------------------------------------------------------------
 11 | ERROR | Missing class doc comment
 15 | ERROR | Missing function doc comment
 23 | ERROR | Missing function doc comment
 31 | ERROR | Instanciating new classes without parameters does not require
    |       | brackets.
 68 | ERROR | Missing function doc comment
--------------------------------------------------------------------------------
FILE: /home/travis/build/joomla/joomla-cms/libraries/ClassLoader.php
--------------------------------------------------------------------------------
FOUND 73 ERROR(S) AFFECTING 55 LINE(S)
--------------------------------------------------------------------------------
  38 | ERROR | @author tag comment indented incorrectly; expected 2 spaces but
     |       | found 1
  39 | ERROR | @author tag comment indented incorrectly; expected 2 spaces but
     |       | found 1
  40 | ERROR | Missing @since tag in class comment
  45 | ERROR | Expected 1 blank line before member var; 0 found
  46 | ERROR | Expected 1 blank line before member var; 0 found
  50 | ERROR | Expected 1 blank line before member var; 0 found
  53 | ERROR | Expected 1 blank line before member var; 0 found
  55 | ERROR | You must use "/**" style comments for a function comment
  60 | ERROR | Missing function doc comment
  65 | ERROR | Missing function doc comment
  70 | ERROR | Missing function doc comment
  75 | ERROR | Missing function doc comment
  81 | ERROR | Expected 3 spaces before variable type
  81 | ERROR | Expected 2 spaces after the longest type
  81 | ERROR | Expected 2 spaces after the longest variable name
  81 | ERROR | There must be exactly one blank line before the tags in function
     |       | comment
  82 | ERROR | Missing @return tag in function comment
  99 | ERROR | Expected 3 spaces before variable type
 100 | ERROR | Expected 3 spaces before variable type
 100 | ERROR | Expected 2 spaces after the longest type
 101 | ERROR | Expected 3 spaces before variable type
 101 | ERROR | Expected 2 spaces after the longest variable name
 102 | ERROR | Missing @return tag in function comment
 110 | ERROR | Cast statements must be followed by a single space; expected
     |       | "(array) $paths" but found "(array)$paths"
 118 | ERROR | Cast statements must be followed by a single space; expected
     |       | "(array) $paths" but found "(array)$paths"
 129 | ERROR | Cast statements must be followed by a single space; expected
     |       | "(array) $paths" but found "(array)$paths"
 137 | ERROR | Cast statements must be followed by a single space; expected
     |       | "(array) $paths" but found "(array)$paths"
 145 | ERROR | Cast statements must be followed by a single space; expected
     |       | "(array) $paths" but found "(array)$paths"
 154 | ERROR | Expected 3 spaces before variable type
 155 | ERROR | Expected 3 spaces before variable type
 155 | ERROR | Expected 2 spaces after the longest type
 156 | ERROR | Expected 3 spaces before variable type
 156 | ERROR | Expected 2 spaces after the longest variable name
 159 | ERROR | Missing @return tag in function comment
 168 | ERROR | Cast statements must be followed by a single space; expected
     |       | "(array) $paths" but found "(array)$paths"
 176 | ERROR | Cast statements must be followed by a single space; expected
     |       | "(array) $paths" but found "(array)$paths"
 189 | ERROR | Cast statements must be followed by a single space; expected
     |       | "(array) $paths" but found "(array)$paths"
 195 | ERROR | Cast statements must be followed by a single space; expected
     |       | "(array) $paths" but found "(array)$paths"
 204 | ERROR | Cast statements must be followed by a single space; expected
     |       | "(array) $paths" but found "(array)$paths"
 213 | ERROR | Expected 3 spaces before variable type
 213 | ERROR | Expected 2 spaces after the longest variable name
 214 | ERROR | Expected 3 spaces before variable type
 214 | ERROR | Expected 2 spaces after the longest type
 215 | ERROR | Missing @return tag in function comment
 220 | ERROR | Cast statements must be followed by a single space; expected
     |       | "(array) $paths" but found "(array)$paths"
 224 | ERROR | Cast statements must be followed by a single space; expected
     |       | "(array) $paths" but found "(array)$paths"
 232 | ERROR | Expected 3 spaces before variable type
 232 | ERROR | Expected 2 spaces after the longest variable name
 233 | ERROR | Expected 3 spaces before variable type
 233 | ERROR | Expected 2 spaces after the longest type
 236 | ERROR | Missing @return tag in function comment
 241 | ERROR | Cast statements must be followed by a single space; expected
     |       | "(array) $paths" but found "(array)$paths"
 251 | ERROR | Cast statements must be followed by a single space; expected
     |       | "(array) $paths" but found "(array)$paths"
 258 | ERROR | Expected 3 spaces before variable type
 258 | ERROR | Missing comment for param "$useIncludePath" at position 1
 259 | ERROR | Missing @return tag in function comment
 279 | ERROR | Expected 3 spaces before variable type
 279 | ERROR | Expected 2 spaces after the longest type
 279 | ERROR | Expected 2 spaces after the longest variable name
 280 | ERROR | Missing @return tag in function comment
 288 | ERROR | Missing @return tag in function comment
 297 | ERROR | Expected 3 spaces before variable type
 297 | ERROR | Expected 2 spaces after the longest type
 297 | ERROR | Expected 2 spaces after the longest variable name
 316 | ERROR | Expected 3 spaces before variable type
 316 | ERROR | Expected 2 spaces after the longest type
 316 | ERROR | Expected 2 spaces after the longest variable name
 322 | ERROR | Please start your comment with a capital letter; found "// work
     |       | around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731"
 328 | ERROR | Please start your comment with a capital letter; found "// class
     |       | map lookup"
 351 | ERROR | You must use "/**" style comments for a function comment
 386 | ERROR | Please start your comment with a capital letter; found "//
     |       | namespaced class name"
 430 | ERROR | Doc comment for "$file" missing
 434 | ERROR | Missing @return tag in function comment
--------------------------------------------------------------------------------
FILE: /home/travis/build/joomla/joomla-cms/libraries/loader.php
--------------------------------------------------------------------------------
FOUND 1 ERROR(S) AFFECTING 1 LINE(S)
--------------------------------------------------------------------------------
 520 | ERROR | Missing comment for param "$class" at position 1
--------------------------------------------------------------------------------
avatar nikosdion
nikosdion - comment - 24 Nov 2014

ClassLoaderJoomla is a fork of Composer's ClassLoader. Also, the style errors in loader.php are in other methods, not what I touched. Sorry, I honestly don't have the time to go through all of the style issues in 3PD code within the timeframe to implement this fix for a major backwards compatibility issue :(

avatar zero-24
zero-24 - comment - 24 Nov 2014

sorry @nikosdion

avatar mbabker
mbabker - comment - 24 Nov 2014
avatar nikosdion
nikosdion - comment - 24 Nov 2014

I am not sure in which rule I should add the exceptions

avatar mbabker
mbabker - comment - 24 Nov 2014

At the top where we have the exclude-patterns, that tells the sniffer to always ignore files matching those paths.

avatar nikosdion
nikosdion - comment - 24 Nov 2014

@mbabker Thanks, I believe I added the files in the correct place

@chrisdavenport Thanks for the heads up! I have fixed the file headers to indicate the code's origin.

avatar brianteeman brianteeman - change - 24 Nov 2014
Category Libraries
avatar brianteeman
brianteeman - comment - 24 Nov 2014

@test before patch 3.40alpha and akeeba backup doesnt work
after patch it does

This comment was created with the J!Tracker Application at issues.joomla.org/joomla-cms/5189.

avatar brianteeman brianteeman - test_item - 24 Nov 2014 - Tested successfully
avatar smanzi
smanzi - comment - 25 Nov 2014

@test success (tested with both Akeeba Backup 4.0.5 and 4.1.0.rc2)

avatar smanzi smanzi - test_item - 25 Nov 2014 - Tested successfully
avatar zero-24 zero-24 - change - 25 Nov 2014
Status Pending Ready to Commit
avatar zero-24
zero-24 - comment - 25 Nov 2014

two successful tests + travis is happy now --> RTC

Thanks

This comment was created with the J!Tracker Application at issues.joomla.org/joomla-cms/5189.

avatar smanzi
smanzi - comment - 27 Nov 2014

@nikosdion I experienced a single "glitch" that I think is related to this PR. Unhappily I've been totally unable to duplicate it. In case you want to dig deeper, this is what happened:

  • I was willing to understand the nature of issue #5218
  • I logged into the back-end
  • I gave a quick look at com_patchtester just to check that no other patch was enabled beside this one, which I keep enabled for Akeeba Backup (the sole extension installed)
  • I clicked on Components -> Contacts
  • The "Contacts" page opened but I also received the following "Warning" message:
Warning: Cannot redeclare class JStringNormalise in D:\UniServerZ\vhosts\smztest\libraries\loader.php on line 513

As you can see the environment is Windows and the WAMP stack is Uniform Server, with PHP 5.3.29

As I said, I tried several times, even logging-out and back in, resetting my browser, and also shutting down and restarting Apache, but I've been unable to get that message again!

If there anything I can do, please let me know...

avatar smanzi
smanzi - comment - 27 Nov 2014

Ahhh!!! I found another page that triggers this "Warning", always:
Install Akeeba Backup 4.1.0.rc3, go to the "Control Panel" and then click on "Options": same "Warning"!

avatar smanzi
smanzi - comment - 27 Nov 2014

Here it is:
capture
I don't think this a problem in Akeeba Backup, as the first time I got it in "Contacts"....

avatar smanzi
smanzi - comment - 27 Nov 2014

I Think we get it in every "Option" page:
capture
Maybe my memory is failing me and the first time I was in "Contacts -> Options"...

avatar smanzi
smanzi - comment - 27 Nov 2014

... and reverting this PR the warning disappears.

avatar infograf768
infograf768 - comment - 27 Nov 2014

@smanzi
I do not get your issue here on staging.

@test OK for me.

avatar nikosdion
nikosdion - comment - 27 Nov 2014

Sergio, the PR is NOT written for Joomla! 3.3. It must be installed on Joomla! 3.4 alpha.=

avatar smanzi
smanzi - comment - 27 Nov 2014

@nikosdion Do you really think I've tested the last 10+ PRs on 3.3? :open_mouth:

avatar smanzi
smanzi - comment - 27 Nov 2014

@infograf768 Should I refresh 3.4.0-dev with the latest staging? Are you on Windows? PHP?

avatar nikosdion
nikosdion - comment - 27 Nov 2014

@smanzi I have no idea. I am not sitting behind your shoulder :) Can you try pulling the latest staging branch and then try the path on it? This is the environment this PR was developed and tested on.

avatar infograf768
infograf768 - comment - 27 Nov 2014

Mac here, not Windows

avatar smanzi
smanzi - comment - 27 Nov 2014

OK: give me some minutes to refresh with the latest staging...

avatar brianteeman
brianteeman - comment - 27 Nov 2014

i just got the same error message on the first page i visited after applying the patch
this was with the alpa release
now testing with current staging

avatar brianteeman
brianteeman - comment - 27 Nov 2014

confirmed that i got the error with staging as well
see video https://www.dropbox.com/s/v9q5ta7zpp9iqo3/ScreenFlow.mp4?dl=0

This comment was created with the J!Tracker Application at issues.joomla.org/joomla-cms/5189.

avatar brianteeman
brianteeman - comment - 27 Nov 2014

removing the RTC setting for now

This comment was created with the J!Tracker Application at issues.joomla.org/joomla-cms/5189.

avatar brianteeman brianteeman - change - 27 Nov 2014
Status Ready to Commit Pending
avatar smanzi
smanzi - comment - 27 Nov 2014

... while it disappeared here... :smile:

avatar nikosdion
nikosdion - comment - 27 Nov 2014

I see what was going on and fixed it. The loadByAlias would execute class_alias(self::$classAliases[$class], $class); but the regular class (self::$classAliases[$class]) wasn't already loaded. So this line would first trigger the autoloader of the regular class which, in turn, it triggers the applyAliasFor which defines the class alias. So by the time this line would be executed by PHP both the original class and the alias would be loaded, hence the warning.

The fix was simple. I just call class_exists on the regular class first, then check if the alias is already set. By separating these two steps we can prevent this warning from displaying.

avatar smanzi
smanzi - comment - 27 Nov 2014

someone pleas explain me why it disappeared here! :sob:

avatar smanzi
smanzi - comment - 27 Nov 2014

I will explain: 'cause I'm a moron: I forgot to apply the patch!!!

avatar smanzi
smanzi - comment - 27 Nov 2014

@test confirmed OK with latest commit

avatar brianteeman
brianteeman - comment - 27 Nov 2014

Will test again shortly
On 27 Nov 2014 11:57, "Sergio Manzi (smz)" notifications@github.com wrote:

@test https://github.com/test confirmed OK with latest commit


Reply to this email directly or view it on GitHub
#5189 (comment).

avatar smanzi
smanzi - comment - 27 Nov 2014

@infograf768 Can it be that you didn't have E_WARNING in your php.ini?

avatar brianteeman
brianteeman - comment - 27 Nov 2014

@test retested and all good now - setting back to RTC

This comment was created with the J!Tracker Application at issues.joomla.org/joomla-cms/5189.

avatar brianteeman brianteeman - change - 27 Nov 2014
Status Pending Ready to Commit
avatar brianteeman brianteeman - change - 29 Nov 2014
Labels Added: ?
avatar Bakual Bakual - change - 2 Dec 2014
Status Ready to Commit Closed
Closed_Date 0000-00-00 00:00:00 2014-12-02 19:13:48
avatar Bakual Bakual - close - 2 Dec 2014
avatar zero-24 zero-24 - close - 2 Dec 2014
avatar Bakual
Bakual - comment - 2 Dec 2014

Merged into staging. Thanks!

avatar zero-24 zero-24 - change - 14 Oct 2015
Labels Removed: ?
avatar joomla-cms-bot joomla-cms-bot - change - 14 Oct 2015
Labels Added: ?

Add a Comment

Login with GitHub to post a comment