bug PR-5.0-dev b/c break Pending

User tests: Successful: Unsuccessful:

avatar wilsonge
wilsonge
15 Mar 2023

Summary of Changes

This standardises the fact the dispatcher can be injected into any JTable object. Additionally it phases out the use of \Joomla\CMS\Table\Table::getInstance in favour of directly instantiating the class. This is only for Table classes in the same extension or that are in the library folder. The correct way to do cross-extension table instantiation remains through the MVCFactory.

Removing using getInstance is important to allow us to transition to using namespaced classes. getInstance served as a service locator originally when we were not using PSR-4 autoloaders. Now that we are it's surplus to requirements and even actively causing issues with us using namespaced classes.

Testing Instructions

Ensure the entire CMS in all extensions continues to work exactly the same way. There shouldn't be any side effects of this PR - it's purely paving the way for future 5.0 development when the namespace maps will be moved into a compat plugin.

Link to documentations

Please select:

  • Documentation link for docs.joomla.org:

  • No documentation changes for docs.joomla.org needed

  • Pull Request link for manual.joomla.org:

  • No documentation changes for manual.joomla.org needed

avatar joomla-cms-bot joomla-cms-bot - change - 15 Mar 2023
Category Administration com_banners com_contact com_content com_fields com_finder com_installer com_messages com_newsfeeds com_redirect com_tags com_templates com_users com_workflow Libraries
avatar wilsonge wilsonge - open - 15 Mar 2023
avatar wilsonge wilsonge - change - 15 Mar 2023
Status New Pending
avatar wilsonge wilsonge - change - 15 Mar 2023
Title
Improve constructors of JTable objects
[4.4] Improve constructors of JTable objects
avatar wilsonge wilsonge - edited - 15 Mar 2023
avatar SharkyKZ
SharkyKZ - comment - 16 Mar 2023

Additionally it phases out the use of \Joomla\CMS\Table\Table::getInstance in favour of directly instantiating the class.

This is a B/C break for extensions. Joomla\CMS\Table\Table::getInstance() can fetch services from the container, which allows 3PDs to override table classes, including core ones. With your changes this functionality is lost. I get that there are already some places where classes are instantiated directly, but if anything, they should be replaced with consistent use of Joomla\CMS\Table\Table::getInstance() at least for the remainder of 4.x (and actually 5.x according to new policies...).

avatar wilsonge
wilsonge - comment - 21 Mar 2023

This is a B/C break for extensions. Joomla\CMS\Table\Table::getInstance() can fetch services from the container, which allows 3PDs to override table classes, including core ones

I think this is a fair point. I'd also argue that the way that acts currently returning a static cached instance - whereas the rest of getInstance does not is at best not consistent and at worst probably just outright broken (thinking of where within a table class I've currently replaced things with new static. It's only the models (JModelLegacy and JTable) where this is an issue from the original implementation - everything else was statically cached and therefore behaviour between dic and the original methods makes sense 7421a3d

But if you accept that as an argument (accept it's not so clear cut) then it's hard to find a way for people to override the classes.

avatar MacJoom MacJoom - change - 22 Mar 2023
Labels Added: PR-4.4-dev
avatar SharkyKZ
SharkyKZ - comment - 22 Mar 2023

I'd also argue that the way that acts currently returning a static cached instance

Not entirely true. That depends on how the service is defined. It might be shared or not.

avatar laoneo
laoneo - comment - 2 May 2023

@wilsonge want to rebase this one to 5.0 or make it BC?

avatar laoneo laoneo - change - 28 Jun 2023
Labels Added: ? bug
avatar laoneo laoneo - change - 28 Jun 2023
Title
[4.4] Improve constructors of JTable objects
[5.0] Improve constructors of JTable objects
avatar laoneo laoneo - edited - 28 Jun 2023
avatar wilsonge wilsonge - change - 28 Jun 2023
Labels Added: PR-5.0-dev b/c break
Removed: ? PR-4.4-dev
avatar wilsonge
wilsonge - comment - 27 Jul 2023

@HLeithner can you make a decision one way or another about this. Frankly I don't care that much whether we stick with the static getInstance or not (per @SharkyKZ 's comment) but we should at least be consistent.

If you're happy with this approach then I'll go back through and change all the static's to self's per the comments above. But don't wanna do that work if we decide to stick with the getInstance stuff for better b/c

avatar HLeithner
HLeithner - comment - 27 Jul 2023

plan is to get rid of getInstance but in a b/c way till 6.0, but if I see it correctly you always instance the same object again so I would not use new Category for example instead you new static() so that should have the same effect as if your use getInstance for this because getInstance would also resolve to the same implementation.

avatar wilsonge
wilsonge - comment - 28 Jul 2023

Current getInstance allows you to override the class through the container

if (Factory::getContainer()->has($tableClass)) {
return Factory::getContainer()->get($tableClass);
}
. I think before 6.0 we should either convert other things back to getInstance or move all core usage over to creating self/static. Having some things doing named classes and others doing getInstance is inconsistent

avatar HLeithner
HLeithner - comment - 28 Jul 2023

Yes I know I used this in the installer to fix cycle dependencies or where I was not able to inject the database object.
The question is, is this expected behavior? Our Container is not a Container it's a service locator right? which shouldn't store random objects.

In context of our use case in the store function of the banner table

            // Verify that the alias is unique
            /** @var BannerTable $table */
            $table = Table::getInstance('BannerTable', __NAMESPACE__ . '\\', ['dbo' => $db]);

it make zero sense to use getInstance as it could return a singleton because it would return self if someone set 'BannerTable' (with namespace) in the container and then call the store method on the same object.

At least for the getInstance calls within the Table object it should be new static

for the rest of the cms I'm unsure, it's a border case which maybe does more harm then good.

avatar wilsonge
wilsonge - comment - 28 Jul 2023

Our Container is not a Container it's a service locator right?

No the primary container object is supposed to be a genuine container. The individual component containers however are a service locator.

it make zero sense to use getInstance as it could return a singleton

Despite the name getInstance never returns a singleton (unless someone has explicitly made the container override a singleton - but that's them doing their own thing anyway)

for the rest of the cms I'm unsure, it's a border case which maybe does more harm then good.

Well bring it up in the next maintainers call or something. We need to be consistent. I think it's fine removing the containers which I doubt anyone is really using (and I showed you how to sort it in the installer properly) in the major version but I don't feel super strongly about that part. Just the fact we should have a documented consistent approach to how we use this stuff

avatar wilsonge
wilsonge - comment - 3 Sep 2023

@HLeithner what's the plan here?

avatar wilsonge
wilsonge - comment - 4 Sep 2023

Fixed the only outstanding feedback here. Please either merge or close and I'll create a PR to move back to Table::getInstance in the other places

avatar HLeithner HLeithner - change - 4 Sep 2023
Status Pending Fixed in Code Base
Closed_Date 0000-00-00 00:00:00 2023-09-04 20:45:06
Closed_By HLeithner
avatar HLeithner HLeithner - close - 4 Sep 2023
avatar HLeithner HLeithner - merge - 4 Sep 2023
avatar HLeithner
HLeithner - comment - 4 Sep 2023

We will see if it's a problem since this override way not always worked and in introduced in j4 I would say by error , I think it's not really used out there. We need migration documentation at manual please.

Add a Comment

Login with GitHub to post a comment