Passed
Push — main ( 64c093...fcba4f )
by Yaroslav
17:14
created

MetaFieldUpdater::flexibleField()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3.2098

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 6
c 1
b 0
f 0
dl 0
loc 11
ccs 5
cts 7
cp 0.7143
rs 10
cc 3
nc 3
nop 1
crap 3.2098
1
<?php
2
3
namespace NovaThinKit\Nova\Helpers;
4
5
use Laravel\Nova\Fields\Code;
6
use Laravel\Nova\Fields\Field;
7
8
class MetaFieldUpdater
9
{
10
    protected string $relationship;
11
    protected string $keyName;
12
    protected string $dataKeyName;
13
14
    /**
15
     * @param string $relationship
16
     * @param string $keyName
17
     * @param string $dataKeyName
18
     */
19 6
    public function __construct(string $relationship, string $keyName = 'key', string $dataKeyName = 'data')
20
    {
21 6
        $this->relationship = $relationship;
22 6
        $this->keyName      = $keyName;
23 6
        $this->dataKeyName  = $dataKeyName;
24
    }
25
26 6
    public function field(Field $field, ?\Closure $resolve = null, ?\Closure $fill = null, ?string $computedAttribute = null): Field
27
    {
28 6
        if (is_a($field, 'NovaFlexibleContent\Flexible', true)) {
29 5
            return $this->flexibleField($field);
30
        }
31 6
        $field
32 6
            ->resolveUsing(function ($value, $model, $attribute) use ($field, $resolve, $computedAttribute) {
33 6
                $meta = $model->{$this->relationship}()->where('key', $computedAttribute ?? $attribute)->first();
34 6
                if ($meta) {
35 6
                    if ($resolve) {
36 5
                        return call_user_func($resolve, $meta, $value, $model, $attribute);
37
                    }
38
39 6
                    if ($this->fieldExpectsRawValue($field)) {
40 5
                        return $meta->{$this->dataKeyName};
41
                    }
42
43 6
                    $decoded = json_decode($meta->{$this->dataKeyName}, true);
44 6
                    if (is_array($decoded)) {
45 1
                        return $decoded;
46
                    }
47
48 6
                    return $meta->{$this->dataKeyName};
49
                }
50
51 6
                return null;
52 6
            })
53 6
            ->fillUsing(function ($request, $model, $attribute, $requestAttribute) use ($fill, $computedAttribute) {
54 5
                if($model->exists) {
55 5
                    $meta = $model->fresh()->{$this->relationship}()->firstOrNew(
56 5
                        [$this->keyName => $computedAttribute ?? $attribute],
57 5
                        [$this->dataKeyName => null]
58 5
                    );
59
60 5
                    if ($fill) {
61 5
                        $value = $fill($meta, $request->$requestAttribute, $request, $model, $attribute, $requestAttribute);
62 5
                        $meta->fill([
63 5
                            $this->dataKeyName => is_string($value) ? $value : json_encode($value),
64 5
                        ]);
65
                    } else {
66 5
                        $meta->fill([
67 5
                            $this->dataKeyName => $request->$requestAttribute,
68 5
                        ]);
69
                    }
70
71 5
                    $meta->save();
72
                }
73 6
            });
74
75 6
        return $field;
76
    }
77
78 5
    public function flexibleField($field)
79
    {
80 5
        if (!class_exists('NovaFlexibleContent\Flexible')) {
81
            throw new \Exception('Please install nova-flexible-content package');
82
        }
83 5
        if (!is_a($field, 'NovaFlexibleContent\Flexible', true)) {
84
            throw new \Exception('Filed should be instance of NovaFlexibleContent\Flexible');
85
        }
86 5
        $field->setResolver(new \NovaThinKit\Nova\Flexible\Resolvers\MetaTableResolver($this->relationship, $this->keyName, $this->dataKeyName));
87
88 5
        return $field;
89
    }
90
91 6
    protected function fieldExpectsRawValue(Field $field): bool
92
    {
93 6
        return $field instanceof Code;
94
    }
95
}
96