Completed
Push — master ( cfc96c...883ebd )
by Gino
03:17 queued 01:42
created

Plugin.php (1 issue)

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 GinoPane\BlogTaxonomy\Components\RelatedSeries;
19
use RainLab\Blog\Controllers\Posts as PostsController;
20
use GinoPane\BlogTaxonomy\Components\SeriesNavigation;
21
use RainLab\Blog\Controllers\Categories as CategoriesController;
22
23
/**
24
 * Class Plugin
25
 *
26
 * @package GinoPane\BlogTaxonomy
27
 */
28
class Plugin extends PluginBase
29
{
30
    const LOCALIZATION_KEY = 'ginopane.blogtaxonomy::lang.';
31
32
    const DIRECTORY_KEY = 'ginopane/blogtaxonomy';
33
34
    const REQUIRED_PLUGIN_RAINLAB_BLOG = 'RainLab.Blog';
35
36
    /**
37
     * @var array   Require the RainLab.Blog plugin
38
     */
39
    public $require = [
40
        'RainLab.Blog'
41
    ];
42
43
    /**
44
     * Returns information about this plugin
45
     *
46
     * @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...
47
     */
48
    public function pluginDetails()
49
    {
50
        return [
51
            'name'        => self::LOCALIZATION_KEY . 'plugin.name',
52
            'description' => self::LOCALIZATION_KEY . 'plugin.description',
53
            'author'      => 'Siarhei <Gino Pane> Karavai',
54
            'icon'        => 'icon-tags',
55
            'homepage'    => 'https://github.com/GinoPane/oc-blogtaxonomy-plugin'
56
        ];
57
    }
58
59
    /**
60
     * Register components
61
     *
62
     * @return  array
63
     */
64
    public function registerComponents()
65
    {
66
        return [
67
            TagList::class          => TagList::NAME,
68
            TagPosts::class         => TagPosts::NAME,
69
            RelatedPosts::class     => RelatedPosts::NAME,
70
            SeriesList::class       => SeriesList::NAME,
71
            SeriesPosts::class      => SeriesPosts::NAME,
72
            SeriesNavigation::class => SeriesNavigation::NAME,
73
            RelatedSeries::class    => RelatedSeries::NAME
74
        ];
75
    }
76
77
    /**
78
     * Boot method, called right before the request route
79
     */
80
    public function boot()
81
    {
82
        // extend the post model
83
        $this->extendModel();
84
85
        // extend posts functionality
86
        $this->extendPostsController();
87
88
        // extend categories functionality
89
        $this->extendCategoriesController();
90
    }
91
92
    /**
93
     * Register plugin navigation
94
     */
95
    public function registerNavigation()
96
    {
97
        // Extend the navigation
98
        Event::listen('backend.menu.extendItems', function ($manager) {
99
            $manager->addSideMenuItems(self::REQUIRED_PLUGIN_RAINLAB_BLOG, 'blog', [
100
                'series' => [
101
                    'label' => self::LOCALIZATION_KEY . 'navigation.series',
102
                    'icon' => 'icon-list-alt',
103
                    'code' => 'series',
104
                    'owner' => self::REQUIRED_PLUGIN_RAINLAB_BLOG,
105
                    'url' => Backend::url(self::DIRECTORY_KEY . '/series')
106
                ],
107
108
                'tags' => [
109
                    'label' => self::LOCALIZATION_KEY . 'navigation.tags',
110
                    'icon'  => 'icon-tags',
111
                    'code'  => 'tags',
112
                    'owner' => self::REQUIRED_PLUGIN_RAINLAB_BLOG,
113
                    'url'   => Backend::url(self::DIRECTORY_KEY . '/tags')
114
                ]
115
            ]);
116
        });
117
    }
118
119
    /**
120
     * Extend RainLab Post model
121
     */
122
    private function extendModel()
123
    {
124
        PostModel::extend(function ($model) {
125
            $model->belongsToMany['tags'] = [
126
                Tag::class,
127
                'table' => Tag::CROSS_REFERENCE_TABLE_NAME,
128
                'order' => 'name'
129
            ];
130
131
            $model->belongsTo['series'] = [
132
                Series::class,
133
                'key' => Series::TABLE_NAME . "_id"
134
            ];
135
        });
136
    }
137
138
    /**
139
     * Extends post controller functionality
140
     */
141
    private function extendPostsController()
142
    {
143
        PostsController::extendFormFields(function ($form, $model) {
144
            if (!$model instanceof PostModel) {
145
                return;
146
            }
147
148
            /*
149
             * When extending the form, you should check to see if $formWidget->isNested === false
150
             * as the Repeater FormWidget includes nested Form widgets which can cause your changes
151
             * to be made in unexpected places.
152
             *
153
             * @link https://octobercms.com/docs/plugin/extending#extending-backend-form
154
             */
155
            if (!empty($form->isNested)) {
156
                return;
157
            }
158
            
159
            $tab = self::LOCALIZATION_KEY . 'navigation.taxonomy';
160
161
            $categoriesConfig = $form->getField('categories')->config;
162
            $categoriesConfig['tab'] = $tab;
163
            $categoriesConfig['mode'] = 'relation';
164
            $categoriesConfig['type'] = 'taglist';
165
            $categoriesConfig['label'] = 'rainlab.blog::lang.post.tab_categories';
166
            $categoriesConfig['comment'] = "rainlab.blog::lang.post.categories_comment";
167
            $categoriesConfig['placeholder'] = self::LOCALIZATION_KEY . 'placeholders.categories';
168
            unset($categoriesConfig['commentAbove']);
169
170
            $form->removeField('categories');
171
172
            $form->addSecondaryTabFields([
173
                'categories' => $categoriesConfig,
174
                'tags' => [
175
                    'label' => self::LOCALIZATION_KEY . 'form.tags.label',
176
                    'comment' => self::LOCALIZATION_KEY . 'form.tags.comment',
177
                    'mode' => 'relation',
178
                    'tab' => $tab,
179
                    'type' => 'taglist',
180
                    'placeholder' => self::LOCALIZATION_KEY . 'placeholders.tags',
181
                ],
182
                'series' => [
183
                    'label' => self::LOCALIZATION_KEY . 'form.series.label',
184
                    'tab' => $tab,
185
                    'type' => 'relation',
186
                    'nameFrom' => 'title',
187
                    'comment' => self::LOCALIZATION_KEY . 'form.series.comment',
188
                    // October CMS has a bug with displaying of placeholders without an explicit empty option
189
                    // https://github.com/octobercms/october/pull/4060
190
                    'placeholder' => self::LOCALIZATION_KEY . 'placeholders.series',
191
                    'emptyOption' => self::LOCALIZATION_KEY . 'placeholders.series'
192
                ],
193
            ]);
194
        });
195
    }
196
197
    /**
198
     * Extends categories controller functionality
199
     */
200
    private function extendCategoriesController()
201
    {
202
        CategoriesController::extend(function (Controller $controller) {
203
            $controller->implement[] = RelationController::class;
204
            $relationConfig = '$/' . self::DIRECTORY_KEY . '/controllers/category/config_relation.yaml';
205
206
            if (property_exists($controller, 'relationConfig')) {
207
                $controller->relationConfig = $controller->mergeConfig(
208
                    $controller->relationConfig,
209
                    $relationConfig
210
                );
211
            } else {
212
                $controller->addDynamicProperty('relationConfig', $relationConfig);
213
            }
214
215
            $formConfig = '$/' . self::DIRECTORY_KEY . '/controllers/category/config_form.yaml';
216
217
            if (property_exists($controller, 'formConfig')) {
218
                $controller->formConfig = $controller->mergeConfig(
219
                    $controller->formConfig,
220
                    $formConfig
221
                );
222
            } else {
223
                $controller->addDynamicProperty('formConfig', $formConfig);
224
            }
225
        });
226
    }
227
}
228