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) { |
||
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) { |
||
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()) { |
|
0 ignored issues
–
show
|
|||
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()) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
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) { |
||
551 | return; |
||
552 | } |
||
553 | |||
554 | // Only for the Post model |
||
555 | if (!$listWidget->model instanceof PostModel) { |
||
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 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.