Passed
Push — master ( 4f50ad...2698b3 )
by Michael
02:21
created

CustomOrderTrait::setOrders()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 3
nc 2
nop 3
1
<?php
2
3
namespace Blasttech\EloquentRelatedPlus;
4
5
use Illuminate\Database\Eloquent\Builder;
6
use InvalidArgumentException;
7
8
/**
9
 * Trait CustomOrderTrait
10
 *
11
 * @property array order_fields
12
 * @property array order_defaults
13
 * @property array order_relations
14
 * @property array order_with
15
 * @property array search_fields
16
 * @property string connection
17
 */
18
trait CustomOrderTrait
19
{
20
    /**
21
     * Check $order_fields and $order_defaults are set
22
     *
23
     * @param string $orderField
24
     * @param string $direction
25
     * @return bool
26
     */
27
    protected function hasOrderFieldsAndDefaults($orderField, $direction)
28
    {
29
        return $this->hasOrderFields() && $this->hasOrderDefaults($orderField, $direction);
30
    }
31
32
    /**
33
     * Check $this->order_fields set correctly
34
     *
35
     * @return bool
36
     */
37
    protected function hasOrderFields()
38
    {
39
        return $this->hasProperty('order_fields');
40
    }
41
42
    /**
43
     * @param string $attributeName
44
     * @param bool $canBeEmpty
45
     * @return bool
46
     */
47
    protected function hasProperty($attributeName, $canBeEmpty = true)
48
    {
49
        if (!isset($this->$attributeName) || !is_array($this->$attributeName) ||
50
            (!$canBeEmpty && empty($this->$attributeName))) {
51
            throw new InvalidArgumentException(get_class($this) . ' ' . $attributeName . ' property not set correctly.');
52
        }
53
54
        return true;
55
    }
56
57
    /**
58
     * Check order defaults set correctly
59
     *
60
     * @param string $orderField
61
     * @param string $direction
62
     * @return bool
63
     */
64
    protected function hasOrderDefaults($orderField, $direction)
65
    {
66
        if ($orderField === '' || $direction === '') {
67
            return $this->hasProperty('order_defaults');
68
        }
69
70
        return true;
71
    }
72
73
    /**
74
     * Check $this->search_fields set correctly
75
     *
76
     * @return bool
77
     */
78
    protected function hasSearchFields()
79
    {
80
        return $this->hasProperty('search_fields', false);
81
    }
82
83
    /**
84
     * Override column if provided column not valid
85
     *
86
     * @param string $column
87
     * @return string
88
     */
89
    protected function setOrderColumn($column)
90
    {
91
        // If $column not in order_fields list, use default
0 ignored issues
show
Unused Code Comprehensibility introduced by
36% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
92
        if ($column == '' || !isset($this->order_fields[$column])) {
93
            $column = $this->order_defaults['field'];
94
        }
95
96
        return $column;
97
    }
98
99
    /**
100
     * Override direction if provided direction not valid
101
     *
102
     * @param string $direction
103
     * @return string
104
     */
105
    protected function setOrderDirection($direction)
106
    {
107
        // If $direction not asc or desc, use default
0 ignored issues
show
Unused Code Comprehensibility introduced by
36% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
108
        if ($direction == '' || !in_array(strtoupper($direction), ['ASC', 'DESC'])) {
109
            $direction = $this->order_defaults['dir'];
110
        }
111
112
        return $direction;
113
    }
114
115
    /**
116
     * Set order based on order_fields
117
     *
118
     * @param Builder $query
119
     * @param string $column
120
     * @param string $direction
121
     * @return Builder
122
     */
123
    protected function setOrder($query, $column, $direction)
124
    {
125
        if (is_array($this->order_fields[$column])) {
126
            return $this->setOrders($query, $column, $direction);
127
        }
128
129
        return $query->orderByCheckModel($this->order_fields[$column], $direction);
130
    }
131
132
    /**
133
     * Set order based on multiple order_fields
134
     *
135
     * @param Builder $query
136
     * @param string $column
137
     * @param string $direction
138
     * @return Builder
139
     */
140
    protected function setOrders($query, $column, $direction)
141
    {
142
        foreach ($this->order_fields[$column] as $dbField) {
143
            $query->orderByCheckModel($dbField, $direction);
144
        }
145
146
        return $query;
147
    }
148
149
    /**
150
     * Join a related table if not already joined
151
     *
152
     * @param Builder $query
153
     * @param string $table
154
     * @return Builder
155
     */
156
    protected function joinRelatedTable($query, $table)
157
    {
158
        if (isset($this->order_relations[$table]) &&
159
            !$this->hasJoin($query, $table, $this->order_relations[$table])) {
160
            $columnRelations = $this->order_relations[$table];
161
162
            $query->modelJoin($columnRelations, '=', 'left', false, false);
163
        }
164
165
        return $query;
166
    }
167
168
    /**
169
     * Check if this model has already been joined to a table or relation
170
     *
171
     * @param Builder $builder
172
     * @param string $table
173
     * @param \Illuminate\Database\Eloquent\Relations\Relation $relation
174
     * @return bool
175
     */
176
    protected function hasJoin(Builder $builder, $table, $relation)
177
    {
178
        if (!$this->isJoinedToTable($builder, $table)) {
179
            return $this->isEagerLoaded($builder, $relation);
180
        }
181
182
        return true;
183
    }
184
185
    /**
186
     * Check if model is currently joined to $table
187
     *
188
     * @param Builder $builder
189
     * @param string $table
190
     * @return bool
191
     */
192
    protected function isJoinedToTable(Builder $builder, $table)
193
    {
194
        $joins = $builder->getQuery()->joins;
195
        if (!is_null($joins)) {
0 ignored issues
show
introduced by
The condition ! is_null($joins) can never be false.
Loading history...
196
            foreach ($joins as $joinClause) {
197
                if ($joinClause->table == $table) {
198
                    return true;
199
                }
200
            }
201
        }
202
203
        return false;
204
    }
205
206
    /**
207
     * Check if relation exists in eager loads
208
     *
209
     * @param Builder $builder
210
     * @param \Illuminate\Database\Eloquent\Relations\Relation $relation
211
     * @return bool
212
     */
213
    protected function isEagerLoaded(Builder $builder, $relation)
214
    {
215
        $eagerLoads = $builder->getEagerLoads();
216
217
        return !is_null($eagerLoads) && in_array($relation, $eagerLoads);
218
    }
219
}
220