Completed
Push — master ( 6575c1...0d16be )
by Scott
01:59
created

Category::scopeIsActive()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
1
<?php namespace Bedard\Shop\Models;
2
3
use Lang;
4
use Model;
5
6
/**
7
 * Category Model.
8
 */
9
class Category extends Model
10
{
11
    use \October\Rain\Database\Traits\Validation;
12
13
    /**
14
     * @var string The database table used by the model.
15
     */
16
    public $table = 'bedard_shop_categories';
17
18
    /**
19
     * @var array Default attributes
20
     */
21
    public $attributes = [
22
        'description_html' => '',
23
        'description_plain' => '',
24
    ];
25
26
    /**
27
     * @var array Attribute casting
28
     */
29
    protected $casts = [
30
        'is_active' => 'boolean',
31
        'is_visible' => 'boolean',
32
    ];
33
34
    /**
35
     * @var array Guarded fields
36
     */
37
    protected $guarded = ['*'];
38
39
    /**
40
     * @var array Fillable fields
41
     */
42
    protected $fillable = [
43
        'is_active',
44
        'is_visible',
45
        'description_html',
46
        'description_plain',
47
        'name',
48
        'parent_id',
49
        'slug',
50
    ];
51
52
    /**
53
     * @var array Relations
54
     */
55
    public $attachMany = [
56
        'thumbnails' => 'System\Models\File',
57
    ];
58
59
    public $belongsTo = [
60
        'parent' => 'Bedard\Shop\Models\Category',
61
    ];
62
63
    public $belongsToMany = [
64
        'discounts' => [
65
            'Bedard\Shop\Models\Discount',
66
            'table' => 'bedard_shop_category_discount',
67
        ],
68
        'products' => [
69
            'Bedard\Shop\Models\Product',
70
            'table' => 'bedard_shop_category_product',
71
            'pivot' => ['is_inherited'],
72
        ],
73
    ];
74
75
    /**
76
     * @var array Validation
77
     */
78
    public $rules = [
79
        'name' => 'required',
80
        'slug' => 'required|unique:bedard_shop_categories',
81
    ];
82
83
    /**
84
     * After delete.
85
     *
86
     * @return void
87
     */
88
    public function afterDelete()
89
    {
90
        $this->syncInheritedProductsAfterDelete();
91
    }
92
93
    /**
94
     * After save.
95
     *
96
     * @return void
97
     */
98
    public function afterSave()
99
    {
100
        $this->syncInheritedProductsAfterSave();
101
    }
102
103
    /**
104
     * Before save.
105
     *
106
     * @return void
107
     */
108
    public function beforeSave()
109
    {
110
        $this->setPlainDescription();
111
        $this->setNullParentId();
112
    }
113
114
    /**
115
     * Get the parent IDs of every category.
116
     *
117
     * @return array
118
     */
119
    public static function getParentCategoryIds()
120
    {
121
        $categories = self::select('id', 'parent_id')->get();
122
123
        $tree = [];
124
        foreach ($categories as $category) {
125
            $tree[$category->id] = self::walkParentCategories($categories, $category);
126
        }
127
128
        return $tree;
129
    }
130
131
    /**
132
     * Find the child ids of a parent category.
133
     *
134
     * @param  \Bedard\Shop\Models\Category|int     $parent
135
     * @param  \October\Rain\Database\Collection    $categories
136
     * @return array
137
     */
138
    public static function getChildIds($parent, \October\Rain\Database\Collection $categories = null)
139
    {
140
        if ($categories === null) {
141
            $categories = self::whereNotNull('parent_id')
142
                ->where('id', '<>', $parent)
143
                ->select('id', 'parent_id')
144
                ->get();
145
        }
146
147
        $children = [];
148
        foreach ($categories as $category) {
149
            if ($category->parent_id == $parent) {
150
                $children[] = $category->id;
151
                $children = array_merge($children, self::getChildIds($category->id, $categories));
152
            }
153
        }
154
155
        return $children;
156
    }
157
158
    public static function getParentIds($children, \October\Rain\Database\Collection $categories = null)
159
    {
160
        if (! is_array($children)) {
161
            $children = [$children];
162
        }
163
164
        if ($categories === null) {
165
            $categories = self::select('id', 'parent_id')->get();
166
        }
167
168
        $parents = [];
169
        foreach ($children as $child) {
170
            $category = $categories->filter(function ($model) use ($child) {
171
                return $model->id == $child;
172
            })->first();
173
174
            while ($category && $category->parent_id) {
175
                $parents[] = $category->parent_id;
176
                $category = $categories->filter(function ($model) use ($category) {
177
                    return $model->id == $category->parent_id;
178
                })->first();
179
            }
180
        }
181
182
        return array_unique($parents);
183
    }
184
185
    /**
186
     * Get options for the parent form field.
187
     *
188
     * @return array
189
     */
190
    public function getParentIdOptions()
191
    {
192
        $options = $this->exists
193
            ? self::where('id', '<>', $this->id)->isNotChildOf($this->id)->orderBy('name')->lists('name', 'id')
194
            : self::orderBy('name')->lists('name', 'id');
195
196
        array_unshift($options, '<em>'.Lang::get('bedard.shop::lang.categories.form.no_parent').'</em>');
197
198
        return $options;
199
    }
200
201
    /**
202
     * Query categories that are listed as active.
203
     *
204
     * @param  \October\Rain\Database\Builder   $query
205
     * @param  \Bedard\Shop\Models\Category|int $parent
0 ignored issues
show
Bug introduced by
There is no parameter named $parent. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
206
     * @return \October\Rain\Database\Builder
207
     */
208
    public function scopeIsActive($query)
209
    {
210
        return $query->whereIsActive(true);
211
    }
212
213
    /**
214
     * Query categories that are listed as not active.
215
     *
216
     * @param  \October\Rain\Database\Builder   $query
217
     * @param  \Bedard\Shop\Models\Category|int $parent
0 ignored issues
show
Bug introduced by
There is no parameter named $parent. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
218
     * @return \October\Rain\Database\Builder
219
     */
220
    public function scopeIsNotActive($query)
221
    {
222
        return $query->whereIsActive(false);
223
    }
224
225
    /**
226
     * Query categories that are children of another category.
227
     *
228
     * @param  \October\Rain\Database\Builder   $query
229
     * @param  \Bedard\Shop\Models\Category|int $parent
230
     * @return \October\Rain\Database\Builder
231
     */
232
    public function scopeIsChildOf($query, $parent)
233
    {
234
        return $query->whereIn('id', self::getChildIds($parent));
235
    }
236
237
    /**
238
     * Query categories that are not children of another category.
239
     *
240
     * @param  \October\Rain\Database\Builder   $query
241
     * @param  \Bedard\Shop\Models\Category|int $parent
242
     * @return \October\Rain\Database\Builder
243
     */
244
    public function scopeIsNotChildOf($query, $parent)
245
    {
246
        return $query->whereNotIn('id', self::getChildIds($parent));
247
    }
248
249
    /**
250
     * Query categories that are a parent of another category.
251
     *
252
     * @param  \October\Rain\Database\Builder   $query
253
     * @param  int                              $child
254
     * @return \October\Rain\Database\Builder
255
     */
256
    public function scopeIsParentOf($query, $child)
257
    {
258
        return $query->whereIn('id', self::getParentIds($child));
259
    }
260
261
    /**
262
     * Query categories that are not a parent of another category.
263
     *
264
     * @param  \October\Rain\Database\Builder   $query
265
     * @param  int                              $child
266
     * @return \October\Rain\Database\Builder
267
     */
268
    public function scopeIsNotParentOf($query, $child)
269
    {
270
        return $query->whereNotIn('id', self::getParentIds($child));
271
    }
272
273
    /**
274
     * Convert falsey parent id values to null.
275
     *
276
     * @return void
277
     */
278
    public function setNullParentId()
279
    {
280
        if (! $this->parent_id) {
281
            $this->parent_id = null;
282
        }
283
    }
284
285
    /**
286
     * Set the plain text description_html.
287
     *
288
     * @return void
289
     */
290
    public function setPlainDescription()
291
    {
292
        $this->description_plain = strip_tags($this->description_html);
293
    }
294
295
    /**
296
     * If the model wasn't deleted in bulk, sync inherited categories.
297
     *
298
     * @return void
299
     */
300
    public function syncInheritedProductsAfterDelete()
301
    {
302
        if (! $this->dontSyncAfterDelete) {
303
            Product::syncAllInheritedCategories();
304
        }
305
    }
306
307
    /**
308
     * If the parent id has changed, resync all products.
309
     *
310
     * @return void
311
     */
312
    public function syncInheritedProductsAfterSave()
313
    {
314
        if ($this->isDirty('parent_id')) {
315
            Product::syncAllInheritedCategories();
316
        }
317
    }
318
319
    /**
320
     * Itterate over categories and update them with the given values.
321
     *
322
     * @param  array    $categories
323
     * @return void
324
     */
325
    public static function updateMany(array $categories)
326
    {
327
        foreach ($categories as $category) {
328
            $id = $category['id'];
329
            unset($category['id']);
330
            self::whereId($id)->update($category);
331
        }
332
    }
333
334
    /**
335
     * Walk up the category tree gathering parent IDs.
336
     *
337
     * @param  \October\Rain\Database\Collection    $categories     All categories
338
     * @param  \Bedard\Shop\Models\Category         $category       Current category being walked over
339
     * @param  array                                $tree           Tree of parent IDs
340
     * @return arrau
341
     */
342
    public static function walkParentCategories($categories, $category, $tree = [])
343
    {
344
        if ($category && $category->parent_id !== null) {
345
            $tree[] = $category->parent_id;
346
            $tree = array_merge($tree, self::walkParentCategories($categories, $categories->find($category->parent_id)));
347
        }
348
349
        return $tree;
350
    }
351
}
352