This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace GinoPane\BlogTaxonomy; |
||
4 | |||
5 | use Event; |
||
6 | use Input; |
||
7 | use Backend; |
||
8 | use Exception; |
||
9 | use Validator; |
||
10 | use System\Models\File; |
||
11 | use Backend\Widgets\Form; |
||
12 | use Backend\Widgets\Lists; |
||
13 | use Backend\Widgets\Filter; |
||
14 | use System\Classes\PluginBase; |
||
15 | use Backend\Classes\Controller; |
||
16 | use GinoPane\BlogTaxonomy\Models\Tag; |
||
17 | use GinoPane\BlogTaxonomy\Models\Series; |
||
18 | use Backend\Behaviors\RelationController; |
||
19 | use RainLab\Blog\Models\Post as PostModel; |
||
20 | use GinoPane\BlogTaxonomy\Models\Settings; |
||
21 | use GinoPane\BlogTaxonomy\Models\PostType; |
||
22 | use GinoPane\BlogTaxonomy\Components\TagList; |
||
23 | use GinoPane\BlogTaxonomy\Components\TagPosts; |
||
24 | use GinoPane\BlogTaxonomy\Components\SeriesList; |
||
25 | use GinoPane\BlogTaxonomy\Components\SeriesPosts; |
||
26 | use RainLab\Blog\Models\Category as CategoryModel; |
||
27 | use GinoPane\BlogTaxonomy\Components\RelatedPosts; |
||
28 | use GinoPane\BlogTaxonomy\Components\RelatedSeries; |
||
29 | use GinoPane\BlogTaxonomy\Console\MigrateFromPlugin; |
||
30 | use RainLab\Blog\Controllers\Posts as PostsController; |
||
31 | use GinoPane\BlogTaxonomy\Components\SeriesNavigation; |
||
32 | use RainLab\Blog\Controllers\Categories as CategoriesController; |
||
33 | |||
34 | /** |
||
35 | * Class Plugin |
||
36 | * |
||
37 | * @package GinoPane\BlogTaxonomy |
||
38 | */ |
||
39 | class Plugin extends PluginBase |
||
40 | { |
||
41 | const LOCALIZATION_KEY = 'ginopane.blogtaxonomy::lang.'; |
||
42 | |||
43 | const DIRECTORY_KEY = 'ginopane/blogtaxonomy'; |
||
44 | |||
45 | const REQUIRED_PLUGIN_RAINLAB_BLOG = 'RainLab.Blog'; |
||
46 | |||
47 | const DEFAULT_ICON = 'icon-sitemap'; |
||
48 | |||
49 | /** |
||
50 | * @var array Require the RainLab.Blog plugin |
||
51 | */ |
||
52 | public $require = [ |
||
53 | 'RainLab.Blog' |
||
54 | ]; |
||
55 | |||
56 | /** |
||
57 | * @var Settings |
||
58 | */ |
||
59 | private $settings; |
||
60 | |||
61 | /** |
||
62 | * Returns information about this plugin |
||
63 | * |
||
64 | * @return array |
||
65 | */ |
||
66 | public function pluginDetails(): array |
||
67 | { |
||
68 | return [ |
||
69 | 'name' => self::LOCALIZATION_KEY . 'plugin.name', |
||
70 | 'description' => self::LOCALIZATION_KEY . 'plugin.description', |
||
71 | 'author' => 'Siarhei <Gino Pane> Karavai', |
||
72 | 'icon' => self::DEFAULT_ICON, |
||
73 | 'homepage' => 'https://github.com/GinoPane/oc-blogtaxonomy-plugin' |
||
74 | ]; |
||
75 | } |
||
76 | |||
77 | /** |
||
78 | * Register components |
||
79 | * |
||
80 | * @return array |
||
81 | */ |
||
82 | public function registerComponents(): array |
||
83 | { |
||
84 | return [ |
||
85 | TagList::class => TagList::NAME, |
||
86 | TagPosts::class => TagPosts::NAME, |
||
87 | RelatedPosts::class => RelatedPosts::NAME, |
||
88 | SeriesList::class => SeriesList::NAME, |
||
89 | SeriesPosts::class => SeriesPosts::NAME, |
||
90 | SeriesNavigation::class => SeriesNavigation::NAME, |
||
91 | RelatedSeries::class => RelatedSeries::NAME |
||
92 | ]; |
||
93 | } |
||
94 | |||
95 | public function register() |
||
96 | { |
||
97 | $this->registerConsoleCommand(MigrateFromPlugin::NAME, MigrateFromPlugin::class); |
||
98 | } |
||
99 | |||
100 | /** |
||
101 | * Boot method, called right before the request route |
||
102 | */ |
||
103 | public function boot(): void |
||
104 | { |
||
105 | $this->extendValidator(); |
||
106 | |||
107 | $this->extendPostModel(); |
||
108 | |||
109 | $this->extendPostListColumns(); |
||
110 | |||
111 | $this->extendPostFilterScopes(); |
||
112 | |||
113 | $this->extendPostsController(); |
||
114 | |||
115 | $this->extendCategoriesModel(); |
||
116 | |||
117 | $this->extendCategoriesController(); |
||
118 | |||
119 | $this->extendCategoriesFormFields(); |
||
120 | } |
||
121 | |||
122 | private function getSettings(): Settings |
||
123 | { |
||
124 | return $this->settings ?: $this->settings = Settings::instance(); |
||
125 | } |
||
126 | |||
127 | /** |
||
128 | * Register plugin navigation |
||
129 | * - add tags and series menu items |
||
130 | * |
||
131 | * @return void |
||
132 | */ |
||
133 | public function registerNavigation(): void |
||
134 | { |
||
135 | // Extend the navigation |
||
136 | Event::listen('backend.menu.extendItems', function ($manager) { |
||
137 | $manager->addSideMenuItems(self::REQUIRED_PLUGIN_RAINLAB_BLOG, 'blog', [ |
||
138 | 'series' => [ |
||
139 | 'label' => self::LOCALIZATION_KEY . 'navigation.sidebar.series', |
||
140 | 'icon' => 'icon-list-alt', |
||
141 | 'code' => 'series', |
||
142 | 'owner' => self::REQUIRED_PLUGIN_RAINLAB_BLOG, |
||
143 | 'url' => Backend::url(self::DIRECTORY_KEY . '/series') |
||
144 | ], |
||
145 | |||
146 | 'tags' => [ |
||
147 | 'label' => self::LOCALIZATION_KEY . 'navigation.sidebar.tags', |
||
148 | 'icon' => 'icon-tags', |
||
149 | 'code' => 'tags', |
||
150 | 'owner' => self::REQUIRED_PLUGIN_RAINLAB_BLOG, |
||
151 | 'url' => Backend::url(self::DIRECTORY_KEY . '/tags') |
||
152 | ] |
||
153 | ]); |
||
154 | |||
155 | if ($this->getSettings()->postTypesEnabled()) { |
||
156 | $manager->addSideMenuItems(self::REQUIRED_PLUGIN_RAINLAB_BLOG, 'blog', [ |
||
157 | 'post_types' => [ |
||
158 | 'label' => self::LOCALIZATION_KEY . 'navigation.sidebar.post_types', |
||
159 | 'icon' => 'icon-cog', |
||
160 | 'code' => 'post_types', |
||
161 | 'owner' => self::REQUIRED_PLUGIN_RAINLAB_BLOG, |
||
162 | 'url' => Backend::url(self::DIRECTORY_KEY . '/posttypes') |
||
163 | ] |
||
164 | ]); |
||
165 | } |
||
166 | }); |
||
167 | } |
||
168 | |||
169 | /** |
||
170 | * Register plugin settings |
||
171 | * |
||
172 | * @return array |
||
173 | */ |
||
174 | public function registerSettings(): array |
||
175 | { |
||
176 | return [ |
||
177 | 'settings' => [ |
||
178 | 'label' => self::LOCALIZATION_KEY . 'plugin.name', |
||
179 | 'description' => self::LOCALIZATION_KEY . 'plugin.description', |
||
180 | 'icon' => self::DEFAULT_ICON, |
||
181 | 'class' => Settings::class, |
||
182 | 'order' => 100 |
||
183 | ] |
||
184 | ]; |
||
185 | } |
||
186 | |||
187 | /** |
||
188 | * Extend RainLab Post model |
||
189 | * - add tags relation |
||
190 | * - add series relation |
||
191 | * - add post type relation |
||
192 | * |
||
193 | * @return void |
||
194 | */ |
||
195 | private function extendPostModel(): void |
||
196 | { |
||
197 | PostModel::extend(function ($model) { |
||
198 | $model->morphToMany = [ |
||
199 | 'tags' => [Tag::class, 'name' => Tag::PIVOT_COLUMN] |
||
200 | ]; |
||
201 | |||
202 | $model->belongsTo['series'] = [ |
||
203 | Series::class, |
||
204 | 'key' => Series::TABLE_NAME . "_id" |
||
205 | ]; |
||
206 | |||
207 | if ($this->getSettings()->postTypesEnabled()) { |
||
208 | $model->belongsTo['post_type'] = [ |
||
209 | PostType::class, |
||
210 | 'key' => PostType::TABLE_NAME . "_id" |
||
211 | ]; |
||
212 | |||
213 | $model->addJsonable(PostType::TABLE_NAME. '_attributes'); |
||
214 | |||
215 | $model->addDynamicMethod('typeAttributes', function () use ($model) { |
||
216 | if (!empty($model->post_type->id)) { |
||
217 | $rawFields = $model->{PostType::TABLE_NAME. '_attributes'}[0] ?? []; |
||
218 | $prefix = $model->post_type->id.'.'; |
||
219 | $fields = []; |
||
220 | |||
221 | foreach ($rawFields as $code => $value) { |
||
222 | if (strpos($code, $prefix) === 0) { |
||
223 | $fields[str_replace($prefix, '', $code)] = $value; |
||
224 | } |
||
225 | } |
||
226 | |||
227 | return $fields; |
||
228 | } |
||
229 | |||
230 | return []; |
||
231 | }); |
||
232 | |||
233 | $model->addDynamicMethod('typeAttribute', function (string $code) use ($model) { |
||
234 | if (!empty($model->post_type->id)) { |
||
235 | $attributeKey = sprintf('%s.%s', $model->post_type->id, $code); |
||
236 | |||
237 | return $model->{PostType::TABLE_NAME. '_attributes'}[0][$attributeKey] ?? null; |
||
238 | } |
||
239 | |||
240 | return $model->post_type->id; |
||
241 | }); |
||
242 | |||
243 | $model->addDynamicMethod('scopeFilterPostTypes', function ($query, array $types) { |
||
244 | return $query->whereHas('post_type', function ($query) use ($types) { |
||
245 | $query->whereIn('id', $types); |
||
246 | }); |
||
247 | }); |
||
248 | } |
||
249 | }); |
||
250 | } |
||
251 | |||
252 | /** |
||
253 | * Extends post controller functionality |
||
254 | * - transform categories into taglist and move then into taxonomy tab |
||
255 | * - add tags and series properties |
||
256 | * |
||
257 | * @throws Exception |
||
258 | * |
||
259 | * @return void |
||
260 | */ |
||
261 | private function extendPostsController(): void |
||
262 | { |
||
263 | PostsController::extendFormFields(function (Form $form, $model) { |
||
264 | if (!$model instanceof PostModel) { |
||
0 ignored issues
–
show
|
|||
265 | return; |
||
266 | } |
||
267 | |||
268 | /* |
||
269 | * When extending the form, you should check to see if $formWidget->isNested === false |
||
270 | * as the Repeater FormWidget includes nested Form widgets which can cause your changes |
||
271 | * to be made in unexpected places. |
||
272 | * |
||
273 | * @link https://octobercms.com/docs/plugin/extending#extending-backend-form |
||
274 | */ |
||
275 | if (!empty($form->isNested)) { |
||
276 | return; |
||
277 | } |
||
278 | |||
279 | $tab = self::LOCALIZATION_KEY . 'navigation.tab.taxonomy'; |
||
280 | |||
281 | $categoriesConfig = $this->transformPostCategoriesIntoTaglist($form, $tab); |
||
282 | |||
283 | $form->addSecondaryTabFields([ |
||
284 | 'categories' => $categoriesConfig, |
||
285 | 'tags' => [ |
||
286 | 'label' => self::LOCALIZATION_KEY . 'form.tags.label', |
||
287 | 'comment' => self::LOCALIZATION_KEY . 'form.tags.comment_post', |
||
288 | 'mode' => 'relation', |
||
289 | 'tab' => $tab, |
||
290 | 'type' => 'taglist', |
||
291 | 'placeholder' => self::LOCALIZATION_KEY . 'placeholders.tags', |
||
292 | ], |
||
293 | 'series' => [ |
||
294 | 'label' => self::LOCALIZATION_KEY . 'form.series.label', |
||
295 | 'tab' => $tab, |
||
296 | 'type' => 'relation', |
||
297 | 'nameFrom' => 'title', |
||
298 | 'comment' => self::LOCALIZATION_KEY . 'form.series.comment', |
||
299 | 'placeholder' => self::LOCALIZATION_KEY . 'placeholders.series' |
||
300 | ], |
||
301 | ]); |
||
302 | |||
303 | if ($this->getSettings()->postTypesEnabled()) { |
||
304 | $this->addPostTypeAttributes($form, $model); |
||
305 | } |
||
306 | }); |
||
307 | } |
||
308 | |||
309 | /** |
||
310 | * Extends categories controller functionality |
||
311 | */ |
||
312 | private function extendCategoriesController(): void |
||
313 | { |
||
314 | CategoriesController::extend(function (Controller $controller) { |
||
315 | $controller->implement[] = RelationController::class; |
||
316 | $relationConfig = '$/' . self::DIRECTORY_KEY . '/controllers/category/config_relation.yaml'; |
||
317 | |||
318 | if (property_exists($controller, 'relationConfig')) { |
||
319 | $controller->relationConfig = $controller->mergeConfig( |
||
320 | $controller->relationConfig, |
||
321 | $relationConfig |
||
322 | ); |
||
323 | } else { |
||
324 | $controller->addDynamicProperty('relationConfig', $relationConfig); |
||
325 | } |
||
326 | |||
327 | $formConfig = '$/' . self::DIRECTORY_KEY . '/controllers/category/config_form.yaml'; |
||
328 | |||
329 | if (property_exists($controller, 'formConfig')) { |
||
330 | $controller->formConfig = $controller->mergeConfig( |
||
331 | $controller->formConfig, |
||
332 | $formConfig |
||
333 | ); |
||
334 | } else { |
||
335 | $controller->addDynamicProperty('formConfig', $formConfig); |
||
336 | } |
||
337 | }); |
||
338 | } |
||
339 | |||
340 | private function extendCategoriesModel(): void |
||
341 | { |
||
342 | CategoryModel::extend(function ($model) { |
||
343 | if ($this->getSettings()->postCategoriesCoverImageEnabled()) { |
||
344 | $model->attachOne['cover_image'] = [ |
||
345 | File::class, 'delete' => true |
||
346 | ]; |
||
347 | } |
||
348 | |||
349 | if ($this->getSettings()->postCategoriesFeaturedImagesEnabled()) { |
||
350 | $model->attachMany['featured_images'] = [ |
||
351 | File::class, 'order' => 'sort_order', 'delete' => true |
||
352 | ]; |
||
353 | } |
||
354 | }); |
||
355 | } |
||
356 | |||
357 | private function extendCategoriesFormFields(): void |
||
358 | { |
||
359 | CategoriesController::extendFormFields(function ($form, $model) { |
||
360 | if (!$model instanceof CategoryModel) { |
||
0 ignored issues
–
show
The class
RainLab\Blog\Models\Category does not exist. Did you forget a USE statement, or did you not list all dependencies?
This error could be the result of: 1. Missing dependenciesPHP Analyzer uses your Are you sure this class is defined by one of your dependencies, or did you maybe
not list a dependency in either the 2. Missing use statementPHP does not complain about undefined classes in if ($x instanceof DoesNotExist) {
// Do something.
}
If you have not tested against this specific condition, such errors might go unnoticed. ![]() |
|||
361 | return; |
||
362 | } |
||
363 | |||
364 | if ($this->getSettings()->postCategoriesCoverImageEnabled() || |
||
365 | $this->getSettings()->postCategoriesFeaturedImagesEnabled() |
||
366 | ) { |
||
367 | $form->addFields([ |
||
368 | 'images_section' => [ |
||
369 | 'label' => self::LOCALIZATION_KEY . 'form.categories.images_section', |
||
370 | 'type' => 'section', |
||
371 | 'comment' => self::LOCALIZATION_KEY . 'form.categories.images_section_comment' |
||
372 | ] |
||
373 | ]); |
||
374 | } |
||
375 | |||
376 | View Code Duplication | if ($this->getSettings()->postCategoriesCoverImageEnabled()) { |
|
377 | $form->addFields([ |
||
378 | 'cover_image' => [ |
||
379 | 'label' => self::LOCALIZATION_KEY . 'form.fields.cover_image', |
||
380 | 'type' => 'fileupload', |
||
381 | 'mode' => 'image', |
||
382 | 'tab' => 'Images', |
||
383 | 'span' => 'left' |
||
384 | ] |
||
385 | ]); |
||
386 | } |
||
387 | |||
388 | View Code Duplication | if ($this->getSettings()->postCategoriesFeaturedImagesEnabled()) { |
|
389 | $form->addFields([ |
||
390 | 'featured_images' => [ |
||
391 | 'label' => self::LOCALIZATION_KEY . 'form.fields.featured_images', |
||
392 | 'type' => 'fileupload', |
||
393 | 'mode' => 'image', |
||
394 | 'tab' => 'Images' |
||
395 | ] |
||
396 | ]); |
||
397 | } |
||
398 | }); |
||
399 | } |
||
400 | |||
401 | private function extendValidator(): void |
||
402 | { |
||
403 | if ($this->getSettings()->postTypesEnabled()) { |
||
404 | Validator::extend('unique_in_repeater', function ($attribute, $value, $parameters, $validator) { |
||
405 | $attributeNameParts = explode('.', $attribute); |
||
406 | |||
407 | $repeaterName = reset($attributeNameParts); |
||
408 | $fieldName = end($attributeNameParts); |
||
409 | |||
410 | $repeaterData = isset($validator->getData()[$repeaterName]) |
||
411 | ? (array) $validator->getData()[$repeaterName] |
||
412 | : []; |
||
413 | |||
414 | $fieldData = array_column($repeaterData, $fieldName); |
||
415 | |||
416 | if (count(array_unique($fieldData)) !== count($fieldData)) { |
||
417 | return false; |
||
418 | } |
||
419 | |||
420 | return true; |
||
421 | }); |
||
422 | } |
||
423 | } |
||
424 | |||
425 | private function transformPostCategoriesIntoTaglist(Form $form, string $tab) |
||
426 | { |
||
427 | $categoriesConfig = $form->getField('categories')->config; |
||
428 | $categoriesConfig['tab'] = $tab; |
||
429 | $categoriesConfig['mode'] = 'relation'; |
||
430 | $categoriesConfig['type'] = 'taglist'; |
||
431 | $categoriesConfig['label'] = 'rainlab.blog::lang.post.tab_categories'; |
||
432 | $categoriesConfig['comment'] = "rainlab.blog::lang.post.categories_comment"; |
||
433 | $categoriesConfig['placeholder'] = self::LOCALIZATION_KEY . 'placeholders.categories'; |
||
434 | unset($categoriesConfig['commentAbove']); |
||
435 | |||
436 | $form->removeField('categories'); |
||
437 | return $categoriesConfig; |
||
438 | } |
||
439 | |||
440 | private function addPostTypeAttributes(Form $form, PostModel $model): void |
||
441 | { |
||
442 | $tab = self::LOCALIZATION_KEY . 'navigation.tab.type'; |
||
443 | |||
444 | $form->addSecondaryTabFields([ |
||
445 | 'post_type' => [ |
||
446 | 'label' => self::LOCALIZATION_KEY . 'form.post_types.label', |
||
447 | 'tab' => $tab, |
||
448 | 'type' => 'relation', |
||
449 | 'nameFrom' => 'name', |
||
450 | 'comment' => self::LOCALIZATION_KEY . 'form.post_types.comment', |
||
451 | 'placeholder' => self::LOCALIZATION_KEY . 'placeholders.post_types' |
||
452 | ], |
||
453 | ]); |
||
454 | |||
455 | $condition = implode( |
||
456 | array_map( |
||
457 | static function ($value) { |
||
458 | return "[$value]"; |
||
459 | }, |
||
460 | PostType::all()->pluck('id')->toArray() |
||
461 | ) |
||
462 | ); |
||
463 | |||
464 | $typeAttributes = [ |
||
465 | 'label' => self::LOCALIZATION_KEY . 'form.post_types.type_attributes', |
||
466 | 'commentAbove' => self::LOCALIZATION_KEY . 'form.post_types.type_attributes_comment', |
||
467 | 'type' => 'repeater', |
||
468 | 'minItems' => 1, |
||
469 | // there's October bug related to maxItems option when you can add more than one record |
||
470 | // though only one is expected. The backend won't allow to save this anyway |
||
471 | // https://github.com/octobercms/october/issues/5533 |
||
472 | 'maxItems' => 1, |
||
473 | 'dependsOn' => 'post_type', |
||
474 | 'trigger' => [ |
||
475 | 'action' => 'show', |
||
476 | 'field' => 'post_type', |
||
477 | 'condition' => "value$condition" |
||
478 | ], |
||
479 | 'sortable' => false, |
||
480 | 'style' => 'accordion', |
||
481 | 'tab' => $tab, |
||
482 | 'form' => [ |
||
483 | 'fields' => [] |
||
484 | ] |
||
485 | ]; |
||
486 | |||
487 | if ((($postTypeId = Input::get('Post.post_type')) !== null && |
||
488 | $postType = PostType::find($postTypeId)) |
||
489 | || |
||
490 | (!empty($model->id) && !empty($model->post_type->id) && $postType = $model->post_type) |
||
491 | ) { |
||
492 | if (!empty($postType->type_attributes)) { |
||
493 | $fields = []; |
||
494 | |||
495 | foreach ($postType->type_attributes as $typeAttribute) { |
||
496 | if (empty($typeAttribute['code'])) { |
||
497 | continue; |
||
498 | } |
||
499 | |||
500 | $field = []; |
||
501 | |||
502 | $type = $typeAttribute['type'] ?? 'text'; |
||
503 | |||
504 | switch ($type) { |
||
505 | case 'file': |
||
506 | case 'image': |
||
507 | $field['type'] = 'mediafinder'; |
||
508 | $field['mode'] = $type; |
||
509 | $field['imageWidth'] = 200; |
||
510 | break; |
||
511 | case 'dropdown': |
||
512 | $field['type'] = $type; |
||
513 | |||
514 | $options = array_map(static function ($value) { |
||
515 | return trim($value); |
||
516 | }, explode(',', $typeAttribute['dropdown_options'] ?? '')); |
||
517 | |||
518 | $field['options'] = $options; |
||
519 | |||
520 | break; |
||
521 | case 'text': |
||
522 | case 'textarea': |
||
523 | $field['type'] = $type; |
||
524 | break; |
||
525 | case 'datepicker': |
||
526 | $field['type'] = $type; |
||
527 | $field['mode'] = $typeAttribute['datepicker_mode'] ?? 'date'; |
||
528 | |||
529 | break; |
||
530 | } |
||
531 | |||
532 | $field['label'] = $typeAttribute['name'] ?? ''; |
||
533 | |||
534 | $fields[sprintf("%s.%s", $postType->id, $typeAttribute['code'])] = $field; |
||
535 | } |
||
536 | |||
537 | $typeAttributes['form']['fields'] = $fields; |
||
538 | } |
||
539 | } |
||
540 | |||
541 | $form->addSecondaryTabFields([ |
||
542 | PostType::TABLE_NAME . '_attributes' => $typeAttributes |
||
543 | ]); |
||
544 | } |
||
545 | |||
546 | private function extendPostListColumns(): void |
||
547 | { |
||
548 | Event::listen('backend.list.extendColumns', function (Lists $listWidget) { |
||
549 | // Only for the Posts controller |
||
550 | if (!$listWidget->getController() instanceof PostsController) { |
||
0 ignored issues
–
show
The class
RainLab\Blog\Controllers\Posts does not exist. Did you forget a USE statement, or did you not list all dependencies?
This error could be the result of: 1. Missing dependenciesPHP Analyzer uses your Are you sure this class is defined by one of your dependencies, or did you maybe
not list a dependency in either the 2. Missing use statementPHP does not complain about undefined classes in if ($x instanceof DoesNotExist) {
// Do something.
}
If you have not tested against this specific condition, such errors might go unnoticed. ![]() |
|||
551 | return; |
||
552 | } |
||
553 | |||
554 | // Only for the Post model |
||
555 | if (!$listWidget->model instanceof PostModel) { |
||
0 ignored issues
–
show
The class
RainLab\Blog\Models\Post does not exist. Did you forget a USE statement, or did you not list all dependencies?
This error could be the result of: 1. Missing dependenciesPHP Analyzer uses your Are you sure this class is defined by one of your dependencies, or did you maybe
not list a dependency in either the 2. Missing use statementPHP does not complain about undefined classes in if ($x instanceof DoesNotExist) {
// Do something.
}
If you have not tested against this specific condition, such errors might go unnoticed. ![]() |
|||
556 | return; |
||
557 | } |
||
558 | |||
559 | if ($this->getSettings()->postTypesEnabled()) { |
||
560 | $listWidget->addColumns([ |
||
561 | 'type' => [ |
||
562 | 'label' => self::LOCALIZATION_KEY . 'form.post_types.post_list_column', |
||
563 | 'relation' => 'post_type', |
||
564 | 'select' => 'name', |
||
565 | 'searchable' => 'true', |
||
566 | 'sortable' => true |
||
567 | ] |
||
568 | ]); |
||
569 | } |
||
570 | }); |
||
571 | } |
||
572 | |||
573 | private function extendPostFilterScopes(): void |
||
574 | { |
||
575 | Event::listen('backend.filter.extendScopes', function (Filter $filterWidget) { |
||
576 | if ($this->getSettings()->postTypesEnabled()) { |
||
577 | $filterWidget->addScopes([ |
||
578 | 'type' => [ |
||
579 | 'label' => self::LOCALIZATION_KEY . 'form.post_types.post_list_filter_scope', |
||
580 | 'modelClass' => PostType::class, |
||
581 | 'nameFrom' => 'name', |
||
582 | 'scope' => 'filterPostTypes' |
||
583 | ] |
||
584 | ]); |
||
585 | } |
||
586 | }); |
||
587 | } |
||
588 | } |
||
589 |
This error could be the result of:
1. Missing dependencies
PHP Analyzer uses your
composer.json
file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects thecomposer.json
to be in the root folder of your repository.Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the
require
orrequire-dev
section?2. Missing use statement
PHP does not complain about undefined classes in
ìnstanceof
checks. For example, the following PHP code will work perfectly fine:If you have not tested against this specific condition, such errors might go unnoticed.