attribute-events icon indicating copy to clipboard operation
attribute-events copied to clipboard

Package doesn't support PHP Enums

Open radmen opened this issue 2 years ago • 1 comments

I see that the package supports castables however, it doesn't support enums.

Here's example model:

<?php

namespace App\Models;

use App\Enums\OrderFinancialStatus;
use App\Events\Orders\OrderCreated;
use App\Events\Orders\OrderPaid;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Kleemans\AttributeEvents;

class Order extends Model
{
    use HasFactory,
        AttributeEvents;

    protected $dispatchesEvents = [
        'created' => OrderCreated::class,
        'status:financial_status' => OrderPaid::class,
    ];

    protected $casts = [
        'financial_status' => OrderFinancialStatus::class,
    ];
}

When financial_status is changed to paid, the package fails with the following error:

1) Tests\Feature\Models\OrderTest::test_it_dispatched_order_paid_event
Error: Object of class App\Enums\OrderFinancialStatus could not be converted to string

/app/vendor/jpkleemans/attribute-events/src/AttributeEvents.php:64
/app/vendor/jpkleemans/attribute-events/src/AttributeEvents.php:15
/app/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php:421
/app/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php:249
/app/vendor/laravel/framework/src/Illuminate/Support/Testing/Fakes/EventFake.php:262
/app/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasEvents.php:189
/app/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:1078
/app/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:989
/app/tests/Feature/Models/OrderTest.php:33

Here's the test case I used:

    public function test_it_dispatched_order_paid_event()
    {
        Event::fake([
            OrderPaid::class,
        ]);

        $order = Order::withoutEvents(fn () => Order::factory()->createOne());
        $order->financial_status = OrderFinancialStatus::PAID;
        $order->save();

        Event::assertDispatched(fn (OrderPaid $event) => $event->order->id === $order->id);
    }

I tried finding a workaround for this, though with no luck. I tried:

  • adding __toString() to enum - not possible
  • using a custom getter

// Edit

I'm attaching the missing enum:

enum OrderFinancialStatus: string
{
    case PAID = 'paid';
}

radmen avatar Apr 28 '22 09:04 radmen

I've created a PR for basic enum-support: https://github.com/jpkleemans/attribute-events/pull/12/commits/9a3b2ef165aa145bb8657a27681cb7f5a028062b

jeffreyvanhees avatar Jun 13 '22 22:06 jeffreyvanhees

Thank you!

radmen avatar Sep 01 '22 07:09 radmen