Passed
Push — 0.3 ( 9a1703...7b1086 )
by Philippe
42:07
created

PageManager   A

Complexity

Total Complexity 32

Size/Duplication

Total Lines 219
Duplicated Lines 0 %

Test Coverage

Coverage 97.25%

Importance

Changes 22
Bugs 9 Features 1
Metric Value
wmc 32
eloc 97
c 22
b 9
f 1
dl 0
loc 219
ccs 106
cts 109
cp 0.9725
rs 9.84

15 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A delete() 0 7 2
A filters() 0 4 1
A details() 0 11 2
A saveFields() 0 8 2
A pageBuilderField() 0 7 2
A storeRequest() 0 20 5
A can() 0 9 2
A updateRequest() 0 18 3
A authorize() 0 14 5
A addDefaultShortDescription() 0 7 2
A fields() 0 25 1
A afterUpdate() 0 5 1
A fieldArrangement() 0 16 2
A afterStore() 0 5 1
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\Fields\Fields;
9
use Thinktomorrow\Chief\Filters\Filters;
10
use Thinktomorrow\Chief\Fields\FieldsTab;
11
use Thinktomorrow\Chief\Management\Manager;
12
use Thinktomorrow\Chief\Fields\Types\TextField;
13
use Thinktomorrow\Chief\Fields\FieldArrangement;
14
use Thinktomorrow\Chief\Fields\Types\InputField;
15
use Thinktomorrow\Chief\Fields\Types\MediaField;
16
use Thinktomorrow\Chief\Management\Registration;
17
use Thinktomorrow\Chief\Fields\RemainingFieldsTab;
18
use Thinktomorrow\Chief\Management\AbstractManager;
19
use Thinktomorrow\Chief\Management\Assistants\ArchiveAssistant;
20
use Thinktomorrow\Chief\Management\Assistants\PublishAssistant;
21
use Thinktomorrow\Chief\Management\Assistants\UrlAssistant;
22
use Thinktomorrow\Chief\Management\Details\Details;
23
use Thinktomorrow\Chief\Pages\Application\DeletePage;
24
use Thinktomorrow\Chief\Management\Exceptions\DeleteAborted;
25
use Thinktomorrow\Chief\Management\Exceptions\NotAllowedManagerRoute;
26
use Thinktomorrow\Chief\Urls\UrlRecord;
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 72
    public function __construct(Registration $registration)
41
    {
42 72
        parent::__construct($registration);
43 72
    }
44
45 66
    public function can($verb): bool
46
    {
47
        try {
48 66
            $this->authorize($verb);
49 1
        } catch (NotAllowedManagerRoute $e) {
50 1
            return false;
51
        }
52
53 65
        return parent::can($verb);
54
    }
55
56
    /**
57
     * @param $verb
58
     * @throws NotAllowedManagerRoute
59
     */
60 66
    private function authorize($verb)
61
    {
62 66
        $permission = 'update-page';
63
64 66
        if (in_array($verb, ['index','show'])) {
65 17
            $permission = 'view-page';
66 53
        } elseif (in_array($verb, ['create','store'])) {
67 17
            $permission = 'create-page';
68 40
        } elseif (in_array($verb, ['delete'])) {
69 4
            $permission = 'delete-page';
70
        }
71
72 66
        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 65
    }
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 43
    public function fields(): Fields
87
    {
88 43
        return parent::fields()->add(
89 43
            $this->pageBuilderField(),
90 43
            InputField::make('title')->translatable($this->model->availableLocales())
0 ignored issues
show
Bug introduced by
The method availableLocales() 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

90
            InputField::make('title')->translatable($this->model->/** @scrutinizer ignore-call */ availableLocales())

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...
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 43
                                     ->validation('required-fallback-locale|max:200', [], [
92 43
                                         'trans.'.config('app.fallback_locale', 'nl').'.title' => 'title',
93
                                     ])
94 43
                                     ->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 43
                                     ->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 43
            InputField::make('seo_title')
97 43
                ->translatable($this->model->availableLocales())
98 43
                ->label('Zoekmachine titel'),
99 43
            TextField::make('seo_description')
100 43
                ->translatable($this->model->availableLocales())
101 43
                ->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 43
                ->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 43
            InputField::make('seo_keywords')
104 43
                ->translatable($this->model->availableLocales())
105 43
                ->label('Zoekmachine sleutelwoorden')
106 43
                ->description('sleutelwoorden van de pagina waarop in search engines (o.a google) gezocht kan worden.'),
107 43
            MediaField::make('seo_image')
108 43
                ->translatable($this->model->availableLocales())
109 43
                ->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

109
                ->/** @scrutinizer ignore-call */ label('Zoekmachine foto')
Loading history...
110 43
                ->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

110
                ->/** @scrutinizer ignore-call */ description('foto die bij het delen van deze pagina getoont word. (afmeting: 1200x627px)')
Loading history...
111
        );
112
    }
113
114
    public static function filters(): Filters
115
    {
116
        return new Filters([
117
            PublishedFilter::class
118
        ]);
119
    }
120
121 43
    private function pageBuilderField()
122
    {
123 43
        if ($this->pageBuilderField) {
124 38
            return $this->pageBuilderField;
125
        }
126
127 43
        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...
128
    }
129
130 2
    public function fieldArrangement($key = null): FieldArrangement
131
    {
132 2
        if ($key == 'create') {
133
            return new FieldArrangement($this->fieldsWithAssistantFields()->filterBy(function ($field) {
134 1
                return in_array($field->key, ['title']);
135 1
            }));
136
        }
137
138 1
        return new FieldArrangement($this->fieldsWithAssistantFields(), [
139 1
            new FieldsTab('url', ['url-slugs'], 'chief::back.pages._partials.url', [
140 1
                'redirects' =>  UrlSlugFields::redirectsFromModel($this->model),
0 ignored issues
show
Bug introduced by
It seems like $this->model can also be of type Illuminate\Contracts\Foundation\Application; however, parameter $model of Thinktomorrow\Chief\Urls...s::redirectsFromModel() does only seem to accept Thinktomorrow\Chief\Urls\ProvidesUrl\ProvidesUrl, 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

140
                'redirects' =>  UrlSlugFields::redirectsFromModel(/** @scrutinizer ignore-type */ $this->model),
Loading history...
141
            ]),
142 1
            new RemainingFieldsTab('inhoud'),
143 1
            new FieldsTab('pagina', ['sections']),
144 1
            new FieldsTab('modules', [], 'chief::back.pages._partials.modules'),
145 1
            new FieldsTab('seo', ['seo_title', 'seo_description', 'seo_keywords', 'seo_image']),
146
        ]);
147
    }
148
149 66
    public function details(): Details
150
    {
151
        // For existing model
152 66
        if ($this->model->id) {
153 52
            return parent::details()
154 52
                ->set('title', $this->model->title)
155 52
                ->set('intro', 'Aangepast ' . $this->model->updated_at->format('d/m/Y H:i'))
156 52
                ->set('context', '<span class="inline-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

156
                ->set('context', '<span class="inline-s">' . $this->assistant('publish')->/** @scrutinizer ignore-call */ publicationStatusAsLabel() . '</span>');
Loading history...
157
        }
158
159 17
        return parent::details();
160
    }
161
162 44
    public function saveFields(): Manager
163
    {
164
        // Store the morph_key upon creation
165 44
        if (! $this->model->morph_key) {
166 14
            $this->model->morph_key = $this->model->morphKey();
0 ignored issues
show
Bug introduced by
The method morphKey() 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

166
            /** @scrutinizer ignore-call */ 
167
            $this->model->morph_key = $this->model->morphKey();

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...
167
        }
168
169 44
        return parent::saveFields();
170
    }
171
172 4
    public function delete()
173
    {
174 4
        if (request()->get('deleteconfirmation') !== 'DELETE') {
175 1
            throw new DeleteAborted();
176
        }
177
178 3
        app(DeletePage::class)->handle($this->model->id);
179 3
    }
180
181 16
    public function storeRequest(Request $request): Request
182
    {
183 16
        $trans = [];
184 16
        $urls = $request->get('url-slugs', []);
185
186 16
        foreach ($request->get('trans', []) as $locale => $translation) {
187 15
            if (is_array_empty($translation)) {
188 1
                continue;
189
            }
190
191 15
            $trans[$locale] = $this->addDefaultShortDescription($translation);
192
193
            // Automatically add an url for this locale based on the given title
194 15
            if (!isset($urls[$locale]) && isset($translation['title'])) {
195 15
                $urls[$locale] = Str::slug($translation['title']);
196
            }
197
        }
198
199
        // Merge with request...
200 16
        return $request->merge(['trans' => $trans, 'url-slugs' => $urls]);
201
    }
202
203 35
    public function updateRequest(Request $request): Request
204
    {
205 35
        $trans = [];
206 35
        foreach ($request->get('trans', []) as $locale => $translation) {
207 34
            if (is_array_empty($translation)) {
208
209
                // Nullify all values
210
                $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

210
                $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...
211 2
                    return null;
212 2
                }, $translation);
213 2
                continue;
214
            }
215
216 34
            $trans[$locale] = $this->addDefaultShortDescription($translation);
217
        }
218
219
        // Merge with request...
220 35
        return $request->merge(['trans' => $trans]);
221
    }
222
223 14
    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

223
    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...
224
    {
225 14
        Audit::activity()
226 14
            ->performedOn($this->model)
0 ignored issues
show
Bug introduced by
It seems like $this->model can also be of type Illuminate\Contracts\Foundation\Application; however, parameter $model of Spatie\Activitylog\ActivityLogger::performedOn() does only seem to accept Illuminate\Database\Eloquent\Model, 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

226
            ->performedOn(/** @scrutinizer ignore-type */ $this->model)
Loading history...
227 14
            ->log('created');
228 14
    }
229
230 33
    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

230
    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...
231
    {
232 33
        Audit::activity()
233 33
            ->performedOn($this->model)
0 ignored issues
show
Bug introduced by
It seems like $this->model can also be of type Illuminate\Contracts\Foundation\Application; however, parameter $model of Spatie\Activitylog\ActivityLogger::performedOn() does only seem to accept Illuminate\Database\Eloquent\Model, 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

233
            ->performedOn(/** @scrutinizer ignore-type */ $this->model)
Loading history...
234 33
            ->log('edited');
235 33
    }
236
237
    /**
238
     * @param array $translation
239
     * @return array
240
     */
241 46
    private function addDefaultShortDescription(array $translation): array
242
    {
243 46
        if (isset($translation['content'])) {
244 1
            $translation['short'] = $translation['short'] ?? teaser($translation['content'], 100);
245
        }
246
247 46
        return $translation;
248
    }
249
}
250