[4.4] Remove protected flags in DI containers#40388
[4.4] Remove protected flags in DI containers#40388Elfangor93 wants to merge 3 commits intojoomla:4.4-devfrom Elfangor93:remove-protectFlags
Conversation
Remove the protected flag of containers when registering within providers.
|
What do I have to do in documentations? |
|
I think we have to be a bit careful about allowing overrides of everything. For example as a hard thing I don't think the password handlers should be overrideable for security reasons. I think that certain other things like the applications and session (things that traditionally had a Jfactory static method) also probably shouldn't either. Obviously most the factories probably should be overrideable on the other hand. Don't think it's quite as easy as we're making it out to be I'm afraid! |
|
|
I couldn't have worded it better myself. Seriously I couldn't have :) Far from it even. But I completely agree with all of the above. |
|
Tbh, the side effects of switching already used objects are endless. it's something different on Factories used in the local container of the component. there you can't expect that the joomla own factory is used. From my point of view it must be really clear why you want to remove the lock and why and if you don't have a better way to do it. Other example, if a shared instance in the container get replaced, old copies used in extensions are still the old object while new access to the container object will be the new object which could have extremely negative side effects on joomla (core). So to make it should please proof that it doesn't work different for each use case. |
In some of my extensions I use Doctrine ORM instead of Joomla's database handler. That is not conforming the Joomla database interface, so I don't replace that interface. I use them side by side, Joomla's db and Doctrine. No problem for any other extension. I think that the original problem that led to this issue and PR should not be solved by replacing the protected-flag, but by adding another key to the DI-container. But I still think, for other cases (testing amongst them), that we should get rid of that odd protected-flag, for it only protects developers from properly using the DIC. That double message might be a bit confusing. I owe you some concrete examples, both of a better solution of the original problem and proper examples of why we better drop that protected-flag in the DI-container (to be continued). This will need some research. |
If I replace the implementation with my own implementation of the same interface with different functionality and someone else does the same my installation is broken, in worse case beyond repair.
You know joomla is old and extension developers and agencies are complaining that we are too fast in our translation (lol took 7 years for a major version which is basically the same was before with some cleanups)
If I need replace functionality which can't be done by other ways I have to replace existing keys with my own implementation if other components should use them (active or automatically). Since this could make a clash I skipped this and used another approach.
yes but you don't boot joomla and then swap the parts of the container, instead you fill the container with the things you need before they are protected.
So no need to remove the protection because you found a better solution, as you mentioned earlier, modifying the main container is not much more then changing a $globals variable.
If you find a use case where removing the protection is the only way to solve it, I'm happy to here about it. I think the DIC implementation of a CMS like Joomla which is highly dynamical compared to a laravel or symfony application needs to make a "safe playground" for all extension developers and for the site own who installs 30 extensions and expect that not 2 extensions kills each other. |
different functionallity == different interface.
replacing functionallity == changing the interface. Another implementation should preserve the interface. Otherwise it is another interface (and should not be with the original interface as a key in the DIC).
In Joomla extensions we use a clone of the DI-container, so we never swap objects in the original container, but only in the local clone. And that indeed is something else than filling the container with different objects. Would be interesting to create some nice examples of both approaches.
I totally agree. But I think a lot can be improved for that on the current use of Joomla's DI-container in the core. It is in my agenda to try to help with that. |
This comment was marked as outdated.
This comment was marked as outdated.
Wel, that is the case in a Joomla extension: you only override something locally, in the clone of the DI-container that is only used locally. The protected-flag however prevents even that! |
I don't understand 100% what you want to say here. Could you explain this sentence a bit? Do I understand it well, that you think that it would be better to fill the container with your own things before the core protected objects are registered? So that the own objects are (globally) used instead of the core protected objects? And that would be better than replacing a core object in the clone of the DI-container that is only used locally in your extension? I probably misunderstand that, for it looks obvious to me that overriding core things globally is more dangerous for the whole installation than only locally in the cloned container in your own extension. |
Not removing that protected flag might be more dangerous: if someone then wants to override some core behaviour, then we do it globally (for instance using the Obix class extender plugin). Much more powerful, but not restricted to the local clone of the DI-container that every extension makes. I can imagine the following compromise if anyone would be worried that some extension might not only override a local clone of the DI-container that is normally used in every container. For some developer might also do the override in the |
|
This discussion has reached a depth and a level of knowledge about the joomla core where I unfortunately can no longer follow. It seems to me that my change proposal cannot be accepted in this way. However, I do not understand the concept and the implementation of DI containers in joomla well enough to make another, better change proposal. As extension developer I simply became aware that, contrary to the promises, overwriting containers in components does not work after all. In my current project I would like to overwrite the FormFactory, which should be possible from my point of view but isn't at the moment. Therefore my proposition is to unprotect all insensitive containers like From my point of view these containers we can unprotect without causing harm:
What do you think @HLeithner @wilsonge ? |
|
can you show me your formfactory? About the list, every singelton (isShared) cant be unprotected in my opinion. We should have a look to unprotect/allow override for local extension "clones/childs" of the container |
|
Here is possible solutuion joomla-framework/di#47 |
|
@Fedik thanks. Some extra information, if someone might be interested in that: Theoretically, you could change something in the parent container ( The PR of @Fedik in the DI-container joomla-framework/di#47 makes that possible. No difficulties what keys should stay protected: all keys in the child-container (that we now usually use) can then be overriden. I think that is a simple and good (and safe) way to do it. And anyone having concerns about overriding keys in the "central" container can have peace of mind. |
If I see it write the only thing you change is by removing a and do I correctly expect that you show our own configuration view instead of the joomla native implementation? |
Yes this is currently the difference. But there are plans to add also some additional methods to the ConfigForm class...
Yes, exactly. The component will offer more functionality for the configuration than the native implementation. |
|
Thanks to @HLeithner I found a way around overriding the container for my usecase. Since my initial intention was to replace the FormFactory within my component I can do that by using the switch provided in the So maybe a clean solution would be to offer such switches for all containers that may be overritten by extensions? |
|
When we go the way from @Fedik, it would men that my system plugin needs to replace the default form factory in every extension container with my shiny awesome factory, instead of replacing just the global one. I don't have an issue with this, just want to make sure we are aware about this. |
|
seems a very big change with lots of potential for screwups with extensions to go in a minor release |
|
How is this a "very big change" en where would those "lots of potential for screwups" come from in existing core and/or 3rd party extensions? |
As we discussed a couple comments up, better to avoid replacing "global resources", only local needed for extension ;) |
|
For a FormFactory this makes sense. But I'm pretty sure that extensions want to replace the global Database or Language Factory. So this should still be possible IMO. A selling point of Joomla is the extensibility, but having protected services prevents that. So I still think this here is a valid change, even when it comes with the cost, that it can lead to conflicts two extensions will change the Database factory. So what should be promoted more is the extend feature of the container and not the override. |
|
Maybe it's ok to replace a factory but replacing a singleton will create more problems then solving. |
|
A real world use case would be an attempt to implement a router alternative, like @roland-d and yours truly attempted. It is a real shame that Joomla! cannot be fully utilized. Not only as a CMS but also as an application development platform. It has much that is needed but is hampered by obstacles like this. |
|
tbh if this is the only real problem in joomla then we have one. I know so many short comings in joomla and the DIC implementation was never my problem, even if you really want you can bypass it for your self. |
|
Not sure if I interpret that last comment correctly, but do you mean to say that it is not a problem if you don´t experience it as such? Apart from that I would love to learn the solution for the problem Roland and I experienced. We could not find a way around it, due to the protection flag. |
|
As already mentioned Joomla has many parts in the core which hurt us as maintainer on a daily base because the have been merged without thinking about the consequences. We still struggle on features merged in joomla 10 years ago because we can't replace it with a better/easier/efficient system. on the other hand we have only a hand full of developer maintaining the core and have to consider all features for each pr merged, as you can see in the latest release it's not easy to see or test all side effects. And the more open we are the more side effects we have. if you really need it for your own extensions on your own systems you can use the php reflection api an replace more or less everything in joomla. But instead of doing your own thing it would be better to invest your time in the core and help us to maintain joomla and make it better if our apis lacks features. |
|
Thanks for bringing up this issue and the good discussion here. In the meantime allows the Joomla DI container to override services in child containers as the pr joomla-framework/di#48 got merged in the framework repository. That change will be part of Joomla 5.0, so I'm closing this pull request. |
Pull Request for Issue #40324 .
Summary of Changes
Set protected flag to false when registering new container using the service providers available under the namespace
Joomla\CMS\Service\Provider.This will allow to override these containers within custom components.
Testing Instructions
Since this PR provides the possibility to override containers in components, you eighter have to create a new component or modify an existing one like com_content to test it. In the example test below we will override the FormFactory class within com_content by modifying the component provider.
Override the FormFactory class in com_content
Actual result BEFORE applying this Pull Request
php error:
Key Joomla\CMS\Form\FormFactoryInterface is protected and can't be overwritten.Expected result AFTER applying this Pull Request
Form view should open without error and work exactly the same as before.
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