Test Setup Failed
Push — a-simpler-manager ( cc67c7...cc5aa5 )
by Ben
07:45
created

FragmentAssistant::fragmentable()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 2
dl 0
loc 5
c 1
b 0
f 0
rs 10
cc 1
nc 1
nop 0
1
<?php
2
declare(strict_types=1);
3
4
namespace Thinktomorrow\Chief\Managers\Assistants;
5
6
use Illuminate\Http\Request;
7
use Thinktomorrow\Chief\Fragments\Fragmentable;
8
use Thinktomorrow\Chief\Fragments\FragmentsOwner;
9
use Thinktomorrow\Chief\Managers\Register\Registry;
10
use Thinktomorrow\Chief\Managers\Routes\ManagedRoute;
11
use Thinktomorrow\Chief\ManagedModels\Fields\Validation\FieldValidator;
12
use Thinktomorrow\Chief\Fragments\Actions\CreateFragmentModel;
13
use Thinktomorrow\Chief\ManagedModels\Application\DeleteModel;
14
15
trait FragmentAssistant
16
{
17
    abstract protected function fieldValidator(): FieldValidator;
18
    abstract protected function generateRoute(string $action, $model = null, ...$parameters): string;
19
    abstract protected function guard(string $action, $model = null);
20
21
    public function routesFragmentAssistant(): array
22
    {
23
        return [
24
            ManagedRoute::get('fragment-edit', 'fragment/{fragment_id}/edit'),
25
            ManagedRoute::put('fragment-update', 'fragment/{fragment_id}/update'),
26
            ManagedRoute::post('fragment-status', 'fragment/{fragment_id}/status'),
27
            ManagedRoute::delete('fragment-delete', 'fragment/{fragment_id}'),
28
            ManagedRoute::get('fragment-create', 'fragment/{fragmentowner_type}/{fragmentowner_id}/create'),
29
            ManagedRoute::post('fragment-store', 'fragment/{fragmentowner_type}/{fragmentowner_id}'),
30
        ];
31
    }
32
33
    public function routeFragmentAssistant(string $action, $model = null, ...$parameters): ?string
34
    {
35
        if(!in_array($action, ['fragment-edit','fragment-update','fragment-delete','fragment-create','fragment-store', 'fragment-status'])) {
36
            return null;
37
        }
38
39
        $modelKey = $this->managedModelClass()::managedModelKey();
0 ignored issues
show
Bug introduced by
It seems like managedModelClass() 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

39
        $modelKey = $this->/** @scrutinizer ignore-call */ managedModelClass()::managedModelKey();
Loading history...
40
41
        if(in_array($action, ['fragment-create', 'fragment-store'])) {
42
            if (!$model || !$model instanceof FragmentsOwner) {
43
                throw new \Exception('Fragment route definition for '.$action.' requires the owning Model as second argument.');
44
            }
45
46
            return route('chief.' . $modelKey . '.' . $action, array_merge([
47
                $model::managedModelKey(),
48
                $model->modelReference()->id(),
49
            ], $parameters));
50
        }
51
52
        if (!$model || !$model instanceof Fragmentable) {
53
            throw new \Exception('Fragment route definition for '.$action.' requires the fragment model as second argument.');
54
        }
55
56
        return route('chief.' . $modelKey . '.' . $action, $model->fragmentModel()->id);
57
    }
58
59
    public function canFragmentAssistant(string $action, $model = null): bool
60
    {
61
        return in_array($action, ['fragment-edit','fragment-update','fragment-delete','fragment-create','fragment-store', 'fragment-status']);
62
    }
63
64
    public function fragmentCreate(Request $request, string $ownerKey, $ownerId)
65
    {
66
        $owner = $this->owner($ownerKey, $ownerId);
67
        $fragmentable = $this->fragmentable();
68
69
        return view('chief::managers.fragments.create', [
70
            'manager'    => $this,
71
            'owner'      => $owner,
72
            'model'      => $fragmentable,
73
            'fields'     => $fragmentable->fields()->notTagged('edit'),
74
        ]);
75
    }
76
77
    public function fragmentStore(Request $request, string $ownerKey, $ownerId)
78
    {
79
        $this->guard('fragment-store');
80
81
        $owner = $this->owner($ownerKey, $ownerId);
82
        $fragmentable = $this->fragmentable();
83
84
        $this->fieldValidator()->handle($fragmentable->fields()->notTagged('edit'), $request->all());
85
86
        // TODO: pass order with request
87
        $request->merge(['order' => 1]);
88
89
        $this->storeFragmentable($owner, $fragmentable, $request);
90
91
        // TODO: savefields for static fragment
92
        // Allow relations, translations, assets, ...
93
94
        return response()->json([
95
            'message' => 'fragment created',
96
            'data' => [],
97
        ], 201);
98
    }
99
100
    private function storeFragmentable(FragmentsOwner $owner, Fragmentable $fragmentable, Request $request): void
101
    {
102
        $fragmentable->saveFields($fragmentable->fields()->notTagged('edit'), $request->all(), $request->allFiles());
103
104
        $fragmentable->setFragmentModel(
105
            app(CreateFragmentModel::class)->create($owner, $fragmentable, $request->order)
106
        );
107
    }
108
109
    public function fragmentEdit(Request $request, string $fragmentId)
110
    {
111
        $this->guard('fragment-edit');
112
113
        $fragmentable = $this->fragmentRepository->findFragment($fragmentId);
114
115
        return view('chief::managers.fragments.edit', [
116
            'manager'    => $this,
117
            'model'      => $fragmentable,
118
            'fields'     => $fragmentable->fields()->notTagged('create')->model($this->fragmentModel($fragmentable)),
119
        ]);
120
    }
121
122
    public function fragmentUpdate(Request $request, string $fragmentId)
123
    {
124
        $this->guard('fragment-update');
125
126
        $fragmentable = $this->fragmentRepository->findFragment($fragmentId);
127
128
        $this->fieldValidator()->handle($fragmentable->fields()->notTagged('create'), $request->all());
129
130
        // TODO: pass order with request
131
//        $request->merge(['order' => 1]);
132
133
        $this->fragmentModel($fragmentable)->saveFields($fragmentable->fields()->notTagged('create'), $request->all(), $request->allFiles());
134
135
        return response()->json([
136
            'message' => 'fragment updated',
137
            'data' => [],
138
        ], 200);
139
    }
140
141
    public function fragmentStatus(Request $request, string $fragmentId)
142
    {
143
        $this->guard('fragment-update');
144
145
        $fragmentable = $this->fragmentRepository->findFragment($fragmentId);
146
147
        $fragmentable->fragmentModel()->update(['online_status' => !!$request->input('online_status')]);
148
149
        return response()->json([
150
            'message' => 'fragment online status updated',
151
            'data' => [],
152
        ]);
153
    }
154
155
    public function fragmentDelete($id, Request $request)
156
    {
157
        $this->guard('fragment-delete');
158
159
        $model = $this->managedModelClass()::findOrFail($id);
160
161
        if ($request->get('deleteconfirmation') !== 'DELETE') {
162
            return redirect()->back()->with('messages.warning', $model->adminLabel('title') . ' is niet verwijderd.');
163
        }
164
165
        app(DeleteModel::class)->handle($model);
166
167
        return redirect()->to($this->route('index'))
0 ignored issues
show
Bug introduced by
It seems like route() 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

167
        return redirect()->to($this->/** @scrutinizer ignore-call */ route('index'))
Loading history...
168
            ->with('messages.success', '<i class="fa fa-fw fa-check-circle"></i>  "' . $model->adminLabel('title') . '" is verwijderd.');
169
    }
170
171
    private function owner(string $ownerKey, $ownerId): FragmentsOwner
172
    {
173
        $ownerClass = app(Registry::class)->modelClass($ownerKey);
174
175
        return $ownerClass::find($ownerId);
176
    }
177
178
    /**
179
     * Which fragment model will the fields be saved to? This can be overwritten so that
180
     * also static fragments can store their values on the fragmentModel.
181
     */
182
    private function fragmentModel(Fragmentable $fragmentable)
183
    {
184
        return $fragmentable;
185
    }
186
187
    private function fragmentable(): Fragmentable
188
    {
189
        $modelClass = $this->managedModelClass();
190
191
        return new $modelClass();
192
    }
193
}
194