Skip to content

Commit

Permalink
Merge pull request #203 from bskl/get-enum-value
Browse files Browse the repository at this point in the history
Get value from model with casts php native enum
  • Loading branch information
freekmurze authored Oct 24, 2023
2 parents 37edac0 + a41f93d commit 00faf80
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 1 deletion.
19 changes: 18 additions & 1 deletion src/Html.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Spatie\Html;

use BackedEnum;
use DateTimeImmutable;
use Illuminate\Contracts\Support\Htmlable;
use Illuminate\Http\Request;
Expand All @@ -26,6 +27,7 @@
use Spatie\Html\Elements\Select;
use Spatie\Html\Elements\Span;
use Spatie\Html\Elements\Textarea;
use UnitEnum;

class Html
{
Expand Down Expand Up @@ -591,7 +593,9 @@ protected function old($name, $value = null)
// has a model assigned and there aren't old input items,
// try to retrieve a value from the model.
if (is_null($value) && $this->model && empty($this->request->old())) {
$value = data_get($this->model, $name) ?? '';
$value = ($value = data_get($this->model, $name)) instanceof UnitEnum
? $this->getEnumValue($value)
: $value;
}

return $this->request->old($name, $value);
Expand Down Expand Up @@ -647,4 +651,17 @@ protected function formatDateTime($value, $format)
return $value;
}
}

/**
* Get the value from the given enum.
*
* @param \UnitEnum|\BackedEnum $value
* @return string|int
*/
protected function getEnumValue($value)
{
return $value instanceof BackedEnum
? $value->value
: $value->name;
}
}
21 changes: 21 additions & 0 deletions tests/Html/ModelFormTest.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
<?php

use Spatie\Html\Test\Stubs\Role;
use Spatie\Html\Test\Stubs\Status;

it('can create a form from a model', function () {
assertHtmlStringEqualsHtmlString(
'<form method="POST">' .
Expand All @@ -8,3 +11,21 @@
$this->html->modelForm([])
);
});

it('returns an enum value from a name with an enum cast in the model', function () {
withModel(['relation' => ['role' => Role::Admin]]);
assertHtmlStringEqualsHtmlString(
'<input type="text" name="relation[role]" id="relation[role]" value="Admin">',
$this->html->text('relation[role]')
);

withModel(['select' => Status::Pending]);
assertHtmlStringEqualsHtmlString(
'<select name="select" id="select">
<option value="0">Unknown</option>
<option value="1" selected="selected">Pending</option>
<option value="2">Complete</option>
</select>',
$this->html->select('select', Status::asSelectArray())->render()
);
});
10 changes: 10 additions & 0 deletions tests/Stubs/Role.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace Spatie\Html\Test\Stubs;

enum Role
{
case User;
case Manager;
case Admin;
}
20 changes: 20 additions & 0 deletions tests/Stubs/Status.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

namespace Spatie\Html\Test\Stubs;

enum Status: int
{
case Unknown = 0;
case Pending = 1;
case Complete = 2;

/**
* Get the enum as an array formatted for a select.
*
* @return array
*/
public static function asSelectArray()
{
return array_column(self::cases(), 'name', 'value');
}
}

0 comments on commit 00faf80

Please sign in to comment.