Completed
Push — master ( ae1d1c...3e4575 )
by Gino
01:37
created

ModelAbstract::handleExceptions()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.9332
c 0
b 0
f 0
cc 3
nc 4
nop 2
1
<?php
2
3
namespace GinoPane\BlogTaxonomy\Models;
4
5
use Model;
6
use Cms\Classes\Controller;
7
use October\Rain\Database\Builder;
8
use October\Rain\Database\Relations\HasMany;
9
use GinoPane\BlogTaxonomy\Classes\PostListExceptionsTrait;
10
11
/**
12
 * Class ModelAbstract
13
 *
14
 * @property string $url
15
 *
16
 * @package GinoPane\BlogTaxonomy\Models
17
 */
18
abstract class ModelAbstract extends Model
0 ignored issues
show
Coding Style introduced by
ModelAbstract 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...
19
{
20
    /**
21
     * @var array
22
     */
23
    public static $sortingOptions = [];
24
25
    /**
26
     * Sets the URL attribute with a URL to this object
27
     *
28
     * @param string $pageName
29
     * @param Controller $controller
30
     * @param array $params
31
     *
32
     * @return void
33
     */
34
    public function setUrl($pageName, Controller $controller, array $params = array())
35
    {
36
        $params = $this->getModelUrlParams($params);
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $params. This often makes code more readable.
Loading history...
37
38
        $this->url = $controller->pageUrl($pageName, $params);
39
    }
40
41
    /**
42
     * @param array $params
43
     *
44
     * @return array
45
     */
46
    abstract protected function getModelUrlParams(array $params): array;
47
48
    /**
49
     * Gets a list of items related to Posts for frontend use
50
     *
51
     * @param       $query
52
     * @param array $options Available options are "sort", "displayEmpty", "limit", "post"
53
     *
54
     * @return mixed
55
     */
56
    public function scopeListFrontend(Builder $query, array $options = [])
57
    {
58
        $this->withRelation($query, $options);
59
60
        $this->queryOrderBy($query, $options);
61
62
        $this->queryDisplayEmpty($query, $options);
63
64
        $this->queryPostSlug($query, $options);
65
66
        $this->queryLimit($query, $options);
67
68
        // GROUP BY is required for SQLite to deal with HAVING
69
        // We use it for all connections just to keep implementation
70
        // independent from the connection being used
71
        $this->queryGroupBy($query);
72
73
        return $query->get();
74
    }
75
76
    /**
77
     * @param Builder   $query
78
     * @param string    $property
79
     * @param mixed     $value
80
     */
81
    public function scopeWhereTranslatable(Builder $query, string $property, $value)
82
    {
83
        self::whereTranslatableProperty($query, $property, $value);
84
    }
85
86
    /**
87
     * @param Builder $query
88
     * @param string $property
89
     * @param $value
90
     */
91
    public static function whereTranslatableProperty(Builder $query, string $property, $value)
92
    {
93
        $query->getModel()->isClassExtendedWith('RainLab.Translate.Behaviors.TranslatableModel')
94
            ? $query->transWhere($property, $value)
95
            : $query->where($property, $value);
96
    }
97
98
    /**
99
     * @param Builder $query
100
     * @param array   $options
101
     *
102
     * @return void
103
     */
104
    private function queryDisplayEmpty(Builder $query, array $options)
105
    {
106
        if (empty($options['displayEmpty'])) {
107
            $query->having('posts_count', '>', 0);
108
        }
109
    }
110
111
    /**
112
     * @param Builder $query
113
     * @param array   $options
114
     *
115
     * @return void
116
     */
117
    private function queryPostSlug(Builder $query, array $options)
118
    {
119
        if (!empty($options['post'])) {
120
            $query->whereHas(
121
                'posts',
122
                static function ($query) use ($options) {
123
                    ModelAbstract::whereTranslatableProperty($query, 'slug', $options['post']);
124
                }
125
            );
126
        }
127
    }
128
129
    /**
130
     * @param Builder $query
131
     * @param array   $options
132
     *
133
     * @return void
134
     */
135
    private function queryLimit(Builder $query, array $options)
136
    {
137
        if (!empty($options['limit'])) {
138
            $query->take($options['limit']);
139
        }
140
    }
141
142
    /**
143
     * @param Builder $query
144
     * @param array   $options
145
     *
146
     * @return void
147
     */
148
    private function queryOrderBy(Builder $query, array $options)
149
    {
150
        if (!empty($options['sort']) && \array_key_exists($options['sort'], static::$sortingOptions)) {
151
            if ($options['sort'] === 'random') {
152
                $query->inRandomOrder();
153
            } else {
154
                list($sortField, $sortDirection) = explode(' ', $options['sort']);
155
156
                $query->orderBy($sortField, $sortDirection);
157
            }
158
        }
159
    }
160
161
    /**
162
     * @param Builder $query
163
     * @param array   $options
164
     *
165
     * @return void
166
     */
167
    private function withRelation(Builder $query, array $options)
168
    {
169
        if (!empty($options['fetchPosts'])) {
170
            $query->with(
171
                [
172
                    'posts' => function (HasMany $query) use ($options) {
173
                        $query->isPublished();
174
175
                        $this->handleExceptions($query->getQuery(), $options);
176
                    }
177
                ]
178
            );
179
        }
180
181
        $query->withCount(
182
            [
183
                'posts' => function ($query) use ($options) {
184
                    $query->isPublished();
185
186
                    $this->handleExceptions($query, $options);
187
                }
188
            ]
189
        );
190
    }
191
192
    /**
193
     * @param Builder $query
194
     */
195
    private function queryGroupBy(Builder $query)
196
    {
197
        $query->groupBy('id');
198
    }
199
200
    /**
201
     * @param Builder   $query
202
     * @param array     $options
203
     */
204
    private function handleExceptions(Builder $query, array $options)
205
    {
206
        if (!empty($options['exceptPosts'])) {
207
            PostListExceptionsTrait::handleExceptionsByPost($query, $options['exceptPosts']);
208
        }
209
210
        if (!empty($options['exceptCategories'])) {
211
            PostListExceptionsTrait::handleExceptionsByCategory($query, $options['exceptCategories']);
212
        }
213
    }
214
}
215