From 4b96fce692926ba02a3c99b61024c20e1b165734 Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Thu, 6 Oct 2022 08:49:19 -0400 Subject: [PATCH 1/4] Implement dispatch method for firing multiple events by name --- src/Models/Concerns/HasEvents.php | 37 +++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/src/Models/Concerns/HasEvents.php b/src/Models/Concerns/HasEvents.php index 1ce70834..7e87bd79 100644 --- a/src/Models/Concerns/HasEvents.php +++ b/src/Models/Concerns/HasEvents.php @@ -3,8 +3,11 @@ namespace LdapRecord\Models\Concerns; use Closure; +use LdapRecord\Models\Events; use LdapRecord\Events\NullDispatcher; use LdapRecord\Models\Events\Event; +use LdapRecord\Support\Arr; +use LdapRecord\Support\Str; /** @mixin \LdapRecord\Models\Model */ trait HasEvents @@ -38,7 +41,37 @@ protected static function withoutEvents(Closure $callback) } /** - * Fires the specified model event. + * Dispatch the given model events. + * + * @param string|array $events + * @param array $args + * + * @return void + */ + protected function dispatch($events, array $args = []) + { + foreach (Arr::wrap($events) as $name) { + $this->fireCustomModelEvent($name, $args); + } + } + + /** + * Fire a custom model event. + * + * @param string $name + * @param array $args + * + * @return mixed + */ + protected function fireCustomModelEvent($name, array $args = []) + { + $event = implode('\\', [Events::class, ucfirst($name)]); + + return $this->fireModelEvent(new $event($this, ...$args)); + } + + /** + * Fire a model event. * * @param Event $event * @@ -50,7 +83,7 @@ protected function fireModelEvent(Event $event) } /** - * Listens to a model event. + * Listen to a model event. * * @param string $event * @param Closure $listener From 7d1336ddc067d90298b9944a4750a547ed9fabe4 Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Thu, 6 Oct 2022 08:50:51 -0400 Subject: [PATCH 2/4] Dispatch model events when creating/updating/deleting attributes --- src/Models/Model.php | 63 +++++++++++++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 18 deletions(-) diff --git a/src/Models/Model.php b/src/Models/Model.php index 022f7048..50bf71ba 100644 --- a/src/Models/Model.php +++ b/src/Models/Model.php @@ -3,6 +3,7 @@ namespace LdapRecord\Models; use ArrayAccess; +use Closure; use Illuminate\Contracts\Support\Arrayable; use InvalidArgumentException; use JsonSerializable; @@ -1127,11 +1128,11 @@ public function save(array $attributes = []) { $this->fill($attributes); - $this->fireModelEvent(new Events\Saving($this)); + $this->dispatch('saving'); $this->exists ? $this->performUpdate() : $this->performInsert(); - $this->fireModelEvent(new Events\Saved($this)); + $this->dispatch('saved'); $this->modifications = []; @@ -1163,7 +1164,7 @@ protected function performInsert() $this->setDn($this->getCreatableDn()); } - $this->fireModelEvent(new Events\Creating($this)); + $this->dispatch('creating'); // Here we perform the insert of new object in the directory, // but filter out any empty attributes before sending them @@ -1171,7 +1172,7 @@ protected function performInsert() // attributes have been given empty or null values. $query->insert($this->getDn(), array_filter($this->getAttributes())); - $this->fireModelEvent(new Events\Created($this)); + $this->dispatch('created'); $this->syncOriginal(); @@ -1193,11 +1194,11 @@ protected function performUpdate() return; } - $this->fireModelEvent(new Events\Updating($this)); + $this->dispatch('updating'); $this->newQuery()->update($this->dn, $modifications); - $this->fireModelEvent(new Events\Updated($this)); + $this->dispatch('updated'); $this->syncOriginal(); } @@ -1233,11 +1234,15 @@ public static function create(array $attributes = []) */ public function createAttribute($attribute, $value) { - $this->requireExistence(); + $this->assertExists(); + + $this->dispatch(['saving', 'updating']); $this->newQuery()->insertAttributes($this->dn, [$attribute => (array) $value]); $this->addAttributeValue($attribute, $value); + + $this->dispatch(['updated', 'saved']); } /** @@ -1252,7 +1257,7 @@ public function createAttribute($attribute, $value) */ public function update(array $attributes = []) { - $this->requireExistence(); + $this->assertExists(); $this->save($attributes); } @@ -1270,11 +1275,15 @@ public function update(array $attributes = []) */ public function updateAttribute($attribute, $value) { - $this->requireExistence(); + $this->assertExists(); + + $this->dispatch(['saving', 'updating']); $this->newQuery()->updateAttributes($this->dn, [$attribute => (array) $value]); $this->addAttributeValue($attribute, $value); + + $this->dispatch(['updated', 'saved']); } /** @@ -1323,9 +1332,9 @@ public static function destroy($dns, $recursive = false) */ public function delete($recursive = false) { - $this->requireExistence(); + $this->assertExists(); - $this->fireModelEvent(new Events\Deleting($this)); + $this->dispatch('deleting'); if ($recursive) { $this->deleteLeafNodes(); @@ -1338,7 +1347,7 @@ public function delete($recursive = false) // developers can hook in and run further operations. $this->exists = false; - $this->fireModelEvent(new Events\Deleted($this)); + $this->dispatch('deleted'); } /** @@ -1378,11 +1387,13 @@ protected function deleteLeafNodes() */ public function deleteAttribute($attributes) { - $this->requireExistence(); + $this->assertExists(); $attributes = $this->makeDeletableAttributes($attributes); - $this->newQuery()->deleteAttributes($this->dn, $attributes); + $this->dispatch(['saving', 'updating']); + + $this->newQuery()->deleteAttributes($this->dn, $attributes); foreach ($attributes as $attribute => $value) { // If the attribute value is empty, we can assume the @@ -1401,6 +1412,8 @@ public function deleteAttribute($attributes) } } + $this->dispatch(['updated', 'saved']); + $this->syncOriginal(); } @@ -1440,7 +1453,7 @@ protected function makeDeletableAttributes($attributes) */ public function move($newParentDn, $deleteOldRdn = true) { - $this->requireExistence(); + $this->assertExists(); if (! $rdn = $this->getRdn()) { throw new UnexpectedValueException('Current model does not contain an RDN to move.'); @@ -1463,7 +1476,7 @@ public function move($newParentDn, $deleteOldRdn = true) */ public function rename($rdn, $newParentDn = null, $deleteOldRdn = true) { - $this->requireExistence(); + $this->assertExists(); if ($newParentDn instanceof self) { $newParentDn = $newParentDn->getDn(); @@ -1490,7 +1503,7 @@ public function rename($rdn, $newParentDn = null, $deleteOldRdn = true) $rdn = $this->getUpdateableRdn($rdn); } - $this->fireModelEvent(new Renaming($this, $rdn, $newParentDn)); + $this->dispatch('renaming', [$rdn, $newParentDn]); $this->newQuery()->rename($this->dn, $rdn, $newParentDn, $deleteOldRdn); @@ -1510,7 +1523,7 @@ public function rename($rdn, $newParentDn = null, $deleteOldRdn = true) = $this->original[$modelNameAttribute] = [reset($map[$modelNameAttribute])]; - $this->fireModelEvent(new Renamed($this)); + $this->dispatch('renamed'); $this->wasRecentlyRenamed = true; } @@ -1617,12 +1630,26 @@ protected function buildModificationsFromDirty() /** * Throw an exception if the model does not exist. + * + * @deprecated * * @return void * * @throws ModelDoesNotExistException */ protected function requireExistence() + { + return $this->assertExists(); + } + + /** + * Throw an exception if the model does not exist. + * + * @return void + * + * @throws ModelDoesNotExistException + */ + protected function assertExists() { if (! $this->exists || is_null($this->dn)) { throw ModelDoesNotExistException::forModel($this); From 7d2c5f290bc4e9f1fa77be1631a8471653f1020f Mon Sep 17 00:00:00 2001 From: StyleCI Bot Date: Thu, 6 Oct 2022 12:51:09 +0000 Subject: [PATCH 3/4] Apply fixes from StyleCI [ci skip] [skip ci] --- src/Models/Concerns/HasEvents.php | 25 ++++++++++++------------- src/Models/Model.php | 5 ++--- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/src/Models/Concerns/HasEvents.php b/src/Models/Concerns/HasEvents.php index 7e87bd79..2843dd1d 100644 --- a/src/Models/Concerns/HasEvents.php +++ b/src/Models/Concerns/HasEvents.php @@ -3,11 +3,10 @@ namespace LdapRecord\Models\Concerns; use Closure; -use LdapRecord\Models\Events; use LdapRecord\Events\NullDispatcher; +use LdapRecord\Models\Events; use LdapRecord\Models\Events\Event; use LdapRecord\Support\Arr; -use LdapRecord\Support\Str; /** @mixin \LdapRecord\Models\Model */ trait HasEvents @@ -42,26 +41,26 @@ protected static function withoutEvents(Closure $callback) /** * Dispatch the given model events. - * - * @param string|array $events - * @param array $args - * - * @return void + * + * @param string|array $events + * @param array $args + * + * @return void */ protected function dispatch($events, array $args = []) { foreach (Arr::wrap($events) as $name) { - $this->fireCustomModelEvent($name, $args); + $this->fireCustomModelEvent($name, $args); } } /** * Fire a custom model event. - * - * @param string $name - * @param array $args - * - * @return mixed + * + * @param string $name + * @param array $args + * + * @return mixed */ protected function fireCustomModelEvent($name, array $args = []) { diff --git a/src/Models/Model.php b/src/Models/Model.php index 50bf71ba..8718e4e3 100644 --- a/src/Models/Model.php +++ b/src/Models/Model.php @@ -3,7 +3,6 @@ namespace LdapRecord\Models; use ArrayAccess; -use Closure; use Illuminate\Contracts\Support\Arrayable; use InvalidArgumentException; use JsonSerializable; @@ -1393,7 +1392,7 @@ public function deleteAttribute($attributes) $this->dispatch(['saving', 'updating']); - $this->newQuery()->deleteAttributes($this->dn, $attributes); + $this->newQuery()->deleteAttributes($this->dn, $attributes); foreach ($attributes as $attribute => $value) { // If the attribute value is empty, we can assume the @@ -1630,7 +1629,7 @@ protected function buildModificationsFromDirty() /** * Throw an exception if the model does not exist. - * + * * @deprecated * * @return void From 7897cab9427a758032e32e75b5d22a938b90b194 Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Thu, 6 Oct 2022 08:55:13 -0400 Subject: [PATCH 4/4] Suppress Psalm UndefinedClass --- src/Models/Concerns/HasEvents.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Models/Concerns/HasEvents.php b/src/Models/Concerns/HasEvents.php index 2843dd1d..7c89cfe5 100644 --- a/src/Models/Concerns/HasEvents.php +++ b/src/Models/Concerns/HasEvents.php @@ -64,6 +64,7 @@ protected function dispatch($events, array $args = []) */ protected function fireCustomModelEvent($name, array $args = []) { + /** @psalm-suppress UndefinedClass */ $event = implode('\\', [Events::class, ucfirst($name)]); return $this->fireModelEvent(new $event($this, ...$args));