PR-7.0-dev PR-6.2-dev Architecture Pending

User tests: Successful: Unsuccessful:

avatar joomdonation
joomdonation
19 Jun 2026

Pull Request resolves # .

  • I read the Generative AI policy and my contribution is either not created with the help of AI or is compatible with the policy and GNU/GPL 2 or later.

Summary of Changes

Joomla\CMS\Event\AbstractEvent class has a mechanism to allow preprocess/validate event arguments data before actual storing it. The onSetName syntax is preferred and the setName is deprecated. Please look at https://github.com/joomla/joomla-cms/blob/6.2-dev/libraries/src/Event/AbstractEvent.php#L221-L240 to understand more logic

The problem is that in some our concrete event classes, we have the actual code for preprocess/validation in the deprecated method (the method with set prefix) and the preferred method (the method with onSet prefix) call that deprecated methods. So assume we remove the deprecated methods, the onSet method won't work anymore

This PR fixes that problem by:

  • Moved validation/preprocessing logic from deprecated set*() methods to onSet*() methods
  • Changed deprecated methods to call to onSet*() methods so that it is safe to remove in the future

Testing Instructions

  • Tests pass
  • Code review from maintainers

Actual result BEFORE applying this Pull Request

Works, but wrong implementation for deprecated methods

Expected result AFTER applying this Pull Request

Works, correct deprecated methods implementation

Link to documentations

Please select:

  • [] Documentation link for guide.joomla.org:

  • No documentation changes for guide.joomla.org needed

  • Pull Request link for manual.joomla.org:

  • No documentation changes for manual.joomla.org needed

avatar joomdonation joomdonation - open - 19 Jun 2026
avatar joomdonation joomdonation - change - 19 Jun 2026
Status New Pending
avatar joomla-cms-bot joomla-cms-bot - change - 19 Jun 2026
Category Libraries
avatar richard67
richard67 - comment - 19 Jun 2026

@joomdonation It seems you need to update the phpstan-baseline file. This can be done after a composer install with command ./libraries/vendor/bin/phpstan -b.

avatar joomdonation
joomdonation - comment - 19 Jun 2026

@richard67 Not sure if it is on my Windows or not but running the command generates so many changes to the phpstan-baseline file. If you have time, could you please help me with this?

avatar richard67
richard67 - comment - 19 Jun 2026

./libraries/vendor/bin/phpstan

@joomdonation Yes, lots of changes. But to me they look ok. There are lots of deprecations removed, which is the purpose of this PR.

All other changes are of the following type, replacing a deprecation message by another deprecation message. See one example:

Old

identifier: method.deprecated
count: 1
path: libraries/src/Event/User/LoginEvent.php
message: '''
#^Call to deprecated method setResult\(\) of class Joomla\\CMS\\Event\\User\\LogoutEvent\:
4\.4\.0 will be removed in 7\.0
Use counterpart with onSet prefix$#
'''

New

identifier: property.deprecated
count: 1
path: libraries/src/Event/User/LoginEvent.php
message: '''
#^Access to deprecated property \$preventSetArgumentResult of class Joomla\\CMS\\Event\\User\\LoginEvent\:4\.3 will be removed in 7\.0
Using setResult\(\) for the result argument will always be disallowed\.$#
'''

Note the difference in the identifier and the message.

There are several changes of the same kind.

To me it seems to make sense.

To you, too? Or does it need some more changes to get rid of these completely?

If it is ok as it is, I can push the changed phpstan-baseline.neon file to your branch for this PR.

avatar richard67
richard67 - comment - 19 Jun 2026

@joomdonation I've created a PR in your repo with the phpstan-baseline.neon changes: joomdonation#7 @laoneo Could you check if that makes sense to you?

avatar joomdonation joomdonation - change - 19 Jun 2026
Labels Added: PR-6.2-dev Architecture
avatar joomdonation
joomdonation - comment - 19 Jun 2026

Thanks @richard67 . That looks much better than the file generated by the command in my computer. In my computer, there are lots of more changes. I attached the file on my computer for reference.
phpstan-baseline.zip

avatar Fedik
Fedik - comment - 20 Jun 2026

While code changes looks good it still need to test. There was a reason why I leave it ike that. Was some infinity loop or something, I do not remember the detail sanymore.

avatar laoneo
laoneo - comment - 20 Jun 2026

A lot will be tested with system tests. But some human tests would definitely be good. Wondering if we should rebase to 7.0 because of your infinite loop concern?

avatar joomdonation
joomdonation - comment - 21 Jun 2026

For testing, as Allon said, lots are covered by system tests. For manual testing, I personal tested create/edit/publish... article, same with user. I also tested Multi-factor Authentication, all works good

From code, these methods mostly used to pre-processing/validating event arguments data when event object is created. The method is called when it is needed, so don't see how infinity loop could happen here. To be sure, I wrote small script to test event constructor, call onSetXXX, setXXX method to see if infinity loop happens, but it won't.

$event = new \Joomla\CMS\Event\MultiFactor\BeforeDisplayMethods($this->app->getIdentity());

// Standard method call, usually happens in event contruction
$event->setArgument('user', new User(765));

// Manual call the deprecated method
$event->setUser(new User(765));

// Call this new method (for this method, I have to change the method to public to make it callable for testing)
$event->onSetUser(new User(765)); 


From my view, it is all good. And now you will have to do the hard work to make final decision :)
avatar joomdonation
joomdonation - comment - 21 Jun 2026

For testing, as Allon said, lots are covered by system tests. For manual testing, I personal tested create/edit/publish... article, same with user. I also tested Multi-factor Authentication, all works good

From code, these methods mostly used to pre-processing/validating event arguments data when event object is created. The method is called when it is needed, so don't see how infinity loop could happen here. To be sure, I wrote small script to test event constructor, call onSetXXX, setXXX method to see if infinity loop happens, but it won't.

$event = new \Joomla\CMS\Event\MultiFactor\BeforeDisplayMethods($this->app->getIdentity());

// Standard method call, usually happens in event contruction
$event->setArgument('user', new User(765));

// Manual call the deprecated method
$event->setUser(new User(765));

// Call this new method (for this method, I have to change the method to public to make it callable for testing)
$event->onSetUser(new User(765)); 

From my view, it is all good. And now you will have to do the hard work to make final decision :)

avatar laoneo
laoneo - comment - 21 Jun 2026

I guess the infinite loop was caused by extensions extending event classes and did set arguments in a different order. But can't reall remember as well maybe @wilsonge ?

avatar laoneo
laoneo - comment - 21 Jun 2026

That's why I think we should consider to rebase to 7.0.

avatar joomdonation
joomdonation - comment - 21 Jun 2026

I guess the infinite loop was caused by extensions extending event classes and did set arguments in a different order. But can't reall remember as well maybe @wilsonge ?

That does not happen. I wrote some code, create custom event class, create event object (both with arguments in right and wrong order, even tried to test it with arguments with legacy format) and it's still working OK

  • Custom event class
class CustomEventClass extends \Joomla\CMS\Event\Table\BeforePublishEvent
{
	public function __construct($name, array $arguments = [])
	{
		parent::__construct($name, $arguments);

		$this->setState(0);
		$this->onSetState(1);
		$this->setUserId(100);
		$this->onSetState(200);
	}
}
  • Test script to test create event objects with different cases
$db = Factory::getContainer()->get('db');
$row = new Content($db);

// Correct arguments order
$event = new BeforePublishEvent(
	'onTableBeforePublish',
	[
		'subject' => $row,
		'pks'     => [1, 2, 3],
		'state'   => 1,
		'userId'  => 765,
	]
);

// Random arguments order
$event = new BeforePublishEvent(
	'onTableBeforePublish',
	[
		'userId'  => 765,
		'subject' => $row,
		'state'   => 1,
		'pks'     => [1, 2, 3],
	]
);

// Custom event class with correct arguments order
$event = new CustomEventClass(
	'onTableBeforePublish',
	[
		'subject' => $row,
		'pks'     => [1, 2, 3],
		'state'   => 1,
		'userId'  => 765,
	]
);

// Custom event class with random arguments order
$event = new CustomEventClass(
	'onTableBeforePublish',
	[
		'userId'  => 765,
		'subject' => $row,
		'state'   => 1,
		'pks'     => [1, 2, 3],
	]
);

// Custom event class with arguments in legacy format
$event = new CustomEventClass(
	'onTableBeforePublish',
	[
		$row,
		[1, 2, 3],
		1,
		765,
	]
);

Could not think of any cases which cause infinite loop. But if we are still not confident, we can do it for 7.0

avatar laoneo
laoneo - comment - 21 Jun 2026

If I can recall correctly, then it was something with the override of the set or onset function.

avatar joomdonation
joomdonation - comment - 21 Jun 2026

Ah, Yes. If someone extends the class, and override onSet method, then call set method, it will cause infinite loop

avatar joomdonation
joomdonation - comment - 21 Jun 2026

I change the PR to 7.0-dev. But look like there are conflict between 6.2 and 7.0 branch. I convert the PR to draft for now and will continue when 6.2 is up-merged to 7.0. And we will need to decide if we should remove set*() methods on 7.0.

avatar laoneo
laoneo - comment - 21 Jun 2026

Upmerge is in progress #47997

avatar joomdonation
joomdonation - comment - 21 Jun 2026

Upmerge is in progress #47997

Great. Thanks

avatar Fedik
Fedik - comment - 21 Jun 2026

I think it is fine for 6.2,

avatar Fedik
Fedik - comment - 21 Jun 2026

I think it is fine for 6.2,
There was something when you call setFoobar, or something, then the event code doing call of setArgument which again doing call of setFoobar.
I think it was corrected in all the events by adding onSetFoobar.

avatar joomdonation
joomdonation - comment - 21 Jun 2026

@Fedik There is a case which I mentioned above. Not sure if it happens in real life but it will causes infinite loop as you and Allon worry about

If someone extends the class, and override onSet method, then call set method, it will cause infinite loop

avatar laoneo
laoneo - comment - 21 Jun 2026

Yes exactly, something like this prevented us in the past to make the switch. By the way, Upmerge is done.

avatar laoneo
laoneo - comment - 21 Jun 2026

Can you also adapt the target version in the depreciation message to 8.0?

avatar joomdonation
joomdonation - comment - 21 Jun 2026

@laoneo So you want to keep the set*() methods until J8? If so, in theory, we will still face the infinite loop problem

avatar laoneo
laoneo - comment - 21 Jun 2026

Sure, but on some point we need to do the switch. In a major will cause the least headache. Removeing the set functions in the same release when doing the switch would probably be very disruptive. We should give extension devs some time to migrate.

avatar joomdonation joomdonation - change - 21 Jun 2026
Labels Added: PR-7.0-dev
avatar Fedik
Fedik - comment - 21 Jun 2026

If someone extends the class, and override onSet method, then call set method, it will cause infinite loop

That would be a huge bug in their code. That should newer happen.
We can ignore this.

avatar joomdonation
joomdonation - comment - 21 Jun 2026

OK. I changed the messages to 8.0. These methods were marked as deprecated from 4.4.0, I think we can remove on 7.0, but that can be decided later.

avatar Fedik
Fedik - comment - 21 Jun 2026

set/get methods can be removed in 7.0,
I see no reason to wait to 8.0.

There are realted locgick in get/setArgument which should be removed in 7.0
All set/get which is marked as deprectaed for 7.0 can be removed in 7.0.

avatar joomdonation
joomdonation - comment - 21 Jun 2026

If someone extends the class, and override onSet method, then call set method, it will cause infinite loop
That would be a huge bug in their code. That should newer happen. We can ignore this.

Personal, I agree with this. But I just want to stay on safe side because both of you worried about that. If maintainers accept this on 6.2, I will change it back

avatar Fedik
Fedik - comment - 21 Jun 2026

onSet and onGet was added to avoid confusion and avoid such looping, the situation you guys talking is imaginary.
Just ignore that 😉

avatar joomdonation
joomdonation - comment - 21 Jun 2026

onSet and onGet was added to avoid confusion and avoid such looping, the situation you guys talking is imaginary. Just ignore that 😉

Who knows how creative developers could do :). But I will put this to maintenance meeting and let maintainers decide

avatar laoneo laoneo - change - 23 Jun 2026
Title
[6.2] Correct deprecated methods implementation in event classes
[7.0] Correct deprecated methods implementation in event classes
avatar laoneo laoneo - edited - 23 Jun 2026

Add a Comment

Login with GitHub to post a comment