Skip to content

Commit

Permalink
Added DispatchesOn attribute
Browse files Browse the repository at this point in the history
  • Loading branch information
WendellAdriel committed May 6, 2024
1 parent 9133475 commit ae98c5e
Show file tree
Hide file tree
Showing 7 changed files with 158 additions and 0 deletions.
20 changes: 20 additions & 0 deletions src/Models/Attributes/DispatchesOn.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

namespace WendellAdriel\Virtue\Models\Attributes;

use Attribute;

#[Attribute(Attribute::TARGET_CLASS | Attribute::IS_REPEATABLE)]
final class DispatchesOn
{
/**
* @param class-string $class
*/
public function __construct(
public string $event,
public string $class,
) {
}
}
25 changes: 25 additions & 0 deletions src/Models/Concerns/Virtue.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use ReflectionClass;
use WendellAdriel\Virtue\Models\Attributes\Cast;
use WendellAdriel\Virtue\Models\Attributes\Database;
use WendellAdriel\Virtue\Models\Attributes\DispatchesOn;
use WendellAdriel\Virtue\Models\Attributes\Fillable;
use WendellAdriel\Virtue\Models\Attributes\Hidden;
use WendellAdriel\Virtue\Models\Attributes\PrimaryKey;
Expand All @@ -26,6 +27,7 @@ public function initializeVirtue(): void
$this->applyFillable();
$this->applyHidden();
$this->applyCasts();
$this->handleEvents();

self::handleRelationsKeys($this);
}
Expand Down Expand Up @@ -119,6 +121,29 @@ private function applyCasts(): void
}
}

private function handleEvents(): void
{
$dispatchesAttributes = $this->resolveMultipleAttributes(DispatchesOn::class);
if ($dispatchesAttributes->isEmpty()) {
return;
}

$eventsArray = [];
foreach ($dispatchesAttributes as $dispatchesAttribute) {
/** @var DispatchesOn $attribute */
$attribute = $dispatchesAttribute->newInstance();
if (! in_array($attribute->event, $this->getObservableEvents())) {
continue;
}

$eventsArray[$attribute->event] = $attribute->class;
}

if ($eventsArray !== []) {
$this->dispatchesEvents = $eventsArray;
}
}

/**
* @param class-string $attributeClass
*/
Expand Down
19 changes: 19 additions & 0 deletions tests/Datasets/UserCreated.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

declare(strict_types=1);

namespace Tests\Datasets;

use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

final class UserCreated
{
use Dispatchable;
use SerializesModels;

public function __construct(
public UserEvents $user,
) {
}
}
19 changes: 19 additions & 0 deletions tests/Datasets/UserDeleted.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

declare(strict_types=1);

namespace Tests\Datasets;

use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

final class UserDeleted
{
use Dispatchable;
use SerializesModels;

public function __construct(
public UserEvents $user,
) {
}
}
28 changes: 28 additions & 0 deletions tests/Datasets/UserEvents.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace Tests\Datasets;

use Illuminate\Database\Eloquent\Model;
use WendellAdriel\Virtue\Models\Attributes\Database;
use WendellAdriel\Virtue\Models\Attributes\DispatchesOn;
use WendellAdriel\Virtue\Models\Attributes\Fillable;
use WendellAdriel\Virtue\Models\Attributes\PrimaryKey;
use WendellAdriel\Virtue\Models\Concerns\Virtue;

#[Fillable([
'id',
'name',
'email',
'password',
])]
#[Database(table: 'users')]
#[PrimaryKey(incrementing: false)]
#[DispatchesOn(event: 'created', class: UserCreated::class)]
#[DispatchesOn(event: 'updated', class: UserUpdated::class)]
#[DispatchesOn(event: 'deleted', class: UserDeleted::class)]
final class UserEvents extends Model
{
use Virtue;
}
19 changes: 19 additions & 0 deletions tests/Datasets/UserUpdated.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

declare(strict_types=1);

namespace Tests\Datasets;

use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

final class UserUpdated
{
use Dispatchable;
use SerializesModels;

public function __construct(
public UserEvents $user,
) {
}
}
28 changes: 28 additions & 0 deletions tests/Feature/DispatchesOnTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

use Illuminate\Support\Facades\Event;
use Tests\Datasets\UserCreated;
use Tests\Datasets\UserDeleted;
use Tests\Datasets\UserEvents;
use Tests\Datasets\UserUpdated;

it('dispatches events', function () {
Event::fake();

$user = UserEvents::create([
'id' => 10,
'name' => fake()->name,
'email' => fake()->unique()->safeEmail,
'password' => 's3Cr3t@!!!',
]);
Event::assertDispatched(UserCreated::class);

$user->name = fake()->name;
$user->save();
Event::assertDispatched(UserUpdated::class);

$user->delete();
Event::assertDispatched(UserDeleted::class);
});

0 comments on commit ae98c5e

Please sign in to comment.