Skip to content

Commit 51bb61b

Browse files
committed
feat: insert(), update(), save() can save Email Identity with Model Events
Remove saveWithEmailIdentity().
1 parent 9487136 commit 51bb61b

File tree

4 files changed

+141
-37
lines changed

4 files changed

+141
-37
lines changed

src/Models/UserModel.php

Lines changed: 75 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,20 @@ class UserModel extends Model
2929
];
3030
protected $useTimestamps = true;
3131
protected $afterFind = ['fetchIdentities'];
32+
protected $afterInsert = ['saveEmailIdentity'];
33+
protected $afterUpdate = ['saveEmailIdentity'];
3234

3335
/**
3436
* Whether identity records should be included
3537
* when user records are fetched from the database.
3638
*/
3739
protected bool $fetchIdentities = false;
3840

41+
/**
42+
* Save the User for afterInsert and afterUpdate
43+
*/
44+
protected ?User $tempUser = null;
45+
3946
/**
4047
* Mark the next find* query to include identities
4148
*
@@ -53,7 +60,7 @@ public function withIdentities(): self
5360
* returned from a find* method. Called
5461
* automatically when $this->fetchIdentities == true
5562
*
56-
* Model event callback called `afterFind`.
63+
* Model event callback called by `afterFind`.
5764
*/
5865
protected function fetchIdentities(array $data): array
5966
{
@@ -185,71 +192,107 @@ public function activate(User $user): void
185192
{
186193
$user->active = true;
187194

188-
$this->saveWithEmailIdentity($user);
195+
$this->save($user);
189196
}
190197

191198
/**
192-
* Override the BaseModel's `save()` method to allow
193-
* updating of user email, password, or password_hash fields
194-
* if they've been modified.
195-
*
196199
* @param User $data
197200
*
198201
* @throws ValidationException
202+
*
203+
* @retrun true|int|string Insert ID if $returnID is true
199204
*/
200-
public function save($data): bool
205+
public function insert($data = null, bool $returnID = true)
201206
{
202207
assert($data instanceof User);
203208

204-
$this->saveWithEmailIdentity($data);
209+
$this->tempUser = $data;
205210

206-
return true;
211+
$result = parent::insert($data, $returnID);
212+
213+
$this->checkQueryReturn($result);
214+
215+
return $returnID ? $this->insertID : $result;
207216
}
208217

209218
/**
210-
* Save User and its Email Identity (email, password, or password_hash fields)
211-
* if they've been modified.
219+
* @param array|int|string|null $id
220+
* @param User $data
212221
*
213222
* @throws ValidationException
214223
*/
215-
public function saveWithEmailIdentity(User $data): void
224+
public function update($id = null, $data = null): bool
216225
{
226+
assert($data instanceof User);
227+
228+
$this->tempUser = $data;
229+
217230
try {
218231
/** @throws DataException */
219-
$result = parent::save($data);
232+
$result = parent::update($id, $data);
220233
} catch (DataException $e) {
221234
$messages = [
222-
lang('Database.emptyDataset', ['insert']),
223235
lang('Database.emptyDataset', ['update']),
224236
];
237+
225238
if (in_array($e->getMessage(), $messages, true)) {
226-
// Save updated email identity
227-
$user = $data;
228-
$user->saveEmailIdentity();
239+
$this->tempUser->saveEmailIdentity();
229240

230-
return;
241+
return true;
231242
}
232243

233244
throw $e;
234245
}
235246

236-
if ($result) {
237-
if ($data->id === null) {
238-
// Insert
239-
/** @var User $user */
240-
$user = $this->find($this->db->insertID());
241-
242-
$user->email = $data->email ?? null;
243-
$user->password = $data->password ?? '';
244-
$user->password_hash = $data->password_hash ?? '';
245-
} else {
246-
// Update
247-
$user = $data;
248-
}
247+
$this->checkQueryReturn($result);
248+
249+
return true;
250+
}
251+
252+
/**
253+
* Override the BaseModel's `save()` method to allow
254+
* updating of user email, password, or password_hash fields
255+
* if they've been modified.
256+
*
257+
* @param User $data
258+
*
259+
* @throws ValidationException
260+
*/
261+
public function save($data): bool
262+
{
263+
assert($data instanceof User);
264+
265+
$result = parent::save($data);
266+
267+
$this->checkQueryReturn($result);
268+
269+
return true;
270+
}
271+
272+
/**
273+
* Save Email Identity
274+
*
275+
* Model event callback called by `afterInsert` and `afterUpdate`.
276+
*/
277+
protected function saveEmailIdentity(array $data): array
278+
{
279+
// Insert
280+
if ($this->tempUser->id === null) {
281+
/** @var User $user */
282+
$user = $this->find($this->db->insertID());
283+
284+
$user->email = $this->tempUser->email ?? '';
285+
$user->password = $this->tempUser->password ?? '';
286+
$user->password_hash = $this->tempUser->password_hash ?? '';
249287

250288
$user->saveEmailIdentity();
289+
290+
return $data;
251291
}
252292

253-
$this->checkQueryReturn($result);
293+
// Update
294+
$this->tempUser->saveEmailIdentity();
295+
296+
return $data;
254297
}
255298
}

tests/Controllers/ActionsTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ public function testEmailActivateVerify(): void
247247

248248
$this->user->active = false;
249249
$model = auth()->getProvider();
250-
$model->saveWithEmailIdentity($this->user);
250+
$model->save($this->user);
251251

252252
$result = $this->actingAs($this->user, true)
253253
->withSession($this->getSessionUserInfo(EmailActivator::class))

tests/Unit/UserModelTest.php

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,25 @@ public function testSaveInsertUser(): void
4141
]);
4242
}
4343

44+
public function testInsertUser(): void
45+
{
46+
$users = $this->createUserModel();
47+
48+
$user = $this->createNewUser();
49+
50+
$users->insert($user);
51+
52+
$user = $users->findByCredentials(['email' => '[email protected]']);
53+
$this->seeInDatabase('auth_identities', [
54+
'user_id' => $user->id,
55+
'secret' => '[email protected]',
56+
]);
57+
$this->seeInDatabase('users', [
58+
'id' => $user->id,
59+
'active' => 0,
60+
]);
61+
}
62+
4463
private function createNewUser(): User
4564
{
4665
$user = new User();
@@ -76,6 +95,30 @@ public function testSaveUpdateUserWithUserDataToUpdate(): void
7695
]);
7796
}
7897

98+
public function testUpdateUserWithUserDataToUpdate(): void
99+
{
100+
$users = $this->createUserModel();
101+
$user = $this->createNewUser();
102+
$users->save($user);
103+
104+
$user = $users->findByCredentials(['email' => '[email protected]']);
105+
106+
$user->username = 'bar';
107+
$user->email = '[email protected]';
108+
$user->active = 1;
109+
110+
$users->update(null, $user);
111+
112+
$this->seeInDatabase('auth_identities', [
113+
'user_id' => $user->id,
114+
'secret' => '[email protected]',
115+
]);
116+
$this->seeInDatabase('users', [
117+
'id' => $user->id,
118+
'active' => 1,
119+
]);
120+
}
121+
79122
public function testSaveUpdateUserWithNoUserDataToUpdate(): void
80123
{
81124
$users = $this->createUserModel();
@@ -86,7 +129,25 @@ public function testSaveUpdateUserWithNoUserDataToUpdate(): void
86129

87130
$user->email = '[email protected]';
88131

89-
$users->saveWithEmailIdentity($user);
132+
$users->save($user);
133+
134+
$this->seeInDatabase('auth_identities', [
135+
'user_id' => $user->id,
136+
'secret' => '[email protected]',
137+
]);
138+
}
139+
140+
public function testUpdateUserWithNoUserDataToUpdate(): void
141+
{
142+
$users = $this->createUserModel();
143+
$user = $this->createNewUser();
144+
$users->save($user);
145+
146+
$user = $users->findByCredentials(['email' => '[email protected]']);
147+
148+
$user->email = '[email protected]';
149+
150+
$users->update(null, $user);
90151

91152
$this->seeInDatabase('auth_identities', [
92153
'user_id' => $user->id,

tests/Unit/UserTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ public function testUpdateEmail(): void
112112
$this->user->active = 0;
113113

114114
$users = model(UserModel::class);
115-
$users->saveWithEmailIdentity($this->user);
115+
$users->save($this->user);
116116

117117
$user = $users->find($this->user->id);
118118

@@ -134,7 +134,7 @@ public function testUpdatePassword(): void
134134
$this->user->active = 0;
135135

136136
$users = model(UserModel::class);
137-
$users->saveWithEmailIdentity($this->user);
137+
$users->save($this->user);
138138

139139
$user = $users->find($this->user->id);
140140

@@ -153,7 +153,7 @@ public function testUpdatePasswordHash(): void
153153
$this->user->active = 0;
154154

155155
$users = model(UserModel::class);
156-
$users->saveWithEmailIdentity($this->user);
156+
$users->save($this->user);
157157

158158
$user = $users->find($this->user->id);
159159

0 commit comments

Comments
 (0)