Skip to content

Commit 0e57bdd

Browse files
authored
Introduce a UserFactoryAware interface (#40337)
* Introduce an UserFactoryAware interface * 0 * Test * safe * trigger deprecated message * protected * test * load user correctly * fix the deprecated message
1 parent 2911da0 commit 0e57bdd

File tree

9 files changed

+232
-36
lines changed

9 files changed

+232
-36
lines changed

administrator/components/com_actionlogs/src/Model/ActionlogModel.php

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
use Joomla\CMS\Mail\Exception\MailDisabledException;
1818
use Joomla\CMS\Mail\MailTemplate;
1919
use Joomla\CMS\MVC\Model\BaseDatabaseModel;
20+
use Joomla\CMS\User\UserFactoryAwareInterface;
21+
use Joomla\CMS\User\UserFactoryAwareTrait;
2022
use Joomla\Component\Actionlogs\Administrator\Helper\ActionlogsHelper;
2123
use Joomla\Utilities\IpHelper;
2224
use PHPMailer\PHPMailer\Exception as phpMailerException;
@@ -30,8 +32,10 @@
3032
*
3133
* @since 3.9.0
3234
*/
33-
class ActionlogModel extends BaseDatabaseModel
35+
class ActionlogModel extends BaseDatabaseModel implements UserFactoryAwareInterface
3436
{
37+
use UserFactoryAwareTrait;
38+
3539
/**
3640
* Function to add logs to the database
3741
* This method adds a record to #__action_logs contains (message_language_key, message, date, context, user)
@@ -45,9 +49,13 @@ class ActionlogModel extends BaseDatabaseModel
4549
*
4650
* @since 3.9.0
4751
*/
48-
public function addLog($messages, $messageLanguageKey, $context, $userId = null)
52+
public function addLog($messages, $messageLanguageKey, $context, $userId = 0)
4953
{
50-
$user = Factory::getUser($userId);
54+
if (!is_numeric($userId)) {
55+
@trigger_error(sprintf('User ID must be an integer in %s.', __METHOD__), E_USER_DEPRECATED);
56+
}
57+
58+
$user = $userId ? $this->getUserFactory()->loadUserById($userId) : $this->getCurrentUser();
5159
$db = $this->getDatabase();
5260
$date = Factory::getDate();
5361
$params = ComponentHelper::getComponent('com_actionlogs')->getParams();

administrator/components/com_users/src/View/User/HtmlView.php

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
use Joomla\CMS\Object\CMSObject;
1919
use Joomla\CMS\Toolbar\Toolbar;
2020
use Joomla\CMS\Toolbar\ToolbarHelper;
21-
use Joomla\CMS\User\User;
22-
use Joomla\CMS\User\UserFactoryInterface;
21+
use Joomla\CMS\User\UserFactoryAwareInterface;
22+
use Joomla\CMS\User\UserFactoryAwareTrait;
2323
use Joomla\Component\Users\Administrator\Helper\Mfa;
2424

2525
// phpcs:disable PSR1.Files.SideEffects
@@ -31,8 +31,10 @@
3131
*
3232
* @since 1.5
3333
*/
34-
class HtmlView extends BaseHtmlView
34+
class HtmlView extends BaseHtmlView implements UserFactoryAwareInterface
3535
{
36+
use UserFactoryAwareTrait;
37+
3638
/**
3739
* The Form object
3840
*
@@ -114,10 +116,7 @@ public function display($tpl = null)
114116
$this->form->setValue('password', null);
115117
$this->form->setValue('password2', null);
116118

117-
/** @var User $userBeingEdited */
118-
$userBeingEdited = Factory::getContainer()
119-
->get(UserFactoryInterface::class)
120-
->loadUserById($this->item->id);
119+
$userBeingEdited = $this->getUserFactory()->loadUserById($this->item->id);
121120

122121
if ($this->item->id > 0 && (int) $userBeingEdited->id == (int) $this->item->id) {
123122
try {

libraries/src/Application/IdentityAware.php

Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
namespace Joomla\CMS\Application;
1111

1212
use Joomla\CMS\User\User;
13-
use Joomla\CMS\User\UserFactoryInterface;
13+
use Joomla\CMS\User\UserFactoryAwareTrait;
1414

1515
// phpcs:disable PSR1.Files.SideEffects
1616
\defined('JPATH_PLATFORM') or die;
@@ -23,6 +23,8 @@
2323
*/
2424
trait IdentityAware
2525
{
26+
use UserFactoryAwareTrait;
27+
2628
/**
2729
* The application identity object.
2830
*
@@ -31,14 +33,6 @@ trait IdentityAware
3133
*/
3234
protected $identity;
3335

34-
/**
35-
* UserFactoryInterface
36-
*
37-
* @var UserFactoryInterface
38-
* @since 4.0.0
39-
*/
40-
private $userFactory;
41-
4236
/**
4337
* Get the application identity.
4438
*
@@ -62,22 +56,8 @@ public function getIdentity()
6256
*/
6357
public function loadIdentity(User $identity = null)
6458
{
65-
$this->identity = $identity ?: $this->userFactory->loadUserById(0);
59+
$this->identity = $identity ?: $this->getUserFactory()->loadUserById(0);
6660

6761
return $this;
6862
}
69-
70-
/**
71-
* Set the user factory to use.
72-
*
73-
* @param UserFactoryInterface $userFactory The user factory to use
74-
*
75-
* @return void
76-
*
77-
* @since 4.0.0
78-
*/
79-
public function setUserFactory(UserFactoryInterface $userFactory)
80-
{
81-
$this->userFactory = $userFactory;
82-
}
8363
}

libraries/src/Extension/Service/Provider/MVCFactory.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Joomla\CMS\MVC\Factory\ApiMVCFactory;
1515
use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
1616
use Joomla\CMS\Router\SiteRouter;
17+
use Joomla\CMS\User\UserFactoryInterface;
1718
use Joomla\Database\DatabaseInterface;
1819
use Joomla\DI\Container;
1920
use Joomla\DI\ServiceProviderInterface;
@@ -76,6 +77,7 @@ function (Container $container) {
7677
$factory->setDatabase($container->get(DatabaseInterface::class));
7778
$factory->setSiteRouter($container->get(SiteRouter::class));
7879
$factory->setCacheControllerFactory($container->get(CacheControllerFactoryInterface::class));
80+
$factory->setUserFactory($container->get(UserFactoryInterface::class));
7981

8082
return $factory;
8183
}

libraries/src/MVC/Factory/MVCFactory.php

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
use Joomla\CMS\MVC\Model\ModelInterface;
1919
use Joomla\CMS\Router\SiteRouterAwareInterface;
2020
use Joomla\CMS\Router\SiteRouterAwareTrait;
21+
use Joomla\CMS\User\UserFactoryAwareInterface;
22+
use Joomla\CMS\User\UserFactoryAwareTrait;
2123
use Joomla\Database\DatabaseAwareInterface;
2224
use Joomla\Database\DatabaseAwareTrait;
2325
use Joomla\Database\DatabaseInterface;
@@ -35,13 +37,14 @@
3537
*
3638
* @since 3.10.0
3739
*/
38-
class MVCFactory implements MVCFactoryInterface, FormFactoryAwareInterface, SiteRouterAwareInterface
40+
class MVCFactory implements MVCFactoryInterface, FormFactoryAwareInterface, SiteRouterAwareInterface, UserFactoryAwareInterface
3941
{
4042
use FormFactoryAwareTrait;
4143
use DispatcherAwareTrait;
4244
use DatabaseAwareTrait;
4345
use SiteRouterAwareTrait;
4446
use CacheControllerFactoryAwareTrait;
47+
use UserFactoryAwareTrait;
4548

4649
/**
4750
* The namespace to create the objects from.
@@ -95,6 +98,7 @@ public function createController($name, $prefix, array $config, CMSApplicationIn
9598
$this->setDispatcherOnObject($controller);
9699
$this->setRouterOnObject($controller);
97100
$this->setCacheControllerOnObject($controller);
101+
$this->setUserFactoryOnObject($controller);
98102

99103
return $controller;
100104
}
@@ -140,6 +144,7 @@ public function createModel($name, $prefix = '', array $config = [])
140144
$this->setDispatcherOnObject($model);
141145
$this->setRouterOnObject($model);
142146
$this->setCacheControllerOnObject($model);
147+
$this->setUserFactoryOnObject($model);
143148

144149
if ($model instanceof DatabaseAwareInterface) {
145150
try {
@@ -196,6 +201,7 @@ public function createView($name, $prefix = '', $type = '', array $config = [])
196201
$this->setDispatcherOnObject($view);
197202
$this->setRouterOnObject($view);
198203
$this->setCacheControllerOnObject($view);
204+
$this->setUserFactoryOnObject($view);
199205

200206
return $view;
201207
}
@@ -359,4 +365,26 @@ private function setCacheControllerOnObject($object): void
359365
// Ignore it
360366
}
361367
}
368+
369+
/**
370+
* Sets the internal user factory on the given object.
371+
*
372+
* @param object $object The object
373+
*
374+
* @return void
375+
*
376+
* @since __DEPLOY_VERSION__
377+
*/
378+
private function setUserFactoryOnObject($object): void
379+
{
380+
if (!$object instanceof UserFactoryAwareInterface) {
381+
return;
382+
}
383+
384+
try {
385+
$object->setUserFactory($this->getUserFactory());
386+
} catch (\UnexpectedValueException $e) {
387+
// Ignore it
388+
}
389+
}
362390
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
/**
4+
* Joomla! Content Management System
5+
*
6+
* @copyright (C) 2023 Open Source Matters, Inc. <https://www.joomla.org>
7+
* @license GNU General Public License version 2 or later; see LICENSE.txt
8+
*/
9+
10+
namespace Joomla\CMS\User;
11+
12+
// phpcs:disable PSR1.Files.SideEffects
13+
\defined('_JEXEC') or die;
14+
// phpcs:enable PSR1.Files.SideEffects
15+
16+
/**
17+
* Interface to be implemented by classes depending on a user factory.
18+
*
19+
* @since __DEPLOY_VERSION__
20+
*/
21+
interface UserFactoryAwareInterface
22+
{
23+
/**
24+
* Set the user factory to use.
25+
*
26+
* @param UserFactoryInterface $factory The user factory to use.
27+
*
28+
* @return void
29+
*
30+
* @since __DEPLOY_VERSION__
31+
*/
32+
public function setUserFactory(UserFactoryInterface $factory): void;
33+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
3+
/**
4+
* Joomla! Content Management System
5+
*
6+
* @copyright (C) 2023 Open Source Matters, Inc. <https://www.joomla.org>
7+
* @license GNU General Public License version 2 or later; see LICENSE.txt
8+
*/
9+
10+
namespace Joomla\CMS\User;
11+
12+
// phpcs:disable PSR1.Files.SideEffects
13+
\defined('_JEXEC') or die;
14+
// phpcs:enable PSR1.Files.SideEffects
15+
16+
/**
17+
* Defines the trait for a UserFactoryInterface Aware Class.
18+
*
19+
* @since __DEPLOY_VERSION__
20+
*/
21+
trait UserFactoryAwareTrait
22+
{
23+
/**
24+
* UserFactoryInterface
25+
*
26+
* @var UserFactoryInterface
27+
* @since __DEPLOY_VERSION__
28+
*/
29+
private $userFactory;
30+
31+
/**
32+
* Get the UserFactoryInterface.
33+
*
34+
* @return UserFactoryInterface
35+
*
36+
* @since __DEPLOY_VERSION__
37+
* @throws \UnexpectedValueException May be thrown if the UserFactory has not been set.
38+
*/
39+
protected function getUserFactory(): UserFactoryInterface
40+
{
41+
if ($this->userFactory) {
42+
return $this->userFactory;
43+
}
44+
45+
throw new \UnexpectedValueException('UserFactory not set in ' . __CLASS__);
46+
}
47+
48+
/**
49+
* Set the user factory to use.
50+
*
51+
* @param UserFactoryInterface $userFactory The user factory to use.
52+
*
53+
* @return void
54+
*
55+
* @since __DEPLOY_VERSION__
56+
*/
57+
public function setUserFactory(UserFactoryInterface $userFactory): void
58+
{
59+
$this->userFactory = $userFactory;
60+
}
61+
}

tests/Unit/Libraries/Cms/User/CurrentUserTraitTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
use Joomla\Tests\Unit\UnitTestCase;
1616

1717
/**
18-
* Test class for \Joomla\CMS\MVC\Model\BaseDatabaseModel
18+
* Test class for \Joomla\CMS\MVC\Model\BaseDatabaseModelUser\CurrentUserTrait
1919
*
2020
* @package Joomla.UnitTest
2121
* @subpackage MVC

0 commit comments

Comments
 (0)