From 20c2b6b3e5432feae14358407310cd9e8673b9e9 Mon Sep 17 00:00:00 2001 From: Elias Luhr Date: Mon, 9 Jan 2023 15:43:52 +0100 Subject: [PATCH 01/14] Fixed password recovery link in welcome mail And add this new feature to the plain text variant too --- src/User/resources/views/mail/text/welcome.php | 7 +++++++ src/User/resources/views/mail/welcome.php | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/User/resources/views/mail/text/welcome.php b/src/User/resources/views/mail/text/welcome.php index 484209a1..0d4516b3 100644 --- a/src/User/resources/views/mail/text/welcome.php +++ b/src/User/resources/views/mail/text/welcome.php @@ -15,6 +15,9 @@ * @var \Da\User\Module $module * @var bool $showPassword */ + +use yii\helpers\Url; + ?> , @@ -23,6 +26,10 @@ : password ?> +allowPasswordRecovery): ?> + : + + . diff --git a/src/User/resources/views/mail/welcome.php b/src/User/resources/views/mail/welcome.php index 6a54c052..526f0795 100644 --- a/src/User/resources/views/mail/welcome.php +++ b/src/User/resources/views/mail/welcome.php @@ -30,7 +30,7 @@ : password ?> allowPasswordRecovery): ?> - : + :

From 23106912011258282183fbb34a549be3ad1786f7 Mon Sep 17 00:00:00 2001 From: Elias Luhr Date: Mon, 9 Jan 2023 15:54:28 +0100 Subject: [PATCH 02/14] updated changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c636053a..b8f0ce6f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGELOG +## dev + +- Fix: use correct password recovery url in welcome mail and add functionality to plain text version of the mail + ## 1.6.0 January 9, 2023 **WARNING**: this release (long time due) makes a step forward in PHP From 8a9adf351c48ec3f7058def49c0a9a86dd7edfb6 Mon Sep 17 00:00:00 2001 From: Lorenzo Milesi Date: Mon, 9 Jan 2023 19:51:56 +0100 Subject: [PATCH 03/14] Added author to changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b8f0ce6f..802a099e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## dev -- Fix: use correct password recovery url in welcome mail and add functionality to plain text version of the mail +- Fix: use correct password recovery url in welcome mail and add functionality to plain text version of the mail (@eluhr) ## 1.6.0 January 9, 2023 From 428dcecedf077fedccf05da6a62e25219847b999 Mon Sep 17 00:00:00 2001 From: Lorenzo Milesi Date: Wed, 11 Jan 2023 11:32:49 +0100 Subject: [PATCH 04/14] Add info about BS5 dev in master's readme --- README.md | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 664c29ad..1efde3cf 100644 --- a/README.md +++ b/README.md @@ -27,10 +27,21 @@ module is built to work out of the box with some minor config tweaks and it come We considered that RBAC was essential to be included into any user management module, even if you simply use one user with `admin` role, its much better to actually work with RBAC just in case your application scales in the future. -## Documentation +## Boostrap 4 and 5 support -You can read the latest docs on [http://yii2-usuario.readthedocs.io/en/latest/](http://yii2-usuario.readthedocs.io/en/latest/) +With the release of 1.6, contributors started implementing changes for supporting newer versions of the Boostrap library, +being Usuario stuck at 3. + +Up until around May 2023, the `master` branch will remain stable, so devs who in these years relied on it for +deployment can have time to migrate to a stable version. +BS5 development is ongoing on branch [`2.0.0-dev`](https://github.com/2amigos/yii2-usuario/tree/v2.0.0-dev), +which will eventually be merged in `master` around May. + +You can check issues #476, #488, #500 for updates, or the [branch itself](https://github.com/2amigos/yii2-usuario/tree/v2.0.0-dev). +## Documentation + +You can read the latest docs on [http://yii2-usuario.readthedocs.io/en/latest/](http://yii2-usuario.readthedocs.io/en/latest/) ## Need Help? From 1fd1febaa40468b271e455569b3a8dcd04f0492f Mon Sep 17 00:00:00 2001 From: niciz Date: Mon, 30 Jan 2023 14:20:09 +0100 Subject: [PATCH 05/14] Update LoginWidget.php Fix LoginWidget viewPath --- src/User/Widget/LoginWidget.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/User/Widget/LoginWidget.php b/src/User/Widget/LoginWidget.php index df5729ec..cf31affb 100644 --- a/src/User/Widget/LoginWidget.php +++ b/src/User/Widget/LoginWidget.php @@ -27,7 +27,7 @@ class LoginWidget extends Widget public function run() { return $this->render( - $this->getModule()->$this->viewPath .'/widgets/login/form', + $this->getModule()->viewPath .'/widgets/login/form', [ 'model' => Yii::createObject(LoginForm::class), ] From c274d71ecf1cb45daac52d47f764332ac6ee744b Mon Sep 17 00:00:00 2001 From: niciz Date: Mon, 30 Jan 2023 14:47:42 +0100 Subject: [PATCH 06/14] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 802a099e..e17f31b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## dev - Fix: use correct password recovery url in welcome mail and add functionality to plain text version of the mail (@eluhr) +- Fix: correct viewPath error in LoginWidget (niciz) ## 1.6.0 January 9, 2023 From 22c994db6ed1b113a30aec403f4ef34ae87a0081 Mon Sep 17 00:00:00 2001 From: "E.Alamo" Date: Mon, 6 Feb 2023 20:46:57 +0100 Subject: [PATCH 07/14] Fix mispelling The translation said: Paste the following text, while the original message is Paste the text. It can lead to confussion since there is nothing after that text in the emails. --- src/User/resources/i18n/es/usuario.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/User/resources/i18n/es/usuario.php b/src/User/resources/i18n/es/usuario.php index 505417fd..28394d28 100644 --- a/src/User/resources/i18n/es/usuario.php +++ b/src/User/resources/i18n/es/usuario.php @@ -114,7 +114,7 @@ 'Here you can download your personal data in a comma separated values format.' => 'Aquí puede descargar su información personal en formato de valores separados por comas.', 'I agree processing of my personal data and the use of cookies to facilitate the operation of this site. For more information read our {privacyPolicy}' => 'Doy mi consentimiento para el procesamiento de mis datos personales y el uso de «cookies» para facilitar el funcionamiento de este sitio. Para más información lea nuestra {privacyPolicy}', 'If you already registered, sign in and connect this account on settings page' => 'Si ya está registrado, inicie sesión y conecte esta cuenta en la página de configuración', - 'If you cannot click the link, please try pasting the text into your browser' => 'Si no puede pulsar en el enlace, intente pegar el siguiente texto en su navegador web', + 'If you cannot click the link, please try pasting the text into your browser' => 'Si no puede pulsar en el enlace, intente pegar el texto en su navegador web', 'If you did not make this request you can ignore this email' => 'Si no hizo esta petición, puede ignorar este mensaje', 'Impersonate this user' => 'Personificar este usuario', 'In order to complete your registration, please click the link below' => 'Para completar el registro, pulse el siguiente enlace', From 7bdaeb2202f1baae8225b403fdbbce814cf43c74 Mon Sep 17 00:00:00 2001 From: Liviu Calin Date: Wed, 22 Feb 2023 14:31:12 +0100 Subject: [PATCH 08/14] Possibility to call all the api endpoints with id or username or email --- .../Controller/api/v1/AdminController.php | 63 +++++-------------- src/User/Query/UserQuery.php | 12 ++++ 2 files changed, 27 insertions(+), 48 deletions(-) diff --git a/src/User/Controller/api/v1/AdminController.php b/src/User/Controller/api/v1/AdminController.php index f4ac02e6..4579585a 100644 --- a/src/User/Controller/api/v1/AdminController.php +++ b/src/User/Controller/api/v1/AdminController.php @@ -139,37 +139,6 @@ public function checkAccess($action, $model = null, $params = []) } } - /** - * Override beforeAction. If the api is called with parameter username get the id of the user and set it in query params - * @param mixed $action - */ - public function beforeAction($action) - { - if ($action == 'create') { - return parent::beforeAction($action); - } - - $id = Yii::$app->request->getQueryParam('id'); - if (!is_null($id)) { - return parent::beforeAction($action); - } - - $username = Yii::$app->request->getQueryParam('username'); - if (is_null($username)) { - return parent::beforeAction($action); - } - - $user = $this->userQuery->where(['username' => $username])->one(); - if (is_null($user)) { // Check user, so ` $username` parameter - return parent::beforeAction($action); - } - - $params = Yii::$app->request->getQueryParams(); - $params['id'] = $user->id; - Yii::$app->request->setQueryParams($params); - - return parent::beforeAction($action); - } /** * Create a user. */ @@ -207,15 +176,14 @@ public function actionCreate() * Update a user. * @param int $id ID of the user. */ - public function actionUpdate($id = null) + public function actionUpdate($id) { // Check access $this->checkAccess($this->action); - $id = Yii::$app->request->getQueryParam('id'); // Get user model /** @var User $user */ - $user = $this->userQuery->where(['id' => $id])->one(); + $user = $this->userQuery->whereIdOrUsernameOrEmail($id)->one(); if (is_null($user)) { // Check user, so `$id` parameter $this->throwUser404(); } @@ -247,18 +215,18 @@ public function actionDelete($id) // Check access $this->checkAccess($this->action); - // Check ID parameter (whether own account) - if ((int)$id === Yii::$app->user->getId()) { - throw new BadRequestHttpException(Yii::t('usuario', 'You cannot remove your own account.')); - } - // Get user model /** @var User $user */ - $user = $this->userQuery->where(['id' => $id])->one(); + $user = $this->userQuery->whereIdOrUsernameOrEmail($id)->one(); if (is_null($user)) { // Check user, so `$id` parameter $this->throwUser404(); } + // Check ID parameter (whether own account) + if ($user->id === Yii::$app->user->getId()) { + throw new BadRequestHttpException(Yii::t('usuario', 'You cannot remove your own account.')); + } + // Create event object /** @var UserEvent $event */ $event = $this->make(UserEvent::class, [$user]); @@ -284,7 +252,7 @@ public function actionUpdateProfile($id) // Get user model /** @var User $user */ - $user = $this->userQuery->where(['id' => $id])->one(); + $user = $this->userQuery->whereIdOrUsernameOrEmail($id)->one(); if (is_null($user)) { // Check user, so `$id` parameter $this->throwUser404(); } @@ -322,7 +290,7 @@ public function actionAssignments($id) // Get user model /** @var User $user */ - $user = $this->userQuery->where(['id' => $id])->one(); + $user = $this->userQuery->whereIdOrUsernameOrEmail($id)->one(); if (is_null($user)) { // Check user, so `$id` parameter $this->throwUser404(); } @@ -343,7 +311,7 @@ public function actionConfirm($id) // Get user model /** @var User $user */ - $user = $this->userQuery->where(['id' => $id])->one(); + $user = $this->userQuery->whereIdOrUsernameOrEmail($id)->one(); if (is_null($user)) { // Check user, so `$id` parameter $this->throwUser404(); } @@ -366,11 +334,10 @@ public function actionConfirm($id) * Block and unblock the user. * @param int $id ID of the user. */ - public function actionBlock($id = null) + public function actionBlock($id) { // Check access $this->checkAccess($this->action); - $id = Yii::$app->request->getQueryParam('id'); // Check ID parameter (whether own account) if ((int)$id === Yii::$app->user->getId()) { @@ -379,7 +346,7 @@ public function actionBlock($id = null) // Get user model /** @var User $user */ - $user = $this->userQuery->where(['id' => $id])->one(); + $user = $this->userQuery->whereIdOrUsernameOrEmail($id)->one(); if (is_null($user)) { // Check user, so `$id` parameter $this->throwUser404(); } @@ -407,7 +374,7 @@ public function actionPasswordReset($id) // Get user model /** @var User $user */ - $user = $this->userQuery->where(['id' => $id])->one(); + $user = $this->userQuery->whereIdOrUsernameOrEmail($id)->one(); if (is_null($user)) { // Check user, so `$id` parameter $this->throwUser404(); } @@ -432,7 +399,7 @@ public function actionForcePasswordChange($id) // Get user model /** @var User $user */ - $user = $this->userQuery->where(['id' => $id])->one(); + $user = $this->userQuery->whereIdOrUsernameOrEmail($id)->one(); if (is_null($user)) { // Check user, so `$id` parameter $this->throwUser404(); } diff --git a/src/User/Query/UserQuery.php b/src/User/Query/UserQuery.php index 39d7278c..68c8ad73 100644 --- a/src/User/Query/UserQuery.php +++ b/src/User/Query/UserQuery.php @@ -15,6 +15,18 @@ class UserQuery extends ActiveQuery { + /** + * @param $idOrUsernameOrEmail + * + * @return $this + */ + public function whereIdOrUsernameOrEmail($idOrUsernameOrEmail) + { + return filter_var($idOrUsernameOrEmail, FILTER_VALIDATE_INT) + ? $this->whereId($idOrUsernameOrEmail) + : $this->whereUsernameOrEmail($idOrUsernameOrEmail); + } + /** * @param $usernameOrEmail * From 54c72a2a3231fa0a5a1849e2dda4c35bc4ce2301 Mon Sep 17 00:00:00 2001 From: Liviu Calin Date: Wed, 22 Feb 2023 14:33:40 +0100 Subject: [PATCH 09/14] Possibility to call all the api endpoints with id or username or email changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e17f31b3..fd32ea39 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - Fix: use correct password recovery url in welcome mail and add functionality to plain text version of the mail (@eluhr) - Fix: correct viewPath error in LoginWidget (niciz) +- Enh: possibility to call all the api endpoints with either id or username or email (liviuk2) ## 1.6.0 January 9, 2023 From f22148660beb14e73baf1cfcaa16611986a8b151 Mon Sep 17 00:00:00 2001 From: Jussi Aho Date: Thu, 23 Feb 2023 12:49:07 +0200 Subject: [PATCH 10/14] Use correct User model if overwritten in config Two factor authentication doesn't work if the User model has been changed in the config from the modules own model class. This fix gets the correct User model from the class map. --- src/User/Controller/SecurityController.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/User/Controller/SecurityController.php b/src/User/Controller/SecurityController.php index d7a32053..c49cf79b 100644 --- a/src/User/Controller/SecurityController.php +++ b/src/User/Controller/SecurityController.php @@ -221,9 +221,10 @@ public function actionConfirm() $validators = $module->twoFactorAuthenticationValidators; $credentials = Yii::$app->session->get('credentials'); $login = $credentials['login']; - $user = User::findOne(['email' => $login]); + $userModel = $this->getClassMap()->get(User::class); + $user = $userModel::findOne(['email' => $login]); if ($user == null) { - $user = User::findOne(['username' => $login]); + $user = $userModel::findOne(['username' => $login]); } $tfType = $user->getAuthTfType(); From 9fd6f8da6f6d801154719180ff2cfc6321f5525e Mon Sep 17 00:00:00 2001 From: Jussi Aho Date: Thu, 23 Feb 2023 14:10:30 +0200 Subject: [PATCH 11/14] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fd32ea39..2ca9ab55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - Fix: use correct password recovery url in welcome mail and add functionality to plain text version of the mail (@eluhr) - Fix: correct viewPath error in LoginWidget (niciz) - Enh: possibility to call all the api endpoints with either id or username or email (liviuk2) +- Fix: use configured User model in SecurityController 2FA confirmation (jussiaho) ## 1.6.0 January 9, 2023 From 7216c67854b1f5d76febfbc135c8e2d8883cca48 Mon Sep 17 00:00:00 2001 From: Marco Piazza Date: Mon, 3 Apr 2023 16:34:48 +0200 Subject: [PATCH 12/14] Possibility to get user ids from roles recursively --- CHANGELOG.md | 1 + src/User/Component/AuthDbManagerComponent.php | 73 +++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ca9ab55..396a06ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - Fix: correct viewPath error in LoginWidget (niciz) - Enh: possibility to call all the api endpoints with either id or username or email (liviuk2) - Fix: use configured User model in SecurityController 2FA confirmation (jussiaho) +- Enh: possibility to get user ids from roles recursively (mp1509) ## 1.6.0 January 9, 2023 diff --git a/src/User/Component/AuthDbManagerComponent.php b/src/User/Component/AuthDbManagerComponent.php index 49f76864..11e9d4f2 100644 --- a/src/User/Component/AuthDbManagerComponent.php +++ b/src/User/Component/AuthDbManagerComponent.php @@ -12,8 +12,11 @@ namespace Da\User\Component; use Da\User\Contracts\AuthManagerInterface; +use yii\base\InvalidArgumentException; +use yii\db\Expression; use yii\db\Query; use yii\rbac\DbManager; +use yii\rbac\Role; class AuthDbManagerComponent extends DbManager implements AuthManagerInterface { @@ -80,4 +83,74 @@ public function getItem($name) { return parent::getItem($name); } + + + /** + * @inheritdoc + * @param bool $recursive + * @override to add possibility to get the ids of users assigned to roles that are parents of the given one. + * @since 1.6.1 + */ + public function getUserIdsByRole($roleName, $recursive = false) + { + if(!$recursive || empty($roleName)) { + return parent::getUserIdsByRole($roleName); + } + + $roles = $this->getParentRoles($roleName); + $userIds = array_reduce($roles, function ($ids, $role) { + $roleIds = parent::getUserIdsByRole($role->name); + return array_merge($ids, $roleIds); + }, []); + return array_unique($userIds); + } + + + /** + * Returns parent roles of the role specified. Depth isn't limited. + * @param string $roleName name of the role to file parent roles for + * @return Role[] Child roles. The array is indexed by the role names. + * First element is an instance of the parent Role itself. + * @throws \yii\base\InvalidParamException if Role was not found that are getting by $roleName + * @since 1.6.1 + */ + public function getParentRoles($roleName) + { + $role = $this->getRole($roleName); + + if ($role === null) { + throw new InvalidArgumentException("Role \"$roleName\" not found."); + } + + $result = []; + $this->getParentsRecursive($roleName, $result); + + $roles = [$roleName => $role]; + + $roles += $result; + + return $roles; + } + + /** + * Recursively finds all parents and grandparents of the specified item. + * @param string $name the name of the item whose children are to be looked for. + * @param array $result the children and grand children (in array keys) + * @since 1.6.1 + */ + protected function getParentsRecursive($name, &$result = []) + { + $query = (new Query()) + ->select(['name', 'type', 'description', 'rule_name', 'data', 'created_at', 'updated_at']) + ->from([$this->itemTable, $this->itemChildTable]) + ->where(['child' => $name, 'name' => new Expression('[[parent]]')]); + + foreach ($query->all($this->db) as $row) { + if(isset($result[$row['name']])) { + continue; + } + $result[$row['name']] = $this->populateItem($row); + $this->getParentsRecursive($row['name'], $result); + } + } } From 38ad4d188a918259a71ac83ed0784a16ba50197d Mon Sep 17 00:00:00 2001 From: Lorenzo Milesi Date: Tue, 4 Apr 2023 08:48:42 +0200 Subject: [PATCH 13/14] Update changelog for 1.6.1 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 396a06ab..46f0c762 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # CHANGELOG -## dev +## 1.6.1 March 4th, 2023 - Fix: use correct password recovery url in welcome mail and add functionality to plain text version of the mail (@eluhr) - Fix: correct viewPath error in LoginWidget (niciz) From 14e3c11c4fe47187bbfe6e3c0451424e44126f49 Mon Sep 17 00:00:00 2001 From: Marco Piazza Date: Wed, 5 Apr 2023 16:37:50 +0200 Subject: [PATCH 14/14] Added possibility to limit the depth of the recursion when getting user ids from roles --- CHANGELOG.md | 4 ++++ src/User/Component/AuthDbManagerComponent.php | 20 +++++++++++++------ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 46f0c762..6eb79d23 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGELOG +## dev + +- Enh: possibility to limit the depth of the recursion when getting user ids from roles (mp1509) + ## 1.6.1 March 4th, 2023 - Fix: use correct password recovery url in welcome mail and add functionality to plain text version of the mail (@eluhr) diff --git a/src/User/Component/AuthDbManagerComponent.php b/src/User/Component/AuthDbManagerComponent.php index 11e9d4f2..b2ddf75c 100644 --- a/src/User/Component/AuthDbManagerComponent.php +++ b/src/User/Component/AuthDbManagerComponent.php @@ -87,7 +87,8 @@ public function getItem($name) /** * @inheritdoc - * @param bool $recursive + * @param bool|integer $recursive If the roles are to be calculated recursively. If an integer is passed it will limit the depth of the + * recursion to the given number (e.g. 1 would also get ids from users assigned to only the parents of the given role). * @override to add possibility to get the ids of users assigned to roles that are parents of the given one. * @since 1.6.1 */ @@ -97,7 +98,7 @@ public function getUserIdsByRole($roleName, $recursive = false) return parent::getUserIdsByRole($roleName); } - $roles = $this->getParentRoles($roleName); + $roles = $this->getParentRoles($roleName, $recursive === true ? null : $recursive); $userIds = array_reduce($roles, function ($ids, $role) { $roleIds = parent::getUserIdsByRole($role->name); return array_merge($ids, $roleIds); @@ -109,12 +110,13 @@ public function getUserIdsByRole($roleName, $recursive = false) /** * Returns parent roles of the role specified. Depth isn't limited. * @param string $roleName name of the role to file parent roles for + * @param null|integer $depth The depth to which to search for parents recursively, if null it won't have any limit. Defaults to `null`. * @return Role[] Child roles. The array is indexed by the role names. * First element is an instance of the parent Role itself. * @throws \yii\base\InvalidParamException if Role was not found that are getting by $roleName * @since 1.6.1 */ - public function getParentRoles($roleName) + public function getParentRoles($roleName, $depth = null) { $role = $this->getRole($roleName); @@ -123,7 +125,7 @@ public function getParentRoles($roleName) } $result = []; - $this->getParentsRecursive($roleName, $result); + $this->getParentsRecursive($roleName, $result, $depth); $roles = [$roleName => $role]; @@ -136,10 +138,12 @@ public function getParentRoles($roleName) * Recursively finds all parents and grandparents of the specified item. * @param string $name the name of the item whose children are to be looked for. * @param array $result the children and grand children (in array keys) + * @param null|integer $depth The depth to which to search recursively, if null it won't have any limit. Defaults to `null`. * @since 1.6.1 */ - protected function getParentsRecursive($name, &$result = []) + protected function getParentsRecursive($name, &$result = [], &$depth = null) { + $depth -= 1; // Cannot use -- because we have to cast `null` to integer $query = (new Query()) ->select(['name', 'type', 'description', 'rule_name', 'data', 'created_at', 'updated_at']) ->from([$this->itemTable, $this->itemChildTable]) @@ -150,7 +154,11 @@ protected function getParentsRecursive($name, &$result = []) continue; } $result[$row['name']] = $this->populateItem($row); - $this->getParentsRecursive($row['name'], $result); + // If we have yet to reach the maximum depth, we continue. + // If $depth was orginally `null` it'd start from -1 so decrements will never make reach 0 + if($depth !== 0) { + $this->getParentsRecursive($row['name'], $result); + } } } }