joomla-cms icon indicating copy to clipboard operation
joomla-cms copied to clipboard

[6.0] CMSPlugin: use Lazy Object feature

Open Fedik opened this issue 9 months ago • 11 comments

Summary of Changes

Alternative to https://github.com/joomla/joomla-cms/pull/43658

Use of PHP Lazy Object feature for plugins. This allows to instantiate the plugin only when event is triggered, and saving some resources (time and memory).

This does not applied automatically for every plugins, the plugin service provider need to be updated to support Lazy Object.

Few thing that need to figure out:

  1. ~Following code will trigger lazy object initialization, we need to get rid of it, somehow.~ https://github.com/joomla/joomla-cms/blob/2c859aa0da3cbc075c28b8d1da2222ba84a89c5d/libraries/src/Plugin/PluginHelper.php#L234-L236

  2. Current use of registerListeners() need to be deprecated. There is PR for it:

  • https://github.com/joomla/joomla-cms/pull/43395 Would be good if it get in to 5.x.

As next step we have to: OR change the return type to boolean for registerListeners(), OR replace it with new method, see the PR:

  • https://github.com/joomla/joomla-cms/pull/43657

Testing Instructions

Apply patch, and test on PHP 8.x and 8.4 The following plugins should work as before:

  • schedulerunner
  • tasknotification
  • webauthn

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: TBD
  • [ ] No documentation changes for manual.joomla.org needed

Fedik avatar Mar 03 '25 16:03 Fedik

As said already, this should be done in the DI container and not every plugin itself should implement this. Or do you see problems when the DI container does that?

laoneo avatar Mar 03 '25 19:03 laoneo

How to?

Fedik avatar Mar 03 '25 20:03 Fedik

Similar cod you have in the service provider, I would do here https://github.com/joomla-framework/di/blob/3.x-dev/src/ContainerResource.php#L160.

laoneo avatar Mar 04 '25 06:03 laoneo

hm, yeah, that also could work, need to check. We need it to be flexible.

But I thought that you have some ready to use solution :)

Fedik avatar Mar 04 '25 09:03 Fedik

This pull request has been automatically rebased to 6.0-dev.

HLeithner avatar Mar 04 '25 17:03 HLeithner

I would suggest to add a simple shortcut for creating lazy proxies:

// Container
public function lazy(string $class, callable $factory): callable
{
    if (PHP_VERSION_ID < 80400) {
        return $factory;
    }

    return function () use ($class, $factory) {
        return (new \ReflectionClass($class))->newLazyProxy(fn() => $factory($this));
    };
}

Then defining lazy service would look like this:

$container->share(
    'foo',
    $container->lazy(Foo::class, function($container) {
        return new Foo($container->get('bar'));
    }),
);

Full implementation you can see here:

voronkovich avatar Mar 05 '25 15:03 voronkovich

I've created a PR with more advanced implementation: https://github.com/joomla-framework/di/pull/58

voronkovich avatar Mar 05 '25 18:03 voronkovich

@laoneo That is require changes in Container code with b/c breaks (need new flags and changed method signature). @voronkovich That implementation does not look good.

I will keep it without DI, there more important issue that need to resolve to make it work.

Fedik avatar Mar 06 '25 08:03 Fedik

I'm pretty sure that this can be achieved in a backwards compatible way or with a minimum of bc breaks which shouldn't affect the CMS code.

laoneo avatar Mar 06 '25 13:03 laoneo

I was playing around with lazy objects and made a lightweight version with https://github.com/joomla-framework/di/pull/63. You can see the outcome in #45392. It doesn't affect the existing CMS code but allows us to define a service with a lazy object.

laoneo avatar Apr 25 '25 12:04 laoneo

@laoneo fedir update the pr to use reflections, this would solve the b/c problem without introducing a new interface.

HLeithner avatar Jun 17 '25 07:06 HLeithner

@HLeithner what do you think, should I re-base it to 5.4?

Fedik avatar Aug 12 '25 08:08 Fedik

I think it's already to late for 5.4 and 6.0

HLeithner avatar Aug 12 '25 08:08 HLeithner

It still fine, with introducing of "Reflection checker" it does not change existing behavior.

Fedik avatar Aug 12 '25 08:08 Fedik

✅ Tested my random quotation module zitat-service.de with JBT: it installs from JED Web, is is configurable and working on frontend site

muhme avatar Aug 22 '25 04:08 muhme

This pull request has been automatically rebased to 6.1-dev.

HLeithner avatar Aug 31 '25 11:08 HLeithner