Completed
Push — dependabot/npm_and_yarn/tippy.... ( 40037f...deaa3c )
by
unknown
400:02 queued 379:38
created

SavingFields::saveFields()   A

Complexity

Conditions 6
Paths 6

Size

Total Lines 34
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 16
dl 0
loc 34
ccs 17
cts 17
cp 1
rs 9.1111
c 1
b 0
f 0
cc 6
nc 6
nop 1
crap 6
1
<?php
2
3
namespace Thinktomorrow\Chief\Fields;
4
5
use Illuminate\Http\Request;
6
use Illuminate\Support\Str;
7
use Thinktomorrow\Chief\Fields\Types\Field;
8
use Thinktomorrow\Chief\Fields\Types\FieldType;
9
10
trait SavingFields
11
{
12
    // If there is a save<key>Field this has priority over the set<Key>Field methods
13
    protected $saveAssistantMethods = [];
14
    protected $saveMethods = [];
15
16
    protected $queued_translations = [];
17
18 84
    public function saveFields(Request $request)
19
    {
20 84
        foreach ($this->fieldsWithAssistantFields() as $field) {
0 ignored issues
show
Bug introduced by
It seems like fieldsWithAssistantFields() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

20
        foreach ($this->/** @scrutinizer ignore-call */ fieldsWithAssistantFields() as $field) {
Loading history...
21
22
            // Custom save methods
23 84
            if ($this->detectCustomSaveMethods($field)) {
24 68
                continue;
25
            }
26
27
            // Media fields are treated separately
28 84
            if ($field->ofType(FieldType::MEDIA, FieldType::DOCUMENT)) {
29 76
                if (! isset($this->saveMethods['_files'])) {
30 76
                    $this->saveMethods['_files'] = ['field' => new Fields([$field]), 'method' => 'uploadMedia'];
31 76
                    continue;
32
                }
33
34 30
                $this->saveMethods['_files']['field'][] = $field;
35 30
                continue;
36
            }
37
38
            // Custom set methods - default is the generic setField() method.
39 77
            $methodName = 'set'. ucfirst(Str::camel($field->key())) . 'Field';
40 77
            (method_exists($this, $methodName))
41 31
                ? $this->$methodName($field, $request)
42 77
                : $this->setField($field, $request);
43
        }
44
45
        // Save the model
46 84
        $this->saveQueuedFields();
47
48 84
        $this->saveQueuedMethods($request);
49
50
        // Attach the updated model to our manager.
51 84
        $this->manage($this->model);
0 ignored issues
show
Bug introduced by
It seems like manage() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

51
        $this->/** @scrutinizer ignore-call */ 
52
               manage($this->model);
Loading history...
52 84
    }
53
54 84
    protected function detectCustomSaveMethods(Field $field): bool
55
    {
56 84
        $saveMethodName = 'save'. ucfirst(Str::camel($field->key())) . 'Field';
0 ignored issues
show
Bug introduced by
The method key() does not exist on Thinktomorrow\Chief\Fields\Types\Field. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

56
        $saveMethodName = 'save'. ucfirst(Str::camel($field->/** @scrutinizer ignore-call */ key())) . 'Field';
Loading history...
57
58
        // Custom save method on assistant
59 84
        foreach ($this->assistants() as $assistant) {
0 ignored issues
show
Bug introduced by
It seems like assistants() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

59
        foreach ($this->/** @scrutinizer ignore-call */ assistants() as $assistant) {
Loading history...
60 68
            if (method_exists($assistant, $saveMethodName)) {
61 68
                $this->saveAssistantMethods[$field->key()] = ['field' => $field, 'method' => $saveMethodName, 'assistant' => $assistant];
62 68
                return true;
63
            }
64
        }
65
66
        // Custom save method on manager class
67 84
        if (method_exists($this, $saveMethodName)) {
68 41
            $this->saveMethods[$field->key()] = ['field' => $field, 'method' => $saveMethodName];
69 41
            return true;
70
        }
71
72 84
        return false;
73
    }
74
75 84
    private function saveQueuedMethods($request)
76
    {
77 84
        foreach ($this->saveAssistantMethods as $data) {
78 68
            $method = $data['method'];
79 68
            $data['assistant']->$method($data['field'], $request);
80
        }
81
82 84
        foreach ($this->saveMethods as $data) {
83 78
            $method = $data['method'];
84 78
            $this->$method($data['field'], $request);
85
        }
86 84
    }
87
88 77
    public function setField(Field $field, Request $request)
89
    {
90
        // Is field set as translatable?
91 77
        if ($field->isTranslatable()) {
92 75
            if (!$this->requestContainsTranslations($request)) {
0 ignored issues
show
Bug introduced by
It seems like requestContainsTranslations() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

92
            if (!$this->/** @scrutinizer ignore-call */ requestContainsTranslations($request)) {
Loading history...
93 24
                return;
94
            }
95
96
            // Make our media fields able to be translatable as well...
97 52
            if ($field->ofType(FieldType::MEDIA, FieldType::DOCUMENT)) {
98
                throw new \Exception('Cannot process the ' . $field->key . ' media field. Currently no support for translatable media files. We should fix this!');
0 ignored issues
show
Bug Best Practice introduced by
The property key does not exist on Thinktomorrow\Chief\Fields\Types\Field. Since you implemented __get, consider adding a @property annotation.
Loading history...
99
            }
100
101
            // Okay so this is a bit odd but since all translations are expected to be inside the trans
102
            // array, we can add all these translations at once. Just make sure to keep track of the
103
            // keys since this is what our translation engine requires as well for proper update.
104 52
            $this->queued_translations = $request->get('trans');
105 52
            $this->translation_columns[] = $field->column();
0 ignored issues
show
Bug introduced by
The method column() does not exist on Thinktomorrow\Chief\Fields\Types\Field. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

105
            /** @scrutinizer ignore-call */ 
106
            $this->translation_columns[] = $field->column();
Loading history...
Bug Best Practice introduced by
The property translation_columns does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
106
107 52
            return;
108
        }
109
110
        // By default we assume the key matches the attribute / column naming
111 39
        $this->model->{$field->column()} = $request->get($field->key());
112 39
    }
113
114 84
    private function saveQueuedFields()
115
    {
116 84
        $this->model->save();
117
118
        // Translations
119 84
        if (!empty($this->queued_translations)) {
120 50
            $this->saveTranslations($this->queued_translations, $this->model, $this->translation_columns);
0 ignored issues
show
Bug introduced by
It seems like saveTranslations() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

120
            $this->/** @scrutinizer ignore-call */ 
121
                   saveTranslations($this->queued_translations, $this->model, $this->translation_columns);
Loading history...
121
        }
122
123 84
        return (new static($this->registration))->manage($this->model);
0 ignored issues
show
Unused Code introduced by
The call to Thinktomorrow\Chief\Fiel...ngFields::__construct() has too many arguments starting with $this->registration. ( Ignorable by Annotation )

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

123
        return (/** @scrutinizer ignore-call */ new static($this->registration))->manage($this->model);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
124
    }
125
}
126