Home > Software design >  Laravel: php match does not seem to be working
Laravel: php match does not seem to be working

Time:09-01

I'm working on a Laravel app. I've created an enum like this:

<?php

namespace Domain\Order\Enums;

use Domain\Order\Models\Order;

enum OrderStatuses : string
{
    case New           = 'new';
    case Pending       = 'pending';
    case Canceled      = 'canceled';
    case Paid          = 'paid';
    case PaymentFailed = 'payment-failed';

    public function createOrderStatus(Order $order) : OrderStatus
    {
        return match($this) {
            OrderStatuses::Pending       => new PendingOrderStatus($order),
            OrderStatuses::Canceled      => new CanceledOrderStatus($order),
            OrderStatuses::Paid          => new PaidOrderStatus($order),
            OrderStatuses::PaymentFailed => new PaymentFailedOrderStatus($order),
            default                      => new NewOrderStatus($order)
        };
    }
}

In my order model I've got the following attribute:

protected function status(): Attribute
    {
        return new Attribute(
            get: fn(string $value) =>
                OrderStatuses::from($value)->createOrderStatus($this),
        );
    }

which as you can see receives some data and returns an Order status.

Now, I've got the following piece of code:

$order = Order::find($orderID);

        $newOrder = match ($order->status) {
            OrderStatuses::New => (new NewToPaidTransition)->execute($order),
            NewOrderStatus::class => (new NewToPaidTransition)->execute($order),
            'new' => (new NewToPaidTransition)->execute($order),
            default => null,
        };

but the value of $newOrder is always null, meaning the status is not being matched to any of the elements. There should be one single element there: NewOrderStatus::class, I just added the others for debugging purposes.

If I inspect the value of $order->status while running the debugger I'm getting that it is of type Domain\Order\Enums\NewOrderStatus so why it is not being matched?

Thanks

CodePudding user response:

It looks like you are testing for equality between an instance of a class and a string of the class name.

Try

$newOrder = match (get_class($order->status)) {
    OrderStatuses::New => (new NewToPaidTransition)->execute($order),
    NewOrderStatus::class => (new NewToPaidTransition)->execute($order),
    'new' => (new NewToPaidTransition)->execute($order),
    default => null,
};
  • Related