Completed
Push — master ( 17152c...89f64c )
by Scott
02:25
created

ProductsQuery::applyOrderByStatements()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.2
c 0
b 0
f 0
cc 4
eloc 8
nc 3
nop 0
1
<?php namespace Bedard\Shop\Classes;
2
3
use Bedard\Shop\Models\Category;
4
use Bedard\Shop\Models\Product;
5
6
class ProductsQuery
7
{
8
    /**
9
     * @var \Bedard\Shop\Models\Category    The category to query products for.
10
     */
11
    protected $category;
12
13
    /**
14
     * @var array   Query parameters.
15
     */
16
    protected $params;
17
18
    /**
19
     * @var \October\Rain\Databse\Builder   Products query.
20
     */
21
    public $query;
22
23
    /**
24
     * Construct.
25
     *
26
     * @param \Bedard\Shop\Models\Category  $category
27
     * @param array                         $params
28
     */
29
    public function __construct(Category $category, array $params = [])
30
    {
31
        $this->category = $category;
32
        $this->params = $params;
33
34
        $this->buildQuery();
35
    }
36
37
    /**
38
     * Build up the products query.
39
     *
40
     * @return void
41
     */
42
    protected function buildQuery()
43
    {
44
        $this->query = Product::isEnabled()->joinPrice();
45
46
        $this->applyWhereStatements();
47
        $this->applyPagination();
48
        $this->applyOrderByStatements();
49
        $this->loadRelatedModels();
50
    }
51
52
    /**
53
     * Apply a custom sort order to a products query.
54
     *
55
     * @return void
56
     */
57
    protected function applyCustomOrder()
58
    {
59
        $this->query
60
            ->join('bedard_shop_category_product', function ($join) {
61
                $join->on('bedard_shop_products.id', '=', 'bedard_shop_category_product.product_id')
62
                    ->where('bedard_shop_category_product.category_id', '=', $this->category->id);
63
            })
64
            ->orderBy('bedard_shop_category_product.sort_order');
65
    }
66
67
    /**
68
     * Apply an order by statement to the products query.
69
     *
70
     * @return void
71
     */
72
    protected function applyOrderByStatements()
73
    {
74
        if (array_key_exists('products_sort_column', $this->params) &&
75
            array_key_exists('products_sort_direction', $this->params)) {
76
            $this->query->orderBy($this->params['products_sort_column'], $this->params['products_sort_direction']);
77
        } elseif ($this->category->isCustomSorted()) {
78
            $this->applyCustomOrder();
79
        } else {
80
            $this->query->orderBy($this->category->product_sort_column, $this->category->product_sort_direction);
81
        }
82
    }
83
84
    /**
85
     * Paginate the results.
86
     *
87
     * @return void
88
     */
89
    protected function applyPagination()
90
    {
91
        if (array_key_exists('page', $this->params) && $this->category->isPaginated()) {
92
            $resultsPerPage = $this->category->resultsPerPage();
93
            $resultsToSkip = ($this->params['page'] - 1) * $resultsPerPage;
94
95
            $this->query
96
                ->offset($resultsToSkip)
97
                ->limit($resultsPerPage);
98
        }
99
    }
100
101
    /**
102
     * Apply filters to a products query.
103
     *
104
     * @return void
105
     */
106
    protected function applyProductFilters()
107
    {
108
        $this->query->where(function ($q) {
109
            foreach ($this->category->filters as $filter) {
110
                $right = $filter->getRightClause();
111
                $q->where($filter->left, $filter->comparator, $right);
112
            }
113
        });
114
    }
115
116
    /**
117
     * Restrict our query to products that should be visible in our category.
118
     *
119
     * @return void
120
     */
121
    protected function applyWhereStatements()
122
    {
123
        // if the category is filtered, grab our products from those
124
        if ($this->category->isFiltered()) {
125
            $this->applyProductFilters();
126
        }
127
128
        // otherwise grab all products appearing in our category
129
        else {
130
            $this->query->appearingInCategory($this->category->id);
131
        }
132
    }
133
134
    /**
135
     * Load related models.
136
     *
137
     * @return void
138
     */
139
    protected function loadRelatedModels()
140
    {
141
        if (array_key_exists('load_thumbnails', $this->params) && $this->params['load_thumbnails']) {
142
            $this->query->with('thumbnails');
143
        }
144
    }
145
}
146