MetaFieldUpdater   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 86
Duplicated Lines 0 %

Test Coverage

Coverage 95.74%

Importance

Changes 4
Bugs 0 Features 0
Metric Value
wmc 14
eloc 43
c 4
b 0
f 0
dl 0
loc 86
ccs 45
cts 47
cp 0.9574
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A fieldExpectsRawValue() 0 3 1
B field() 0 50 9
A flexibleField() 0 11 3
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