PostListAbstract   A
last analyzed

Complexity

Total Complexity 17

Size/Duplication

Total Lines 255
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 17
lcom 1
cbo 3
dl 0
loc 255
rs 10
c 0
b 0
f 0

14 Methods

Rating   Name   Duplication   Size   Complexity  
A defineProperties() 0 19 1
A getOrderByOptions() 0 8 1
A onRun() 0 10 2
A listPosts() 0 14 1
A getPostPageOptions() 0 4 1
A getCategoryPageOptions() 0 4 1
prepareContextItem() 0 1 ?
getPostsQuery() 0 1 ?
A prepareVars() 0 11 1
A getPaginationProperties() 0 22 1
A getPageLinkProperties() 0 21 1
A populatePagination() 0 7 3
A populateLinks() 0 5 1
A handleOrder() 0 12 3
1
<?php declare(strict_types=1);
2
3
namespace GinoPane\BlogTaxonomy\Classes;
4
5
use Cms\Classes\Page;
6
use Illuminate\Http\Response;
7
use Rainlab\Blog\Models\Post;
8
use GinoPane\BlogTaxonomy\Plugin;
9
use October\Rain\Database\Builder;
10
use Illuminate\Http\RedirectResponse;
11
use Illuminate\Support\Facades\Redirect;
12
use Illuminate\Database\Eloquent\Collection;
13
14
/**
15
 * Class PostListAbstract
16
 *
17
 * @package GinoPane\BlogTaxonomy\Classes
18
 */
19
abstract class PostListAbstract extends ComponentAbstract
0 ignored issues
show
Coding Style introduced by
PostListAbstract does not seem to conform to the naming convention (^Abstract|Factory$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
20
{
21
    use TranslateArrayTrait;
22
    use PostListFiltersTrait;
23
24
    /**
25
     * @var Collection | array
26
     */
27
    public $posts = [];
28
29
    /**
30
     * Parameter to use for the page number
31
     *
32
     * @var string
33
     */
34
    public $pageParam;
35
36
    /**
37
     * @var integer The current page
38
     */
39
    public $currentPage;
40
41
    /**
42
     * @var integer The number of results per page
43
     */
44
    public $resultsPerPage;
45
46
    /**
47
     * If the post list should be ordered by another attribute
48
     *
49
     * @var string
50
     */
51
    public $orderBy;
52
53
    /**
54
     * The attributes on which the post list can be ordered
55
     * @var array
56
     */
57
    public static $postAllowedSortingOptions = [
58
        'title asc' => Plugin::LOCALIZATION_KEY . 'order_options.title_asc',
59
        'title desc' => Plugin::LOCALIZATION_KEY . 'order_options.title_desc',
60
        'created_at asc' => Plugin::LOCALIZATION_KEY . 'order_options.created_at_asc',
61
        'created_at desc' => Plugin::LOCALIZATION_KEY . 'order_options.created_at_desc',
62
        'updated_at asc' => Plugin::LOCALIZATION_KEY . 'order_options.updated_at_asc',
63
        'updated_at desc' => Plugin::LOCALIZATION_KEY . 'order_options.updated_at_desc',
64
        'published_at asc' => Plugin::LOCALIZATION_KEY . 'order_options.published_at_asc',
65
        'published_at desc' => Plugin::LOCALIZATION_KEY . 'order_options.published_at_desc',
66
        'random' => Plugin::LOCALIZATION_KEY . 'order_options.random'
67
    ];
68
69
    /**
70
     * Component properties
71
     *
72
     * @return array
73
     */
74
    public function defineProperties(): array
75
    {
76
        $properties = [
77
            'orderBy' => [
78
                'title'       => 'rainlab.blog::lang.settings.posts_order',
79
                'description' => 'rainlab.blog::lang.settings.posts_order_description',
80
                'type'        => 'dropdown',
81
                'default'     => 'published_at asc',
82
                'showExternalParam' => false
83
            ]
84
        ];
85
86
        return array_merge(
87
            $properties,
88
            $this->getPaginationProperties(),
89
            $this->getPageLinkProperties(),
90
            $this->getPostFilterProperties()
91
        );
92
    }
93
94
    /**
95
     * @see Post::$allowedSortingOptions
96
     *
97
     * @return string[]
98
     */
99
    public function getOrderByOptions(): array
100
    {
101
        $order = $this->translate(static::$postAllowedSortingOptions);
102
103
        asort($order);
104
105
        return $order;
106
    }
107
108
    /**
109
     * Query the item and posts belonging to it
110
     *
111
     * @return void|RedirectResponse
112
     */
113
    public function onRun()
114
    {
115
        if ($this->prepareContextItem() === null) {
116
            return Redirect::to($this->controller->pageUrl(Response::HTTP_NOT_FOUND));
117
        }
118
119
        $this->prepareVars();
120
121
        $this->listPosts();
122
    }
123
124
    /**
125
     * Load a list of posts
126
     */
127
    public function listPosts()
128
    {
129
        $query = $this->getPostsQuery();
130
131
        $this->handlePostFilters($query);
132
133
        $this->handleOrder($query);
134
135
        $posts = $query->paginate($this->resultsPerPage, $this->currentPage);
136
137
        $this->setPostUrls($posts);
138
139
        $this->posts = $posts;
140
    }
141
142
    /**
143
     * @return mixed
144
     */
145
    public function getPostPageOptions()
146
    {
147
        return Page::sortBy('baseFileName')->lists('baseFileName', 'baseFileName');
148
    }
149
150
    /**
151
     * @return mixed
152
     */
153
    public function getCategoryPageOptions()
154
    {
155
        return Page::sortBy('baseFileName')->lists('baseFileName', 'baseFileName');
156
    }
157
158
    /**
159
     * Prepare main context item
160
     */
161
    abstract protected function prepareContextItem();
0 ignored issues
show
Documentation introduced by
For interfaces and abstract methods it is generally a good practice to add a @return annotation even if it is just @return void or @return null, so that implementors know what to do in the overridden method.

For interface and abstract methods, it is impossible to infer the return type from the immediate code. In these cases, it is generally advisible to explicitly annotate these methods with a @return doc comment to communicate to implementors of these methods what they are expected to return.

Loading history...
162
163
    /**
164
     * @return mixed
165
     */
166
    abstract protected function getPostsQuery();
167
168
    /**
169
     * Prepare variables
170
     */
171
    protected function prepareVars()
172
    {
173
        // Paginator settings
174
        $this->populatePagination();
175
        // Page links
176
        $this->populateLinks();
177
        // Exceptions
178
        $this->populateFilters();
179
180
        $this->orderBy = $this->property('orderBy');
181
    }
182
183
    /**
184
     * Properties for pagination handling
185
     *
186
     * @return array
187
     */
188
    private function getPaginationProperties(): array
189
    {
190
        return [
191
            'page' => [
192
                'group'         => Plugin::LOCALIZATION_KEY . 'components.post_list_abstract.pagination_group',
193
                'title'         => Plugin::LOCALIZATION_KEY . 'components.post_list_abstract.page_parameter_title',
194
                'description'   => Plugin::LOCALIZATION_KEY . 'components.post_list_abstract.page_parameter_description',
195
                'default'       => '{{ :page }}',
196
                'type'          => 'string',
197
            ],
198
            'resultsPerPage' => [
199
                'group'         => Plugin::LOCALIZATION_KEY . 'components.post_list_abstract.pagination_group',
200
                'title'         => Plugin::LOCALIZATION_KEY . 'components.post_list_abstract.pagination_per_page_title',
201
                'description'   => Plugin::LOCALIZATION_KEY . 'components.post_list_abstract.pagination_per_page_description',
202
                'default'       => 10,
203
                'type'          => 'string',
204
                'validationPattern' => '^(0+)?[1-9]\d*$',
205
                'validationMessage' => Plugin::LOCALIZATION_KEY . 'components.post_list_abstract.pagination_validation_message',
206
                'showExternalParam' => false,
207
            ]
208
        ];
209
    }
210
211
    /**
212
     * Properties for proper links handling
213
     *
214
     * @return array
215
     */
216
    private function getPageLinkProperties(): array
217
    {
218
        return [
219
            'postPage' => [
220
                'group'       => Plugin::LOCALIZATION_KEY . 'components.post_list_abstract.links_group',
221
                'title'       => 'rainlab.blog::lang.settings.posts_post',
222
                'description' => 'rainlab.blog::lang.settings.posts_description',
223
                'type'        => 'dropdown',
224
                'default'     => 'blog/post',
225
                'showExternalParam' => false,
226
            ],
227
            'categoryPage' => [
228
                'group'       => Plugin::LOCALIZATION_KEY . 'components.post_list_abstract.links_group',
229
                'title'       => 'rainlab.blog::lang.settings.posts_category',
230
                'description' => 'rainlab.blog::lang.settings.posts_category_description',
231
                'type'        => 'dropdown',
232
                'default'     => 'blog/category',
233
                'showExternalParam' => false,
234
            ],
235
        ];
236
    }
237
238
    /**
239
     * @return void
240
     */
241
    private function populatePagination()
242
    {
243
        $this->pageParam = $this->paramName('page');
244
        $this->currentPage = (int)$this->property('page', 1) ?: (int)post('page');
245
        $this->resultsPerPage = (int)$this->property('resultsPerPage')
246
            ?: $this->defineProperties()['resultsPerPage']['default'];
247
    }
248
249
    /**
250
     * @return void
251
     */
252
    private function populateLinks()
253
    {
254
        $this->postPage = $this->property('postPage');
255
        $this->categoryPage = $this->property('categoryPage');
256
    }
257
258
    /**
259
     * @param $query
260
     */
261
    private function handleOrder(Builder $query)
262
    {
263
        if (array_key_exists($this->orderBy, self::$postAllowedSortingOptions)) {
264
            if ($this->orderBy === 'random') {
265
                $query->inRandomOrder();
266
            } else {
267
                list($sortField, $sortDirection) = explode(' ', $this->orderBy);
268
269
                $query->orderBy($sortField, $sortDirection);
270
            }
271
        }
272
    }
273
}
274