?
avatar anibalsanchez
anibalsanchez
14 Dec 2017

Steps to reproduce the issue

In previous J versions, it was possible to create a system plugin to load a customized core class.

For instance, a new JMail could be loaded with a system plugin before the core class to extend the original mailer class. This is the case of AcyMailing's Override Joomla mailing system plugin (system/acymailingclassmail).

Now, the new Factory prevents the override of core classes binding the namespaced classes:

use Joomla\CMS\Mail\Mail;

...

// Create a Mail object
mail = Mail::getInstance();

...

JClassLoader.. loadClass('Joomla\CMS\Mail\Mail');

Expected result

The current loading order must be respected.

Actual result

JMail is linked to Joomla\CMS\Mail\Mail, instead of following the current loading order.

System information (as much as possible)

Joomla 3.8.3

Additional comments

A workaround for the specific JMail issue is creating a new Joomla\CMS\Mail\Mail ... and loading it before the original Mail class.

So, can we have the same loading order, or do we have to modify the extensions to override the new classes?

avatar anibalsanchez anibalsanchez - open - 14 Dec 2017
avatar joomla-cms-bot joomla-cms-bot - labeled - 14 Dec 2017
avatar franz-wohlkoenig franz-wohlkoenig - change - 14 Dec 2017
Category com_plugins
avatar laoneo
laoneo - comment - 14 Dec 2017

This is still the case. The use statement is not loading the class. Just debugged it on my dev server and JMail is not loaded at all, first time when I send a test mail in the back end. So it should be the same behavior as before.

avatar franz-wohlkoenig franz-wohlkoenig - change - 14 Dec 2017
Status New Discussion
avatar anibalsanchez
anibalsanchez - comment - 14 Dec 2017

Yes, but the problem is that the new Factory class calls Mail::getInstance(); that it is translated into loadClass('Joomla\CMS\Mail\Mail')... So, the loading of JMail is gone.

I'm fixing several sites with the workaround of creating modified versions of Joomla\CMS\Mail\Mail.

avatar mbabker
mbabker - comment - 14 Dec 2017

The old class names are aliased and still heavily used, but should not be permanently relied on going forward. Your best bet as of 3.8 is to overload the proper class name, not the alias.

Note that class overloading is not a supported API feature.

avatar laoneo
laoneo - comment - 14 Dec 2017

The class loader should detect if there is an override for the alias and should then load the override also for the namespaced class. This was introduced in pr #14822.

avatar anibalsanchez
anibalsanchez - comment - 14 Dec 2017

@laoneo The issue is found before the execution of the loader. Factory is calling Mail::getInstance() directly. So, JMailer has no opportunity to be called.

To keep compatibility with previous Joomla 3.x releases, Mail::getInstance() should try to load firstly JMailer instead of going to the new class.

This issue is affecting all J* classes that have been overridden by a system plugin and now are linked to the new namespaced classes.

avatar mbabker
mbabker - comment - 14 Dec 2017

And again, the correct solution is to not rely on overloading of aliased classes as at any time we may update the code to reference the current namespaced class name. And again, overloading of core classes is not a supported API feature (with the exception of the MVC getInstance() methods or form fields/rules which have inbuilt support for path lookups). Overloading core classes is in essence core hacking.

avatar anibalsanchez
anibalsanchez - comment - 14 Dec 2017

Yes, of course, it's an advanced technique. However, this change affects systems and extensions within the J 3.x series and how they are managed.

avatar mbabker
mbabker - comment - 14 Dec 2017

If you can overload core classes you can wrap your core hack logic in a version_compare() conditional for proper functionality. We are not undoing core changes to support developers who overload the core API.

avatar laoneo
laoneo - comment - 14 Dec 2017

Factory is calling Mail::getInstance() directly

But for Joomla\CMS\Mail\Mail exists an alias JMailer and you are overriding this alias or not? Because this should work when you do it in onAfterInitialise. This is before Factory::getMail() is called.

@mbabker if I understood the issue correctly then this should work with the compat layout and the changes in JLoader.

avatar anibalsanchez
anibalsanchez - comment - 14 Dec 2017

@laoneo Yes, there is an alias from JMailer to Joomla\CMS\Mail\Mail. But, in this case, it is never used. Factory calls to Joomla\CMS\Mail\Mail and the loader loads the Mail class. (instead of trying to do the inverse look-up to find JMailer).

avatar Bakual
Bakual - comment - 14 Dec 2017

What stops you from overloading Joomla\CMS\Mail\Mail? It's the same hack as if you overload JMailer.
With code evolving, everything will eventually be changed to use Joomla\CMS\Mail\Mail anyway and JMailer will be dropped.

avatar anibalsanchez
anibalsanchez - comment - 14 Dec 2017

@Bakual I'm applying the fix to the systems that I manage right now. However, this is not a trivial task, and it affects more than the sites and extensions that I manage.

So, we can fix the issue now ... or let it be ...

avatar mbabker
mbabker - comment - 14 Dec 2017

Overloading the core API is not a supported feature. Therefore there is no issue to fix. Period.

If you insist on distributing code that hacks core, you have the requisite skillset to wrap your hack code in version comparisons or other conditional checks that applies your hack in an appropriate manner.

Also, the class name to overload is JMail. If you are really using JMailer then your hack would never work to begin with.

And yes, I am taking a majorly hard nosed stance on this issue. As I do on every issue that equates to "we are core hacking and a change broke our hacks".

avatar laoneo
laoneo - comment - 14 Dec 2017

and the loader loads the Mail class

That's the point where it should detect the override for JMailer and then load the override instead of the original class.

avatar brianteeman
brianteeman - comment - 14 Dec 2017

there is no way we can ever support every crazy decision ever. There is an api - use it. If you dont want to use it then you suffer the consequences
Dont forget that any extension that hacks the core is not allowed on the JED.

avatar anibalsanchez
anibalsanchez - comment - 14 Dec 2017

Thank you for your feedback. It's clear to me now how we have to proceed.

You can close the issue.

avatar franz-wohlkoenig franz-wohlkoenig - change - 14 Dec 2017
Status Discussion Closed
Closed_Date 0000-00-00 00:00:00 2017-12-14 14:34:55
Closed_By franz-wohlkoenig
avatar joomla-cms-bot joomla-cms-bot - close - 14 Dec 2017
avatar franz-wohlkoenig
franz-wohlkoenig - comment - 14 Dec 2017

closed as stated above.


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

avatar joomla-cms-bot
joomla-cms-bot - comment - 14 Dec 2017

Add a Comment

Login with GitHub to post a comment