Passed
Push — ft/pagefield ( db2ad6...f2722b )
by Ben
10:27
created

FragmentField::getFragments()   B

Complexity

Conditions 8
Paths 7

Size

Total Lines 43
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 23
c 1
b 0
f 0
dl 0
loc 43
rs 8.4444
cc 8
nc 7
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Thinktomorrow\Chief\Fragments;
6
7
use Thinktomorrow\Chief\Fields\Fields;
8
use Thinktomorrow\Chief\Fields\Types\AbstractField;
9
use Thinktomorrow\Chief\Fields\Types\Field;
10
use Thinktomorrow\Chief\Fields\Types\FieldType;
11
use Thinktomorrow\Chief\Fields\Types\MediaField;
12
13
class FragmentField extends AbstractField implements Field
14
{
15
    /** @var Fields */
16
    private $fields;
17
18
    /** @var null|string */
19
    private $fragmentLabel;
20
21
    public static function make(string $key, Fields $fields): Field
22
    {
23
        return (new static(new FieldType(FieldType::FRAGMENT), $key))
24
            ->fields($fields);
25
    }
26
27
    private function fields(Fields $fields)
28
    {
29
        $this->fields = $fields;
30
31
        return $this;
32
    }
33
34
    public function getFields(): Fields
35
    {
36
        return $this->fields;
37
    }
38
39
    /**
40
     * @param string|null $locale
41
     * @return Fields[]
42
     */
43
    public function getFragments(?string $locale = null): array
0 ignored issues
show
Unused Code introduced by
The parameter $locale is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

43
    public function getFragments(/** @scrutinizer ignore-unused */ ?string $locale = null): array

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
44
    {
45
        // By default there is one empty Fragment provided to the user
46
        $fragments = [Fragment::empty($this->getKey())];
47
48
        // Model is auto-injected by Manager::editFields() method.
49
        if (($this->model)) {
50
            if (!method_exists($this->model, 'getFragments')) {
51
                throw new \RuntimeException(get_class($this->model) . ' is missing the ' . HasFragments::class . ' trait.');
52
            }
53
54
            if (count($modelFragments = $this->model->getFragments($this->getKey())) > 0) {
55
                $fragments = $modelFragments->map(function (FragmentModel $fragmentModel) {
56
                    return Fragment::fromModel($fragmentModel);
57
                })->all();
58
            }
59
        }
60
61
        foreach ($fragments as $k => $fragment) {
62
            $fragments[$k] = $fragments[$k]
63
                ->setModelIdInputName($this->name . '[' . $k . '][modelId]')
64
                ->setFields($this->fields->clone()->map(function (Field $field) use ($k, $fragment) {
65
                    return $field->name($this->name . '.' . $k . '.' . $field->getName())
0 ignored issues
show
Bug introduced by
The method name() does not exist on Thinktomorrow\Chief\Fields\Types\Field. Since it exists in all sub-types, consider adding an abstract or default implementation to Thinktomorrow\Chief\Fields\Types\Field. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

65
                    return $field->/** @scrutinizer ignore-call */ name($this->name . '.' . $k . '.' . $field->getName())
Loading history...
66
                                 ->localizedFormat(':name.:locale')
67
                                 ->valueResolver(function ($model = null, $locale = null, $field) use ($fragment) {
68
                                     if (isset($field->value)) {
69
                                         return $field->value;
70
                                     }
71
72
                                     if ($field instanceof MediaField) {
73
                                         if (!$fragment->hasModelId()) {
74
                                             return [];
75
                                         }
76
77
                                         return $field->getMedia(FragmentModel::find($fragment->getModelId()), $locale);
78
                                     }
79
80
                                     return $fragment->getValue($field->getColumn(), $locale);
81
                                 });
82
                }));
83
        }
84
85
        return $fragments;
86
    }
87
88
    /**
89
     * A fragmentlabel is shown in admin as the label above each fragment.
90
     *
91
     * @param string $fragmentLabel
92
     * @return $this
93
     */
94
    public function fragmentLabel(string $fragmentLabel): self
95
    {
96
        $this->fragmentLabel = $fragmentLabel;
97
98
        return $this;
99
    }
100
101
    public function getFragmentLabel(): string
102
    {
103
        return $this->fragmentLabel ?? 'fragment';
104
    }
105
106
    public function getDuplicatableFields(): array
107
    {
108
        if (count($this->getFragments()) < 1) {
109
            return [];
110
        }
111
112
        // Take the fields from the first fragment as a starting point for duplication
113
        return array_map(function (\Thinktomorrow\Chief\Fields\Types\Field $field) {
114
            return $field->valueResolver(function ($model = null, $locale = null, $field) {
0 ignored issues
show
Bug introduced by
The method valueResolver() does not exist on Thinktomorrow\Chief\Fields\Types\Field. Since it exists in all sub-types, consider adding an abstract or default implementation to Thinktomorrow\Chief\Fields\Types\Field. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

114
            return $field->/** @scrutinizer ignore-call */ valueResolver(function ($model = null, $locale = null, $field) {
Loading history...
115
                if ($field instanceof \Thinktomorrow\Chief\Fields\Types\MediaField) {
116
                    return [];
117
                }
118
                return null;
119
            })->render();
120
        }, $this->getFragments()[0]->getFields()->clone()->all());
121
    }
122
}
123