Skip to content

Commit e0d1244

Browse files
authored
Merge pull request #165 from code16/fix/multiple-select-formatter
Fix/multiple select formatter
2 parents 85e4f1a + 64f426a commit e0d1244

File tree

10 files changed

+194
-80
lines changed

10 files changed

+194
-80
lines changed

src/Form/Fields/Formatters/AutocompleteFormatter.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Code16\Sharp\Form\Fields\Formatters;
44

55
use Code16\Sharp\Form\Fields\SharpFormField;
6+
use Code16\Sharp\Utils\Transformers\ArrayConverter;
67

78
class AutocompleteFormatter extends SharpFieldFormatter
89
{
@@ -14,6 +15,8 @@ class AutocompleteFormatter extends SharpFieldFormatter
1415
*/
1516
function toFront(SharpFormField $field, $value)
1617
{
18+
$value = ArrayConverter::modelToArray($value);
19+
1720
return is_null($value) || is_array($value)
1821
? $value
1922
: [$field->itemIdAttribute() => $value];

src/Form/Fields/Formatters/AutocompleteListFormatter.php

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,16 @@ function toFront(SharpFormField $field, $value)
1616
{
1717
$autocompleteField = $field->autocompleteField();
1818

19-
return collect($value)->map(function ($item) use($field, $autocompleteField) {
20-
return [
21-
$autocompleteField->itemIdAttribute() => $item[$autocompleteField->itemIdAttribute()],
22-
$autocompleteField->key() => $autocompleteField->formatter()->toFront(
23-
$autocompleteField, $item
24-
)
25-
];
26-
})->all();
19+
return collect($value)
20+
->map(function ($item) use($field, $autocompleteField) {
21+
return [
22+
$autocompleteField->itemIdAttribute() => $item[$autocompleteField->itemIdAttribute()],
23+
$autocompleteField->key() => $autocompleteField->formatter()->toFront(
24+
$autocompleteField, $item
25+
)
26+
];
27+
})
28+
->all();
2729
}
2830

2931
/**
@@ -36,14 +38,16 @@ function fromFront(SharpFormField $field, string $attribute, $value)
3638
{
3739
$autocompleteField = $field->autocompleteField();
3840

39-
return collect($value)->map(function ($item) use($field, $autocompleteField) {
40-
$item = $item[$autocompleteField->key()];
41-
42-
return [
43-
$autocompleteField->itemIdAttribute() => $autocompleteField->formatter()->fromFront(
44-
$autocompleteField, $autocompleteField->key(), $item
45-
)
46-
];
47-
})->all();
41+
return collect($value)
42+
->map(function ($item) use($field, $autocompleteField) {
43+
$item = $item[$autocompleteField->key()];
44+
45+
return [
46+
$autocompleteField->itemIdAttribute() => $autocompleteField->formatter()->fromFront(
47+
$autocompleteField, $autocompleteField->key(), $item
48+
)
49+
];
50+
})
51+
->all();
4852
}
4953
}

src/Form/Fields/Formatters/ListFormatter.php

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,25 @@ class ListFormatter extends SharpFieldFormatter
1414
*/
1515
function toFront(SharpFormField $field, $value)
1616
{
17-
return collect($value)->map(function ($item) use($field) {
18-
$itemArray = [
19-
$field->itemIdAttribute() => $item[$field->itemIdAttribute()]
20-
];
17+
return collect($value)
18+
->map(function ($item) use($field) {
19+
$itemArray = [
20+
$field->itemIdAttribute() => $item[$field->itemIdAttribute()]
21+
];
2122

22-
$field->itemFields()->each(function($itemField) use($item, &$itemArray) {
23-
$key = $itemField->key();
23+
$field
24+
->itemFields()
25+
->each(function($itemField) use($item, &$itemArray) {
26+
$key = $itemField->key();
2427

25-
$itemArray[$key] = isset($item[$key])
26-
? $itemField->formatter()->toFront($itemField, $item[$key])
27-
: null;
28-
});
28+
$itemArray[$key] = isset($item[$key])
29+
? $itemField->formatter()->toFront($itemField, $item[$key])
30+
: null;
31+
});
2932

30-
return $itemArray;
31-
32-
})->all();
33+
return $itemArray;
34+
})
35+
->all();
3336
}
3437

3538
/**
@@ -40,23 +43,24 @@ function toFront(SharpFormField $field, $value)
4043
*/
4144
function fromFront(SharpFormField $field, string $attribute, $value)
4245
{
43-
return collect($value)->map(function ($item) use($field) {
44-
$itemArray = [
45-
$field->itemIdAttribute() => $item[$field->itemIdAttribute()]
46-
];
47-
48-
foreach($item as $key => $value) {
49-
$itemField = $field->findItemFormFieldByKey($key);
50-
51-
if($itemField) {
52-
$itemArray[$key] = $itemField->formatter()
53-
->setInstanceId($this->instanceId)
54-
->fromFront($itemField, $key, $value);
55-
}
56-
}
46+
return collect($value)
47+
->map(function ($item) use($field) {
48+
$itemArray = [
49+
$field->itemIdAttribute() => $item[$field->itemIdAttribute()]
50+
];
5751

58-
return $itemArray;
52+
foreach($item as $key => $value) {
53+
$itemField = $field->findItemFormFieldByKey($key);
54+
55+
if($itemField) {
56+
$itemArray[$key] = $itemField->formatter()
57+
->setInstanceId($this->instanceId)
58+
->fromFront($itemField, $key, $value);
59+
}
60+
}
5961

60-
})->all();
62+
return $itemArray;
63+
})
64+
->all();
6165
}
6266
}

src/Form/Fields/Formatters/SelectFormatter.php

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Code16\Sharp\Form\Fields\Formatters;
44

55
use Code16\Sharp\Form\Fields\SharpFormField;
6+
use Code16\Sharp\Utils\Transformers\ArrayConverter;
67

78
class SelectFormatter extends SharpFieldFormatter
89
{
@@ -14,11 +15,15 @@ class SelectFormatter extends SharpFieldFormatter
1415
function toFront(SharpFormField $field, $value)
1516
{
1617
if($field->multiple()) {
17-
return collect((array)$value)->map(function($item) use($field) {
18-
return is_array($item) || is_object($item)
19-
? ((array)$item)[$field->idAttribute()]
20-
: $item;
21-
})->all();
18+
return collect((array)$value)
19+
->map(function($item) use($field) {
20+
$item = ArrayConverter::modelToArray($item);
21+
22+
return is_array($item)
23+
? $item[$field->idAttribute()]
24+
: $item;
25+
})
26+
->all();
2227

2328
} elseif(is_array($value)) {
2429
// Strip other values is not configured to be multiple
@@ -38,9 +43,11 @@ function fromFront(SharpFormField $field, string $attribute, $value)
3843
{
3944
if($field->multiple()) {
4045
// We must transform items into associative arrays with the "id" key
41-
return collect((array)$value)->map(function ($item) {
42-
return ["id" => $item];
43-
})->all();
46+
return collect((array)$value)
47+
->map(function ($item) use($field) {
48+
return [$field->idAttribute() => $item];
49+
})
50+
->all();
4451

4552
} elseif(is_array($value)) {
4653
return $value[0];

src/Form/Fields/Formatters/TagsFormatter.php

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Code16\Sharp\Form\Fields\Formatters;
44

55
use Code16\Sharp\Form\Fields\SharpFormField;
6+
use Code16\Sharp\Utils\Transformers\ArrayConverter;
67

78
class TagsFormatter extends SharpFieldFormatter
89
{
@@ -16,10 +17,11 @@ function toFront(SharpFormField $field, $value)
1617
{
1718
return collect((array)$value)
1819
->map(function($item) use($field) {
20+
$item = ArrayConverter::modelToArray($item);
1921

20-
if(is_object($item) || is_array($item)) {
22+
if(is_array($item)) {
2123
return [
22-
"id" => ((array)$item)[$field->idAttribute()],
24+
"id" => $item[$field->idAttribute()],
2325
];
2426
}
2527

@@ -45,28 +47,28 @@ function fromFront(SharpFormField $field, string $attribute, $value)
4547
return is_null($item["id"]) || isset($options[$item["id"]]);
4648
})
4749

48-
->when(! $field->creatable(), function($collection) {
49-
// Field isn't creatable, let's just strip all null ids
50-
return $collection->filter(function($item) {
51-
return !is_null($item["id"]);
52-
});
53-
})
50+
->when(! $field->creatable(), function($collection) {
51+
// Field isn't creatable, let's just strip all null ids
52+
return $collection->filter(function($item) {
53+
return !is_null($item["id"]);
54+
});
55+
})
5456

55-
->map(function($item) use($field) {
56-
if(is_null($item["id"])) {
57-
return array_merge([
58-
$field->idAttribute() => null,
59-
$field->createAttribute() => $item["label"]
60-
], $field->createAdditionalAttributes()
61-
);
62-
}
57+
->map(function($item) use($field) {
58+
if(is_null($item["id"])) {
59+
return array_merge([
60+
$field->idAttribute() => null,
61+
$field->createAttribute() => $item["label"]
62+
], $field->createAdditionalAttributes()
63+
);
64+
}
6365

64-
return [
65-
$field->idAttribute() => $item["id"]
66-
];
66+
return [
67+
$field->idAttribute() => $item["id"]
68+
];
6769

68-
})
69-
->values()
70-
->all();
70+
})
71+
->values()
72+
->all();
7173
}
7274
}

src/Form/Fields/Utils/SharpFormFieldWithOptions.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Code16\Sharp\Form\Fields\Utils;
44

5+
use Code16\Sharp\Utils\Transformers\ArrayConverter;
56
use Illuminate\Support\Collection;
67

78
trait SharpFormFieldWithOptions
@@ -19,9 +20,9 @@ protected static function formatOptions($options, $idAttribute = "id")
1920
}
2021

2122
$options = collect($options);
23+
$firstOption = ArrayConverter::modelToArray($options->first());
2224

23-
if((is_array($options->first()) || is_object($options->first()))
24-
&& isset(((array)$options->first())[$idAttribute])) {
25+
if(is_array($firstOption) && isset($firstOption[$idAttribute])) {
2526
// We assume that we already have ["id", "label"] in this case
2627
return $options->all();
2728
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
namespace Code16\Sharp\Utils\Transformers;
4+
5+
class ArrayConverter
6+
{
7+
8+
/**
9+
* Convert a class or Model into an array.
10+
* If $model is not an array or model, simply return it.
11+
*
12+
* @param array|object|mixed $model
13+
* @return array|mixed
14+
*/
15+
public static function modelToArray($model)
16+
{
17+
if(is_array($model)) {
18+
return $model;
19+
}
20+
21+
if(is_object($model)) {
22+
if(method_exists($model, "toArray")) {
23+
return $model->toArray();
24+
}
25+
26+
return (array)$model;
27+
}
28+
29+
// Model is not a structured data. We return it as it is.
30+
return $model;
31+
}
32+
}

src/Utils/Transformers/WithCustomTransformers.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
use Code16\Sharp\Form\SharpForm;
88
use Illuminate\Contracts\Pagination\LengthAwarePaginator as LengthAwarePaginatorContract;
99
use Illuminate\Pagination\LengthAwarePaginator;
10-
use stdClass;
1110

1211
/**
1312
* This trait allows a class to handle a custom transformers array.
@@ -100,7 +99,7 @@ function apply($value, $instance = null, $attribute = null)
10099
*/
101100
protected function applyTransformers($model, bool $forceFullObject = true)
102101
{
103-
$attributes = is_array($model) ? $model: ($model instanceof stdClass ? (array)$model: $model->toArray());
102+
$attributes = ArrayConverter::modelToArray($model);
104103

105104
if($forceFullObject) {
106105
// Merge model attribute with form fields to be sure we have

tests/Unit/Form/Fields/Formatters/AutocompleteFormatterTest.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,28 @@ function we_can_format_local_value_to_front()
2525
SharpFormAutocompleteField::make("text", "local")->setItemIdAttribute("num"),
2626
$value
2727
));
28+
29+
$this->assertEquals(["id" => $value], (new AutocompleteFormatter)->toFront(
30+
SharpFormAutocompleteField::make("text", "local"),
31+
["id" => $value]
32+
));
33+
34+
$this->assertEquals(["id" => $value], (new AutocompleteFormatter)->toFront(
35+
SharpFormAutocompleteField::make("text", "local"),
36+
(object)["id" => $value]
37+
));
38+
39+
$this->assertEquals(["id" => $value], (new AutocompleteFormatter)->toFront(
40+
SharpFormAutocompleteField::make("text", "local"),
41+
new class($value) {
42+
function __construct($value) {
43+
$this->value = $value;
44+
}
45+
function toArray() {
46+
return ["id" => $this->value];
47+
}
48+
}
49+
));
2850
}
2951

3052
/** @test */

0 commit comments

Comments
 (0)