Passed
Push — dependabot/npm_and_yarn/@vue/t... ( 1a0b23...9776fc )
by
unknown
84:45 queued 64:29
created

AbstractManager::fieldsWithAssistantFields()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

Changes 0
Metric Value
eloc 6
dl 0
loc 13
ccs 7
cts 7
cp 1
rs 10
c 0
b 0
f 0
cc 3
nc 3
nop 0
crap 3
1
<?php
2
3
namespace Thinktomorrow\Chief\Management;
4
5
use Illuminate\Http\Request;
6
use Illuminate\Support\Collection;
7
use Thinktomorrow\Chief\Concerns\Translatable\TranslatableCommand;
8
use Thinktomorrow\Chief\Fields\FieldArrangement;
9
use Thinktomorrow\Chief\Fields\Fields;
10
use Thinktomorrow\Chief\Fields\RenderingFields;
11
use Thinktomorrow\Chief\Fields\SavingFields;
12
use Thinktomorrow\Chief\Filters\Filters;
13
use Thinktomorrow\Chief\Management\Assistants\AssistedManager;
14
use Thinktomorrow\Chief\Management\Details\HasDetails;
15
use Thinktomorrow\Chief\Management\Details\HasSections;
16
use Thinktomorrow\Chief\Management\Exceptions\NonExistingRecord;
17
use Thinktomorrow\Chief\Management\Exceptions\NotAllowedManagerRoute;
18
19
abstract class AbstractManager
20
{
21
    use RenderingFields,
0 ignored issues
show
introduced by
The trait Thinktomorrow\Chief\Management\Details\HasDetails requires some properties which are not provided by Thinktomorrow\Chief\Management\AbstractManager: $labelPlural, $id, $labelSingular, $title
Loading history...
introduced by
The trait Thinktomorrow\Chief\Management\ManagesPagebuilder requires some properties which are not provided by Thinktomorrow\Chief\Management\AbstractManager: $trans, $slug, $page_id, $id
Loading history...
Bug introduced by
The trait Thinktomorrow\Chief\Fields\SavingFields requires the property $key which is not provided by Thinktomorrow\Chief\Management\AbstractManager.
Loading history...
22
        SavingFields,
23
        HasDetails,
24
        HasSections,
25
        ManagesMedia,
26
        ManagesPagebuilder,
27
        TranslatableCommand,
28
        AssistedManager;
29
30
    protected $translation_columns = [];
31
32
    protected $model;
33
34
    /** @var Register */
35
    protected $registration;
36
37
    public function __construct(Registration $registration)
38 112
    {
39
        $this->registration = $registration;
0 ignored issues
show
Documentation Bug introduced by
It seems like $registration of type Thinktomorrow\Chief\Management\Registration is incompatible with the declared type Thinktomorrow\Chief\Management\Register of property $registration.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
40 112
41
        // Upon instantiation, a general model is set that doesn't point to a persisted record.
42
        $this->manage(app($this->registration->model()));
43 112
44
        // Check if key and model are present since the model should be set by the manager itself
45
        $this->validateConstraints();
46 112
    }
47 112
48
    public function manage($model): Manager
49 112
    {
50
        $this->model = $model;
51 112
52
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Thinktomorrow\Chief\Management\AbstractManager which is incompatible with the type-hinted return Thinktomorrow\Chief\Management\Manager.
Loading history...
53 112
    }
54
55
    public function findManaged($id): Manager
56 64
    {
57
        $model = $this->registration->model();
0 ignored issues
show
Bug introduced by
The method model() does not exist on Thinktomorrow\Chief\Management\Register. ( Ignorable by Annotation )

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

57
        /** @scrutinizer ignore-call */ 
58
        $model = $this->registration->model();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
58 64
59
        $modelInstance = $model::where('id', $id)->withoutGlobalScopes()->first();
60 64
61
        return (new static($this->registration))->manage($modelInstance);
0 ignored issues
show
Bug introduced by
$this->registration of type Thinktomorrow\Chief\Management\Register is incompatible with the type Thinktomorrow\Chief\Management\Registration expected by parameter $registration of Thinktomorrow\Chief\Mana...tManager::__construct(). ( Ignorable by Annotation )

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

61
        return (new static(/** @scrutinizer ignore-type */ $this->registration))->manage($modelInstance);
Loading history...
62 64
    }
63
64
    public function findAllManaged($apply_filters = false): Collection
65
    {
66
        $model = $this->registration->model();
67
68
        $builder = (new $model)->query();
69
70
        if ($apply_filters) {
71
            $this->filters()->apply($builder);
72
        }
73
74
        if ($this->isAssistedBy('publish')) {
75
            $builder->orderBy('published', 'DESC');
76
        }
77
78
        $builder->orderBy('updated_at', 'DESC');
79
80
        return $builder->get()->map(function ($model) {
81
            return (new static($this->registration))->manage($model);
0 ignored issues
show
Bug introduced by
$this->registration of type Thinktomorrow\Chief\Management\Register is incompatible with the type Thinktomorrow\Chief\Management\Registration expected by parameter $registration of Thinktomorrow\Chief\Mana...tManager::__construct(). ( Ignorable by Annotation )

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

81
            return (new static(/** @scrutinizer ignore-type */ $this->registration))->manage($model);
Loading history...
82
        });
83 58
    }
84
85 58
    public function model()
86
    {
87
        return $this->model;
88
    }
89
90
    public function hasExistingModel(): bool
91
    {
92
        return ($this->model && $this->model->exists);
93
    }
94 65
95
    /**
96 65
     * If the model exists return it otherwise
97 1
     * throws a nonExistingRecord exception;
98
     *
99
     * @throws NonExistingRecord
100 64
     */
101
    protected function existingModel()
102
    {
103
        if (!$this->hasExistingModel()) {
104
            throw new NonExistingRecord('Model does not exist yet but is expected.');
105
        }
106
107
        return $this->model;
108
    }
109
110
    /**
111 78
     * Determine which actions should be available for this
112
     * manager and their respective routed urls.
113
     *
114 78
     * @param $verb
115 78
     * @return null|string
116 78
     * @throws NonExistingRecord
117
     */
118
    public function route($verb): ?string
119 78
    {
120 33
        $routes = [
121
            'index'   => route('chief.back.managers.index', [$this->registration->key()]),
0 ignored issues
show
Bug introduced by
The method key() does not exist on Thinktomorrow\Chief\Management\Register. ( Ignorable by Annotation )

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

121
            'index'   => route('chief.back.managers.index', [$this->registration->/** @scrutinizer ignore-call */ key()]),

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
122
            'create'  => route('chief.back.managers.create', [$this->registration->key()]),
123
            'store'   => route('chief.back.managers.store', [$this->registration->key()]),
124
        ];
125 65
126 64
        if (array_key_exists($verb, $routes)) {
127 64
            return $routes[$verb] ?? null;
128 64
        }
129
130
        //These routes expect the model to be persisted in the database
131 64
        $modelRoutes = [
132
            'edit'    => route('chief.back.managers.edit', [$this->registration->key(), $this->existingModel()->id]),
133
            'update'  => route('chief.back.managers.update', [$this->registration->key(), $this->existingModel()->id]),
134 84
            'delete'  => route('chief.back.managers.delete', [$this->registration->key(), $this->existingModel()->id]),
135
            'upload'  => route('chief.back.managers.media.upload', [$this->registration->key(), $this->existingModel()->id]),
136 84
        ];
137
138
        return $modelRoutes[$verb] ?? null;
139 76
    }
140
141 76
    public function can($verb): bool
142 1
    {
143
        return !is_null($this->route($verb));
144
    }
145 75
146
    public function guard($verb): Manager
147
    {
148
        if (! $this->can($verb)) {
149
            NotAllowedManagerRoute::notAllowedVerb($verb, $this);
150
        }
151
152
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Thinktomorrow\Chief\Management\AbstractManager which is incompatible with the type-hinted return Thinktomorrow\Chief\Management\Manager.
Loading history...
153
    }
154
155
    public function fields(): Fields
156 3
    {
157
        return new Fields();
158 3
    }
159
160
    /**
161 5
     * Enrich the manager fields with any of the assistant specified fields
162
     *
163
     * @return Fields
164 5
     * @throws \Exception
165 5
     */
166 5
    public function fieldsWithAssistantFields(): Fields
167 3
    {
168 5
        $fields = $this->fields();
169
170
        foreach ($this->assistants() as $assistant) {
171
            if (! method_exists($assistant, 'fields')) {
172 5
                continue;
173
            }
174
175 4
            $fields = $fields->merge($assistant->fields());
176 4
        }
177 4
178
        return $fields;
179 4
    }
180
181
    /**
182
     * This determines the arrangement of the manageable fields
183
     * on the create and edit forms. By default, all fields
184
     * are presented in their order of appearance
185
     *
186
     * @param null $key pinpoint to a specific field arrangement e.g. for create page.
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $key is correct as it would always require null to be passed?
Loading history...
187
     * @return FieldArrangement
188 4
     * @throws \Exception
189 3
     */
190
    public function fieldArrangement($key = null): FieldArrangement
191
    {
192 2
        return new FieldArrangement($this->fieldsWithAssistantFields());
193 1
    }
194
195
    public function delete()
196 2
    {
197
        $this->model->delete();
0 ignored issues
show
Bug introduced by
The method delete() does not exist on Illuminate\Contracts\Foundation\Application. ( Ignorable by Annotation )

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

197
        $this->model->/** @scrutinizer ignore-call */ 
198
                      delete();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
198
    }
199 4
200
    public static function filters(): Filters
201 4
    {
202
        return new Filters();
203
    }
204 52
205
    /**
206
     * This method can be used to manipulate the store request payload
207 52
     * before being passed to the storing / updating the models.
208 50
     *
209 8
     * @param Request $request
210
     * @return Request
211
     */
212
    public function storeRequest(Request $request): Request
213 42
    {
214
        return $request;
215
    }
216
217
    /**
218
     * This method can be used to manipulate the update request payload
219
     * before being passed to the storing / updating the models.
220 42
     *
221 42
     * @param Request $request
222
     * @return Request
223 42
     */
224
    public function updateRequest(Request $request): Request
225
    {
226
        return $request;
227 19
    }
228 19
229
    protected function requestContainsTranslations(Request $request): bool
230 58
    {
231
        return $request->has('trans');
232 58
    }
233
234
    protected function validateConstraints()
235 58
    {
236 40
        if (!$this->model) {
237
            throw new \DomainException('Model class should be set for this manager. Please set the model property default via the constructor or by extending the setupDefaults method.');
238
        }
239 58
    }
240
}
241