CRUD icon indicating copy to clipboard operation
CRUD copied to clipboard

PHP Enums support

Open pxpm opened this issue 3 years ago • 3 comments

WHY

BEFORE - What was wrong? What was happening before this PR?

A powerfull introduction in 8.1 was Enums. Backpack was completely un-ware of them until now.

It was not possible use a field casted to an Enum::class.

See the following example, a little adaptation of the Article model and ArticleCrudController:

// the Enum class
enum StatusEnum: string
{
    case DRAFT = 'DRAFT';
    case PUBLISHED = 'PUBLISHED';

    public static function getOptions()
    {
        return array_combine(array_column(self::cases(), 'name'), array_column(self::cases(), 'value'));
    }
}

// In the Article model:

protected $casts = [
        'featured'  => 'boolean',
        'date'      => 'date',
        'status'    => StatusEnum::class
    ];

// In ArticleCrudController - adapting our field to use the enum:

$this->crud->addField([
                'name' => 'status',
                'label' => 'Status',
                'type' => 'select_from_array',
                'options' => StatusEnum::getOptions(),
            ]);

AFTER - What is happening after this PR?

After this PR it works as expected.

HOW

How did you achieve that, in technical terms?

Basically added a layer between getting and returning the models attributes values. That layer will check if Enums is a thing (only available in 8.1), if they are check if the model attribute is any kind of Enum, in case it is, return the appropriate string representation of it.

NOTE For the List/ShowOperation i started from https://github.com/Laravel-Backpack/CRUD/pull/4633 and added support for text and select_from_array columns (probably the ones that make sense to use with an Enum ? )

Is it a breaking change?

I don't think so, no.

How can we test the before & after?

You can use the example I gave on this issue description.

pxpm avatar Sep 21 '22 11:09 pxpm

Clicking Edit to show the edit form get me Backpack\CRUD\app\Library\CrudPanel\CrudPanel::getAttributeFinalValue(): Argument #1 ($attribute) must be of type string, null given

ziming avatar Sep 21 '22 12:09 ziming

Clicking Edit to show the edit form get me Backpack\CRUD\app\Library\CrudPanel\CrudPanel::getAttributeFinalValue(): Argument #1 ($attribute) must be of type string, null given

Should be good now @ziming I will write some tests for it 👍

pxpm avatar Sep 21 '22 14:09 pxpm

Looks good so far. but I have only tested with backed enums. From the code it does look like it will work for Non-backed Enum too

ziming avatar Sep 21 '22 14:09 ziming

I assigned @jorgetwgroup for testing purposes, and @tabacitu for implementation decisions.

We can also create a select_from_enum column/field that would avoid developer having to setup the options manually.

pxpm avatar Sep 23 '22 13:09 pxpm

there is already a database enum field in backpack so are you all going to call it php enum to differentiate it?

edit: ah i see so now the enum field support both database and php enum

ziming avatar Sep 27 '22 10:09 ziming

there is already a database enum field in backpack so are you all going to call it php enum to differentiate it?

edit: ah i see so now the enum field support both database and php enum

No zimming, the enum field should work for both enum types (PHP and database) I already did that change in this PR, I am finishing now the enum column too.

pxpm avatar Sep 27 '22 12:09 pxpm

@ziming I think it's now finished, tests are passing and I added the column too.

If you give this a test and found something let me know.

I am now going to write the docs for it.

Cheers

pxpm avatar Sep 29 '22 11:09 pxpm

Added docs for field and column https://github.com/Laravel-Backpack/docs/pull/379

pxpm avatar Oct 02 '22 09:10 pxpm

Looking forward to this PR. Hopefully it gets back ported to laravel 8 too. Which sometimes happen

https://github.com/laravel/framework/pull/44445

ziming avatar Oct 04 '22 08:10 ziming

Hello @pxpm thank to you because in this revision everything works as we speak about it.

I will go step by step.

Define the Enum Screen Shot 2022-10-10 at 20 52 14

Set Model cast Screen Shot 2022-10-10 at 20 52 21

Add column enum type Screen Shot 2022-10-10 at 20 52 55

Front screenshot-backpack test-2022 10 10-20_53_21

Add field "using the same function as column" Screen Shot 2022-10-10 at 20 53 03

Front screenshot-backpack test-2022 10 10-20_53_10

On my side everything is working as expected.

About code for me look everything ok, just a warning for @tabacitu this required PHP 8.1 to work normal.

Cheers.

jcastroa87 avatar Oct 10 '22 23:10 jcastroa87

Excellent work on this one 👏👏👏 Testing and merging it was smooth sailing too. So so happy with it.

slow_clap_cap

Merged! Tagging later today as part of the CRUD 5.4 minor release 🎉

tabacitu avatar Oct 17 '22 10:10 tabacitu