From 7945f047c60cd0074103b1cbf565302a58492507 Mon Sep 17 00:00:00 2001 From: michalsn Date: Tue, 29 Aug 2023 17:35:06 +0200 Subject: [PATCH 1/3] fix: UserModel::assignIdentities() always produces a DB query --- src/Entities/User.php | 5 +++++ src/Models/UserModel.php | 15 +++++++++------ tests/Unit/UserTest.php | 25 +++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 6 deletions(-) diff --git a/src/Entities/User.php b/src/Entities/User.php index 00a420fe7..2c966e424 100644 --- a/src/Entities/User.php +++ b/src/Entities/User.php @@ -117,6 +117,11 @@ public function getIdentities(string $type = 'all'): array return $identities; } + public function setIdentities(array $identities): void + { + $this->identities = $identities; + } + /** * Creates a new identity for this user with an email/password * combination. diff --git a/src/Models/UserModel.php b/src/Models/UserModel.php index ab5eb49c2..1bae3a03a 100644 --- a/src/Models/UserModel.php +++ b/src/Models/UserModel.php @@ -114,6 +114,7 @@ protected function fetchIdentities(array $data): array private function assignIdentities(array $data, array $identities): array { $mappedUsers = []; + $userIdentities = []; $users = $data['singleton'] ? [$data['data']] : $data['data']; @@ -122,15 +123,17 @@ private function assignIdentities(array $data, array $identities): array } unset($users); - // Now assign the identities to the user + // Now group the identities by user foreach ($identities as $identity) { - $userId = $identity->user_id; - - $newIdentities = $mappedUsers[$userId]->identities; - $newIdentities[] = $identity; + $userIdentities[$identity->user_id][] = $identity; + } + unset($identities); - $mappedUsers[$userId]->identities = $newIdentities; + // Now assign the identities to the user + foreach ($userIdentities as $userId => $identityArray) { + $mappedUsers[$userId]->identities = $identityArray; } + unset($userIdentities); return $mappedUsers; } diff --git a/tests/Unit/UserTest.php b/tests/Unit/UserTest.php index b10860ebc..fd7584416 100644 --- a/tests/Unit/UserTest.php +++ b/tests/Unit/UserTest.php @@ -87,6 +87,31 @@ public function testModelFindByIdWithIdentities(): void $this->assertCount(2, $user->identities); } + public function testModelFindAllWithIdentitiesWhereInQuery(): void + { + fake(UserIdentityModel::class, ['user_id' => $this->user->id, 'type' => 'password']); + fake(UserIdentityModel::class, ['user_id' => $this->user->id, 'type' => 'access_token']); + + // Grab the user again, using the model's identity helper + $users = model(UserModel::class)->withIdentities()->findAll(); + + $identities = 0; + + foreach ($users as $user) { + if ($user->id !== $this->user->id) { + continue; + } + + $identities = $user->identities; + + // Check the last query and see if a proper type of query was used + $query = (string) model(UserModel::class)->getLastQuery(); + $this->assertMatchesRegularExpression('/WHERE\s+.*\s+IN\s+\([^)]+\)/i', $query, 'Identities were not obtained with the single query (missing "WHERE ... IN" condition)'); + } + + $this->assertCount(2, $identities); + } + public function testModelFindByIdWithIdentitiesUserNotExists(): void { $user = model(UserModel::class)->where('active', 0)->withIdentities()->findById(1); From 8e854c859fd988e41f367a5b8a9db0f95ac2ca4a Mon Sep 17 00:00:00 2001 From: michalsn Date: Tue, 29 Aug 2023 17:58:29 +0200 Subject: [PATCH 2/3] code style fixes --- phpstan.neon.dist | 3 ++- src/Models/UserModel.php | 2 +- tests/Unit/UserTest.php | 6 +++++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 8c77114cc..b4186e33f 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -12,7 +12,8 @@ parameters: ignoreErrors: - '#Call to an undefined method CodeIgniter\\Database\\ConnectionInterface::[A-Za-z].+\(\)#' - '#Cannot access property [\$a-z_]+ on (array|object)#' - - + - '#Call to an undefined method CodeIgniter\\Shield\\Models\\UserModel::getLastQuery\(\)#' + - message: '#Call to deprecated function random_string\(\):#' paths: - src/Authentication/Actions/Email2FA.php diff --git a/src/Models/UserModel.php b/src/Models/UserModel.php index 1bae3a03a..3c6f5f518 100644 --- a/src/Models/UserModel.php +++ b/src/Models/UserModel.php @@ -113,7 +113,7 @@ protected function fetchIdentities(array $data): array */ private function assignIdentities(array $data, array $identities): array { - $mappedUsers = []; + $mappedUsers = []; $userIdentities = []; $users = $data['singleton'] ? [$data['data']] : $data['data']; diff --git a/tests/Unit/UserTest.php b/tests/Unit/UserTest.php index fd7584416..55caab6e3 100644 --- a/tests/Unit/UserTest.php +++ b/tests/Unit/UserTest.php @@ -106,7 +106,11 @@ public function testModelFindAllWithIdentitiesWhereInQuery(): void // Check the last query and see if a proper type of query was used $query = (string) model(UserModel::class)->getLastQuery(); - $this->assertMatchesRegularExpression('/WHERE\s+.*\s+IN\s+\([^)]+\)/i', $query, 'Identities were not obtained with the single query (missing "WHERE ... IN" condition)'); + $this->assertMatchesRegularExpression( + '/WHERE\s+.*\s+IN\s+\([^)]+\)/i', + $query, + 'Identities were not obtained with the single query (missing "WHERE ... IN" condition)' + ); } $this->assertCount(2, $identities); From e3f4d8f750446bb46f374e23e024b1640623482a Mon Sep 17 00:00:00 2001 From: Michal Sniatala Date: Tue, 5 Sep 2023 07:50:00 +0200 Subject: [PATCH 3/3] Apply suggestions from code review Co-authored-by: kenjis --- tests/Unit/UserTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/UserTest.php b/tests/Unit/UserTest.php index 55caab6e3..784800063 100644 --- a/tests/Unit/UserTest.php +++ b/tests/Unit/UserTest.php @@ -95,7 +95,7 @@ public function testModelFindAllWithIdentitiesWhereInQuery(): void // Grab the user again, using the model's identity helper $users = model(UserModel::class)->withIdentities()->findAll(); - $identities = 0; + $identities = []; foreach ($users as $user) { if ($user->id !== $this->user->id) {