Completed
Pull Request — master (#23)
by Gino
01:57
created

Plugin.php (2 issues)

Upgrade to new PHP Analysis Engine

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 Backend;
7
use System\Classes\PluginBase;
8
use Backend\Classes\Controller;
9
use GinoPane\BlogTaxonomy\Models\Tag;
10
use GinoPane\BlogTaxonomy\Models\Series;
11
use Backend\Behaviors\RelationController;
12
use RainLab\Blog\Models\Post as PostModel;
13
use GinoPane\BlogTaxonomy\Components\TagList;
14
use GinoPane\BlogTaxonomy\Components\TagPosts;
15
use GinoPane\BlogTaxonomy\Components\SeriesList;
16
use GinoPane\BlogTaxonomy\Components\SeriesPosts;
17
use GinoPane\BlogTaxonomy\Components\RelatedPosts;
18
use RainLab\Blog\Controllers\Posts as PostsController;
19
use GinoPane\BlogTaxonomy\Components\SeriesNavigation;
20
use RainLab\Blog\Controllers\Categories as CategoriesController;
21
22
/**
23
 * Class Plugin
24
 *
25
 * @package GinoPane\BlogTaxonomy
26
 */
27
class Plugin extends PluginBase
28
{
29
    const LOCALIZATION_KEY = 'ginopane.blogtaxonomy::lang.';
30
31
    const DIRECTORY_KEY = 'ginopane/blogtaxonomy';
32
33
    const REQUIRED_PLUGIN_RAINLAB_BLOG = 'RainLab.Blog';
34
35
    /**
36
     * @var array   Require the RainLab.Blog plugin
37
     */
38
    public $require = [
39
        'RainLab.Blog'
40
    ];
41
42
    /**
43
     * Returns information about this plugin
44
     *
45
     * @return  array
0 ignored issues
show
Consider making the return type a bit more specific; maybe use array<string,string>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
46
     */
47
    public function pluginDetails()
48
    {
49
        return [
50
            'name'        => self::LOCALIZATION_KEY . 'plugin.name',
51
            'description' => self::LOCALIZATION_KEY . 'plugin.description',
52
            'author'      => 'Siarhei <Gino Pane> Karavai',
53
            'icon'        => 'icon-tags',
54
            'homepage'    => 'https://github.com/ginopane/oc-blog-taxonomy'
55
        ];
56
    }
57
58
    /**
59
     * Register components
60
     *
61
     * @return  array
62
     */
63
    public function registerComponents()
64
    {
65
        return [
66
            TagList::class          => TagList::NAME,
67
            TagPosts::class         => TagPosts::NAME,
68
            RelatedPosts::class     => RelatedPosts::NAME,
69
            SeriesList::class       => SeriesList::NAME,
70
            SeriesPosts::class      => SeriesPosts::NAME,
71
            SeriesNavigation::class => SeriesNavigation::NAME,
72
        ];
73
    }
74
75
    /**
76
     * Boot method, called right before the request route
77
     */
78
    public function boot()
79
    {
80
        // extend the post model
81
        $this->extendModel();
82
83
        // extend posts functionality
84
        $this->extendPostsController();
85
86
        // extend categories functionality
87
        $this->extendCategoriesController();
88
    }
89
90
    /**
91
     * Register plugin navigation
92
     */
93
    public function registerNavigation()
94
    {
95
        // Extend the navigation
96
        Event::listen('backend.menu.extendItems', function ($manager) {
97
            $manager->addSideMenuItems(self::REQUIRED_PLUGIN_RAINLAB_BLOG, 'blog', [
98
                'series' => [
99
                    'label' => self::LOCALIZATION_KEY . 'navigation.series',
100
                    'icon' => 'icon-list-alt',
101
                    'code' => 'series',
102
                    'owner' => self::REQUIRED_PLUGIN_RAINLAB_BLOG,
103
                    'url' => Backend::url(self::DIRECTORY_KEY . '/series')
104
                ],
105
106
                'tags' => [
107
                    'label' => self::LOCALIZATION_KEY . 'navigation.tags',
108
                    'icon'  => 'icon-tags',
109
                    'code'  => 'tags',
110
                    'owner' => self::REQUIRED_PLUGIN_RAINLAB_BLOG,
111
                    'url'   => Backend::url(self::DIRECTORY_KEY . '/tags')
112
                ]
113
            ]);
114
        });
115
    }
116
117
    /**
118
     * Extend RainLab Post model
119
     */
120
    private function extendModel()
121
    {
122
        PostModel::extend(function ($model) {
123
            $model->belongsToMany['tags'] = [
124
                Tag::class,
125
                'table' => Tag::CROSS_REFERENCE_TABLE_NAME,
126
                'order' => 'name'
127
            ];
128
129
            $model->belongsTo['series'] = [
130
                Series::class,
131
                'key' => Series::TABLE_NAME . "_id"
132
            ];
133
        });
134
    }
135
136
    /**
137
     * Extends post controller functionality
138
     */
139
    private function extendPostsController()
140
    {
141
        PostsController::extendFormFields(function ($form, $model) {
142
            if (!$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 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 the composer.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 or require-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 ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
143
                return;
144
            }
145
146
            /*
147
             * When extending the form, you should check to see if $formWidget->isNested === false
148
             * as the Repeater FormWidget includes nested Form widgets which can cause your changes
149
             * to be made in unexpected places.
150
             *
151
             * @link https://octobercms.com/docs/plugin/extending#extending-backend-form
152
             */
153
            if (!empty($form->isNested)) {
154
                return;
155
            }
156
            
157
            $tab = self::LOCALIZATION_KEY . 'navigation.taxonomy';
158
159
            $categoriesConfig = $form->getField('categories')->config;
160
            $categoriesConfig['tab'] = $tab;
161
            $categoriesConfig['mode'] = 'relation';
162
            $categoriesConfig['type'] = 'taglist';
163
            $categoriesConfig['label'] = 'rainlab.blog::lang.post.tab_categories';
164
            $categoriesConfig['comment'] = "rainlab.blog::lang.post.categories_comment";
165
            $categoriesConfig['placeholder'] = self::LOCALIZATION_KEY . 'placeholders.categories';
166
            unset($categoriesConfig['commentAbove']);
167
168
            $form->removeField('categories');
169
170
            $form->addSecondaryTabFields([
171
                'categories' => $categoriesConfig,
172
                'tags' => [
173
                    'label' => self::LOCALIZATION_KEY . 'form.tags.label',
174
                    'comment' => self::LOCALIZATION_KEY . 'form.tags.comment',
175
                    'mode' => 'relation',
176
                    'tab' => $tab,
177
                    'type' => 'taglist',
178
                    'placeholder' => self::LOCALIZATION_KEY . 'placeholders.tags',
179
                ],
180
                'series' => [
181
                    'label' => self::LOCALIZATION_KEY . 'form.series.label',
182
                    'tab' => $tab,
183
                    'type' => 'relation',
184
                    'nameFrom' => 'title',
185
                    'comment' => self::LOCALIZATION_KEY . 'form.series.comment',
186
                    // October CMS has a bug with displaying of placeholders without an explicit empty option
187
                    // https://github.com/octobercms/october/pull/4060
188
                    'placeholder' => self::LOCALIZATION_KEY . 'placeholders.series',
189
                    'emptyOption' => self::LOCALIZATION_KEY . 'placeholders.series'
190
                ],
191
            ]);
192
        });
193
    }
194
195
    /**
196
     * Extends categories controller functionality
197
     */
198
    private function extendCategoriesController()
199
    {
200
        CategoriesController::extend(function (Controller $controller) {
201
            $controller->implement[] = RelationController::class;
202
            $relationConfig = '$/' . self::DIRECTORY_KEY . '/controllers/category/config_relation.yaml';
203
204
            if (property_exists($controller, 'relationConfig')) {
205
                $controller->relationConfig = $controller->mergeConfig(
206
                    $controller->relationConfig,
207
                    $relationConfig
208
                );
209
            } else {
210
                $controller->addDynamicProperty('relationConfig', $relationConfig);
211
            }
212
213
            $formConfig = '$/' . self::DIRECTORY_KEY . '/controllers/category/config_form.yaml';
214
215
            if (property_exists($controller, 'formConfig')) {
216
                $controller->formConfig = $controller->mergeConfig(
217
                    $controller->formConfig,
218
                    $formConfig
219
                );
220
            } else {
221
                $controller->addDynamicProperty('formConfig', $formConfig);
222
            }
223
        });
224
    }
225
}
226