Passed
Push — master ( 4bd2dc...6390fb )
by Michael
02:32
created

CustomOrderTrait::hasProperty()   B

Complexity

Conditions 5
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 5
nc 2
nop 2
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
     * Check order defaults set correctly
44
     *
45
     * @param string $orderField
46
     * @param string $direction
47
     * @return bool
48
     */
49
    protected function hasOrderDefaults($orderField, $direction)
50
    {
51
        if ($orderField === '' || $direction === '') {
52
            return $this->hasProperty('order_defaults');
53
        } else {
54
            return true;
55
        }
56
    }
57
58
    /**
59
     * Check $this->search_fields set correctly
60
     *
61
     * @return bool
62
     */
63
    protected function hasSearchFields()
64
    {
65
        return $this->hasProperty('search_fields', false);
66
    }
67
68
    /**
69
     * @param string $attributeName
70
     * @param bool $canBeEmpty
71
     * @return bool
72
     */
73
    protected function hasProperty($attributeName, $canBeEmpty = true)
74
    {
75
        if (!isset($this->$attributeName) || !is_array($this->$attributeName) || $canBeEmpty || empty($this->$attributeName)) {
76
            throw new InvalidArgumentException(get_class($this) . ' ' . $attributeName . ' property not set correctly.');
77
        } else {
78
            return true;
79
        }
80
    }
81
82
    /**
83
     * Override column if provided column not valid
84
     *
85
     * @param string $column
86
     * @return string
87
     */
88
    protected function setOrderColumn($column)
89
    {
90
        // If $column not in order_fields list, use default
91
        if ($column == '' || !isset($this->order_fields[$column])) {
92
            $column = $this->order_defaults['field'];
93
        }
94
95
        return $column;
96
    }
97
98
    /**
99
     * Override direction if provided direction not valid
100
     *
101
     * @param string $direction
102
     * @return string
103
     */
104
    protected function setOrderDirection($direction)
105
    {
106
        // If $direction not asc or desc, use default
107
        if ($direction == '' || !in_array(strtoupper($direction), ['ASC', 'DESC'])) {
108
            $direction = $this->order_defaults['dir'];
109
        }
110
111
        return $direction;
112
    }
113
114
    /**
115
     * Set order based on order_fields
116
     *
117
     * @param Builder $query
118
     * @param string $column
119
     * @param string $direction
120
     * @return Builder
121
     */
122
    protected function setOrder($query, $column, $direction)
123
    {
124
        if (!is_array($this->order_fields[$column])) {
125
            $query->orderByCheckModel($this->order_fields[$column], $direction);
126
        } else {
127
            foreach ($this->order_fields[$column] as $dbField) {
128
                $query->orderByCheckModel($dbField, $direction);
129
            }
130
        }
131
132
        return $query;
133
    }
134
135
    /**
136
     * Join a related table if not already joined
137
     *
138
     * @param Builder $query
139
     * @param string $table
140
     * @return Builder
141
     */
142
    protected function joinRelatedTable($query, $table)
143
    {
144
        if (isset($this->order_relations[$table]) &&
145
            !$this->hasJoin($query, $table, $this->order_relations[$table])) {
146
            $columnRelations = $this->order_relations[$table];
147
148
            $query->modelJoin(
149
                $columnRelations,
150
                '=',
151
                'left',
152
                false,
153
                false
154
            );
155
        }
156
157
        return $query;
158
    }
159
160
    /**
161
     * Check if this model has already been joined to a table or relation
162
     *
163
     * @param Builder $builder
164
     * @param string $table
165
     * @param \Illuminate\Database\Eloquent\Relations\Relation $relation
166
     * @return bool
167
     */
168
    protected function hasJoin(Builder $builder, $table, $relation)
169
    {
170
        if (!$this->isJoinedToTable($builder, $table)) {
171
            return $this->isEagerLoaded($builder, $relation);
172
        } else {
173
            return true;
174
        }
175
    }
176
177
    /**
178
     * Check if model is currently joined to $table
179
     *
180
     * @param Builder $builder
181
     * @param string $table
182
     * @return bool
183
     */
184
    protected function isJoinedToTable(Builder $builder, $table)
185
    {
186
        $joins = $builder->getQuery()->joins;
187
        if (!is_null($joins)) {
188
            foreach ($joins as $joinClause) {
189
                if ($joinClause->table == $table) {
190
                    return true;
191
                }
192
            }
193
        }
194
195
        return false;
196
    }
197
198
    /**
199
     * Check if relation exists in eager loads
200
     *
201
     * @param Builder $builder
202
     * @param \Illuminate\Database\Eloquent\Relations\Relation $relation
203
     * @return bool
204
     */
205
    protected function isEagerLoaded(Builder $builder, $relation)
206
    {
207
        $eagerLoads = $builder->getEagerLoads();
208
209
        return !is_null($eagerLoads) && in_array($relation, $eagerLoads);
210
    }
211
}
212