Completed
Pull Request — master (#274)
by
unknown
63:55 queued 33:13
created

PageManager::storeRequest()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 20
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 5

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 9
c 1
b 0
f 0
dl 0
loc 20
ccs 10
cts 10
cp 1
rs 9.6111
cc 5
nc 4
nop 1
crap 5
1
<?php
2
3
namespace Thinktomorrow\Chief\Pages;
4
5
use Illuminate\Http\Request;
6
use Illuminate\Support\Str;
7
use Thinktomorrow\Chief\Audit\Audit;
8
use Thinktomorrow\Chief\Concerns\Morphable\MorphableContract;
9
use Thinktomorrow\Chief\Fields\Fields;
10
use Thinktomorrow\Chief\Filters\Filters;
11
use Thinktomorrow\Chief\Fields\FieldsTab;
12
use Thinktomorrow\Chief\Management\Manager;
13
use Thinktomorrow\Chief\Fields\Types\TextField;
14
use Thinktomorrow\Chief\Fields\FieldArrangement;
15
use Thinktomorrow\Chief\Fields\Types\InputField;
16
use Thinktomorrow\Chief\Fields\Types\MediaField;
17
use Thinktomorrow\Chief\Management\Registration;
18
use Thinktomorrow\Chief\Fields\RemainingFieldsTab;
19
use Thinktomorrow\Chief\Management\AbstractManager;
20
use Thinktomorrow\Chief\Management\Assistants\ArchiveAssistant;
21
use Thinktomorrow\Chief\Management\Assistants\PublishAssistant;
22
use Thinktomorrow\Chief\Management\Assistants\UrlAssistant;
23
use Thinktomorrow\Chief\Management\Details\Details;
24
use Thinktomorrow\Chief\Pages\Application\DeletePage;
25
use Thinktomorrow\Chief\Management\Exceptions\DeleteAborted;
26
use Thinktomorrow\Chief\Management\Exceptions\NotAllowedManagerRoute;
27
use Thinktomorrow\Chief\Urls\UrlSlugFields;
28
29
class PageManager extends AbstractManager implements Manager
30
{
31
    /** @var PageBuilderField */
0 ignored issues
show
Bug introduced by
The type Thinktomorrow\Chief\Pages\PageBuilderField was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
32
    private $pageBuilderField;
33
34
    protected $assistants = [
35
        'url'     => UrlAssistant::class,
36
        'archive' => ArchiveAssistant::class,
37
        'publish' => PublishAssistant::class,
38
    ];
39
40 84
    public function __construct(Registration $registration)
41
    {
42 84
        parent::__construct($registration);
43 84
    }
44
45 76
    public function can($verb): bool
46
    {
47
        try {
48 76
            $this->authorize($verb);
49 1
        } catch (NotAllowedManagerRoute $e) {
50 1
            return false;
51
        }
52
53 75
        return parent::can($verb);
54
    }
55
56
    /**
57
     * @param $verb
58
     * @throws NotAllowedManagerRoute
59
     */
60 76
    private function authorize($verb)
61
    {
62 76
        $permission = 'update-page';
63
64 76
        if (in_array($verb, ['index','show'])) {
65 22
            $permission = 'view-page';
66 59
        } elseif (in_array($verb, ['create','store'])) {
67 19
            $permission = 'create-page';
68 45
        } elseif (in_array($verb, ['delete'])) {
69 4
            $permission = 'delete-page';
70
        }
71
72 76
        if (! auth()->guard('chief')->user()->hasPermissionTo($permission)) {
0 ignored issues
show
Bug introduced by
The method hasPermissionTo() does not exist on Illuminate\Contracts\Auth\Authenticatable. It seems like you code against a sub-type of Illuminate\Contracts\Auth\Authenticatable such as Illuminate\Foundation\Auth\User. ( Ignorable by Annotation )

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

72
        if (! auth()->guard('chief')->user()->/** @scrutinizer ignore-call */ hasPermissionTo($permission)) {
Loading history...
73 1
            throw NotAllowedManagerRoute::notAllowedPermission($permission, $this);
74
        }
75 75
    }
76
77
    /**
78
     * The set of fields that should be manageable for a certain model.
79
     *
80
     * Additionally, you should:
81
     * 1. Make sure to setup the proper migrations and
82
     * 2. For a translatable field you should add this field to the $translatedAttributes property of the model as well.
83
     *
84
     * @return Fields
85
     */
86 47
    public function fields(): Fields
87
    {
88 47
        return parent::fields()->add(
89 47
            $this->pageBuilderField(),
90 47
            InputField::make('title')->translatable($this->model->availableLocales())
0 ignored issues
show
Bug introduced by
It seems like Thinktomorrow\Chief\Fiel...erzichten en modules.') can also be of type null; however, parameter $fields of Thinktomorrow\Chief\Fields\Fields::add() does only seem to accept Thinktomorrow\Chief\Fields\Types\Field, maybe add an additional type check? ( Ignorable by Annotation )

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

90
            /** @scrutinizer ignore-type */ InputField::make('title')->translatable($this->model->availableLocales())
Loading history...
91 47
                                     ->validation('required-fallback-locale|max:200', [], [
92 47
                                         'trans.'.config('app.fallback_locale', 'nl').'.title' => 'title',
93
                                     ])
94 47
                                     ->label('De titel van je '.$this->model->labelSingular ?? 'pagina')
0 ignored issues
show
Bug introduced by
The method label() does not exist on Thinktomorrow\Chief\Fields\Types\InputField. 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

94
                                     ->/** @scrutinizer ignore-call */ label('De titel van je '.$this->model->labelSingular ?? 'pagina')
Loading history...
95 47
                                     ->description('Dit is de titel die zal worden getoond in de overzichten en modules.'),
0 ignored issues
show
Bug introduced by
The method description() does not exist on Thinktomorrow\Chief\Fields\Types\InputField. 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

95
                                     ->/** @scrutinizer ignore-call */ description('Dit is de titel die zal worden getoond in de overzichten en modules.'),
Loading history...
96 47
            InputField::make('seo_title')
97 47
                ->translatable($this->model->availableLocales())
98 47
                ->label('Zoekmachine titel'),
99 47
            TextField::make('seo_description')
100 47
                ->translatable($this->model->availableLocales())
101 47
                ->label('Zoekmachine omschrijving')
0 ignored issues
show
Bug introduced by
The method label() does not exist on Thinktomorrow\Chief\Fields\Types\TextField. 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

101
                ->/** @scrutinizer ignore-call */ label('Zoekmachine omschrijving')
Loading history...
102 47
                ->description('omschrijving van de pagina zoals in search engines (o.a. google) wordt weergegeven.'),
0 ignored issues
show
Bug introduced by
The method description() does not exist on Thinktomorrow\Chief\Fields\Types\TextField. 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

102
                ->/** @scrutinizer ignore-call */ description('omschrijving van de pagina zoals in search engines (o.a. google) wordt weergegeven.'),
Loading history...
103 47
            InputField::make('seo_keywords')
104 47
                ->validation('max:250')
105 47
                ->translatable($this->model->availableLocales())
106 47
                ->label('Zoekmachine sleutelwoorden')
107 47
                ->description('sleutelwoorden van de pagina waarop in search engines (o.a google) gezocht kan worden.'),
108 47
            MediaField::make('seo_image')
109 47
                ->translatable($this->model->availableLocales())
110 47
                ->label('Zoekmachine foto')
0 ignored issues
show
Bug introduced by
The method label() does not exist on Thinktomorrow\Chief\Fields\Types\MediaField. 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

110
                ->/** @scrutinizer ignore-call */ label('Zoekmachine foto')
Loading history...
111 47
                ->description('foto die bij het delen van deze pagina getoont word. (afmeting: 1200x627px)')
0 ignored issues
show
Bug introduced by
The method description() does not exist on Thinktomorrow\Chief\Fields\Types\MediaField. 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

111
                ->/** @scrutinizer ignore-call */ description('foto die bij het delen van deze pagina getoont word. (afmeting: 1200x627px)')
Loading history...
112
        );
113
    }
114
115 1
    public static function filters(): Filters
116
    {
117 1
        return new Filters([
118 1
            PublishedFilter::class
119
        ]);
120
    }
121
122 47
    private function pageBuilderField()
123
    {
124 47
        if ($this->pageBuilderField) {
125 40
            return $this->pageBuilderField;
126
        }
127
128 47
        return $this->pageBuilderField = $this->createPagebuilderField();
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->createPagebuilderField() of type Thinktomorrow\Chief\Fields\Types\PagebuilderField is incompatible with the declared type Thinktomorrow\Chief\Pages\PageBuilderField of property $pageBuilderField.

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...
129
    }
130
131 2
    public function fieldArrangement($key = null): FieldArrangement
132
    {
133 2
        if ($key == 'create') {
134
            return new FieldArrangement($this->fieldsWithAssistantFields()->filterBy(function ($field) {
135 1
                return in_array($field->key, ['title']);
136 1
            }));
137
        }
138
139 1
        return new FieldArrangement($this->fieldsWithAssistantFields(), [
140 1
            new FieldsTab('pagina', ['sections']),
141 1
            new FieldsTab('modules', [], 'chief::back.pages._partials.modules'),
142 1
            new RemainingFieldsTab('algemeen'),
143 1
            new FieldsTab('url', ['url-slugs'], 'chief::back.pages._partials.url', [
144 1
                'redirects' =>  UrlSlugFields::redirectsFromModel($this->model),
145
            ]),
146 1
            new FieldsTab('seo', ['seo_title', 'seo_description', 'seo_keywords', 'seo_image']),
147
        ]);
148
    }
149
150 78
    public function details(): Details
151
    {
152
        // For existing model
153 78
        if ($this->model->id) {
154 60
            return parent::details()
155 60
                ->set('title', ucfirst($this->model->title))
156 60
                ->set('intro', 'Aangepast ' . $this->model->updated_at->format('d/m/Y H:i'))
157 60
                ->set('context', '<span class="inline-xs stack-s">' . $this->assistant('publish')->publicationStatusAsLabel() . '</span>');
0 ignored issues
show
Bug introduced by
The method publicationStatusAsLabel() does not exist on Thinktomorrow\Chief\Mana...nt\Assistants\Assistant. It seems like you code against a sub-type of Thinktomorrow\Chief\Mana...nt\Assistants\Assistant such as Thinktomorrow\Chief\Mana...stants\PublishAssistant. ( Ignorable by Annotation )

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

157
                ->set('context', '<span class="inline-xs stack-s">' . $this->assistant('publish')->/** @scrutinizer ignore-call */ publicationStatusAsLabel() . '</span>');
Loading history...
158
        }
159
160 22
        return parent::details();
161
    }
162
163 49
    public function saveFields(Request $request)
164
    {
165
        // Store the morph_key upon creation
166 49
        if ($this->model instanceof MorphableContract && ! $this->model->morph_key) {
0 ignored issues
show
Bug introduced by
Accessing morph_key on the interface Thinktomorrow\Chief\Conc...hable\MorphableContract suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
167 15
            $this->model->morph_key = $this->model->morphKey();
168
        }
169
170 49
        parent::saveFields($request);
171 49
    }
172
173 4
    public function delete()
174
    {
175 4
        if (request()->get('deleteconfirmation') !== 'DELETE') {
176 1
            throw new DeleteAborted();
177
        }
178
179 3
        app(DeletePage::class)->handle($this->model->id);
180 3
    }
181
182 17
    public function storeRequest(Request $request): Request
183
    {
184 17
        $trans = [];
185 17
        $urls = $request->get('url-slugs', []);
186
187 17
        foreach ($request->get('trans', []) as $locale => $translation) {
188 16
            if (is_array_empty($translation)) {
189 1
                continue;
190
            }
191
192 16
            $trans[$locale] = $this->addDefaultShortDescription($translation);
193
194
            // Automatically add an url for this locale based on the given title
195 16
            if (!isset($urls[$locale]) && isset($translation['title'])) {
196 16
                $urls[$locale] = Str::slug($translation['title']);
197
            }
198
        }
199
200
        // Merge with request...
201 17
        return $request->merge(['trans' => $trans, 'url-slugs' => $urls]);
202
    }
203
204 39
    public function updateRequest(Request $request): Request
205
    {
206 39
        $trans = [];
207 39
        foreach ($request->get('trans', []) as $locale => $translation) {
208 38
            if (is_array_empty($translation)) {
209
210
                // Nullify all values
211
                $trans[$locale] = array_map(function ($value) {
0 ignored issues
show
Unused Code introduced by
The parameter $value 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

211
                $trans[$locale] = array_map(function (/** @scrutinizer ignore-unused */ $value) {

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...
212 2
                    return null;
213 2
                }, $translation);
214 2
                continue;
215
            }
216
217 38
            $trans[$locale] = $this->addDefaultShortDescription($translation);
218
        }
219
220
        // Merge with request...
221 39
        return $request->merge(['trans' => $trans]);
222
    }
223
224 15
    public function afterStore($request)
0 ignored issues
show
Unused Code introduced by
The parameter $request 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

224
    public function afterStore(/** @scrutinizer ignore-unused */ $request)

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...
225
    {
226 15
        Audit::activity()
227 15
            ->performedOn($this->model)
228 15
            ->log('created');
229 15
    }
230
231 37
    public function afterUpdate($request)
0 ignored issues
show
Unused Code introduced by
The parameter $request 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

231
    public function afterUpdate(/** @scrutinizer ignore-unused */ $request)

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...
232
    {
233 37
        Audit::activity()
234 37
            ->performedOn($this->model)
235 37
            ->log('edited');
236 37
    }
237
238
    /**
239
     * @param array $translation
240
     * @return array
241
     */
242 51
    private function addDefaultShortDescription(array $translation): array
243
    {
244 51
        if (isset($translation['content'])) {
245 1
            $translation['short'] = $translation['short'] ?? teaser($translation['content'], 100);
246
        }
247
248 51
        return $translation;
249
    }
250
}
251