Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

text column to support PHP Enum casting #4633

Closed
wants to merge 1 commit into from

Conversation

ziming
Copy link
Contributor

@ziming ziming commented Sep 1, 2022

WHY

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

Some of us do this in our model casts to take advantage of PHP 8.1 Enums to ensure a given column can only contain a set of specific values

protected $casts = [
'status' => StatusEnum::class
]

But in backpack it will be an error

mb_strwidth(): Argument #1 ($string) must be of type string

AFTER - What is happening after this PR?

Display the enum value

HOW

How did you achieve that, in technical terms?

1st we use the function_exists('enum_exists') check, then if that functions exist, we know we are at least on a PHP version that supports PHP enums and check if the value is an instance of UnitEnum, if it is then we call ->value to get the enum value

This is how i see laravel support PHP Enums currently. See Line 26

https://github.com/laravel/framework/blob/0f1eb9ef9d3846eeca0e6bfac77ddd67ce8ca12b/src/Illuminate/Database/Eloquent/Relations/Concerns/InteractsWithDictionary.php#L26

Additionally, concepts like toString() does not exist for PHP Enums (they are not allowed to implement Stringable interface). So we have to handle it at the column view file level (or maybe at the level before it is passed to the column/field blade file)

Is it a breaking change?

No

How can we test the before & after?

Cast a text column to php enum and use the text column

@ziming ziming changed the title text column to support Enum casting text column to support PHP Enum casting Sep 2, 2022
@ziming
Copy link
Contributor Author

ziming commented Sep 2, 2022

I just tested this in production this early morning.

As a backpack column, it works perfect.

However in edit/create view I noticed the following:

  • In Select Field, it goes to blank instead of selecting the value in the column when the edit form loads which is understandable since Enum is not string so the comparison will be false. Saving works correctly since Laravel Eloquent supports string/int <> PHP Enum conversions transparently behind the scenes
  • In Text Field, I get htmlspecialchars(): Argument #1 ($string) must be of type string, Enum given when the edit form loads

So i think we can either:

  • Just merge this since as a backpack column it works perfectly (unless u want a seperate PHP Enum Column blade view). This can be useful for ppl with many readonly backpack crud controllers.
  • Change the PR title to PHP Enums support then update text field, select field.etc to do the $field['value']->value if PHP Enum when displaying the value in forms

@pxpm
Copy link
Contributor

pxpm commented Sep 21, 2022

Hey @ziming I've just submitted #4678 that contains this code plus the code needed to make enums work as fields/columns (note that in columns it only work in text and select_from_array.
See the description I added on that PR.

Can you give that branch a try in your scenario and let me know if everything is working fine on your side ?

You can use composer require backpack/crud:"dev-enum-support as 5.3.99" to checkout that branch!

I will be closing this one, thanks again @ziming for the contribution and bring this to our attention 🙏

@pxpm pxpm closed this Sep 21, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants