In J3 we have Joomla\CMS\HTML\HTMLHelper::register()
method but in J4 it's deprecated in favor of Joomla\CMS\HTML\Registry
but that one seems to handle only classes, not specific methods.
Labels |
Added:
?
|
So no more granular control over methods? In J3 it was possible for different plugins to override different methods of the same service.
Not only to override but now it's not possible for different plugins to add new methods. So this code is going to break completely:
joomla-cms/components/com_users/tmpl/profile/default_params.php
Lines 27 to 35 in 20b306e
That example gets harder to deal with, but there are different ways to deal with it.
/**
* Extended JHtmlUsers instance using inheritance
*/
class MyHtmlUsers extends JHtmlUsers
{
// New methods or extended methods here
}
/**
* Extended JHtmlUsers instance using the decorator pattern
*/
class MyHtmlUsers
{
/**
* Decorated HTML helper.
*
* This can't be typehinted to a specific object type due to there not being interfaces for HTML helper classes and breaking use of the decorator pattern.
*
* @var object
*/
private object $decoratedHelper;
public function __construct(object $decoratedHelper)
{
$this->decoratedHelper = $decoratedHelper;
}
// New methods or extended methods here
public function __call(string $name, array $arguments)
{
if (!method_exists($this->decoratedHelper, $name)) {
throw new BadMethodCallException(sprintf('Method "%s" does not exist in "%s".', $name, self::class));
}
return $this->decoratedHelper->$name(...$arguments);
}
}
Granular control on a per method basis only works if you are only using the API design from when Joomla 1.6 was released when this feature was added (all methods must be static methods inside a class, i.e. no support for class instances with dependency injection which makes automated testing of any of these helper methods more complex). The service registry is a bit more technically complex to manage overrides on, but it also adds another layer of feature support to the API as well.
(FWIW this same type of design flaw, a lack of a central registry of known types that can be overridden programatically, exists in other APIs such as the form API with its resolution of form entities (fields, rules, etc.) and the log API (and supporting different logger instances); I made a similar registry type thing for the log API but in the form API they instead chose to replace the addfieldpath
bit with addfieldprefix
(or whatever it was to specify a namespace) instead of opting for the registry approach)
Fully support. For example, you can create a plugin that changes the methods for the Joomshopping component. Thus, Joomshopping can be updated via the update server. However, Joomshopping can use a modified plugin method.
This is a very important point.
.
For example, the store component uses the add material or contact function: ContentModelContent:: save($data);
Thus, you cannot override the method in the CMS, and you cannot modify the store component. But now this can't be done in the PLUGIN.
Dear developers, explain how to do it then?
Status | New | ⇒ | Discussion |
Status | Discussion | ⇒ | Closed |
Closed_Date | 0000-00-00 00:00:00 | ⇒ | 2021-03-25 17:42:05 |
Closed_By | ⇒ | SharkyKZ |
Use the registry for services, subclass the class whose method(s) you want to extend, and treat it as any other PHP class going forward.