Completed
Push — master ( f63084...bb5576 )
by Michael
05:17
created

CustomOrderTrait::scopeSetCustomOrder()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
cc 2
eloc 5
nc 2
nop 3
1
<?php
2
3
namespace Blasttech\EloquentRelatedPlus;
4
5
use Illuminate\Database\Eloquent\Builder;
6
use Illuminate\Database\Eloquent\Model;
7
8
/**
9
 * Trait RelatedPlusTrait
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
     * Set the model order
22
     *
23
     * @param Builder $query
24
     * @param string $column
25
     * @param string $direction
26
     * @return Builder
27
     */
28
    public function scopeSetCustomOrder(Builder $query, $column, $direction)
29
    {
30
        if (isset($this->order_defaults)) {
31
            $column = $this->setColumn($column);
32
            $direction = $this->setDirection($direction);
33
        }
34
35
        return $this->setOrder($query, $column, $direction);
36
    }
37
38
    /**
39
     * Override column if provided column not valid
40
     *
41
     * @param string $column
42
     * @return string
43
     */
44
    private function setColumn($column)
45
    {
46
        // If $column not in order_fields list, use default
47
        if ($column == '' || !isset($this->order_fields[$column])) {
48
            $column = $this->order_defaults['field'];
49
        }
50
51
        return $column;
52
    }
53
54
    /**
55
     * Override direction if provided direction not valid
56
     *
57
     * @param string $direction
58
     * @return string
59
     */
60
    private function setDirection($direction)
61
    {
62
        // If $direction not asc or desc, use default
63
        if ($direction == '' || !in_array(strtoupper($direction), ['ASC', 'DESC'])) {
64
            $direction = $this->order_defaults['dir'];
65
        }
66
67
        return $direction;
68
    }
69
70
    /**
71
     * Set order based on order_fields
72
     *
73
     * @param Builder $query
74
     * @param string $column
75
     * @param string $direction
76
     * @return Builder
77
     */
78
    private function setOrder($query, $column, $direction)
79
    {
80
        if (!is_array($this->order_fields[$column])) {
81
            $query->orderByCheckModel($this->order_fields[$column], $direction);
82
        } else {
83
            foreach ($this->order_fields[$column] as $dbField) {
84
                $query->orderByCheckModel($dbField, $direction);
85
            }
86
        }
87
88
        return $query;
89
    }
90
91
    /**
92
     * Check if column being sorted by is from a related model
93
     *
94
     * @param Builder $query
95
     * @param string $column
96
     * @param string $direction
97
     * @return Builder
98
     */
99
    public function scopeOrderByCheckModel(Builder $query, $column, $direction)
100
    {
101
        /** @var Model $query */
102
        $query->orderBy(DB::raw($column), $direction);
103
104
        $periodPos = strpos($column, '.');
105
        if (isset($this->order_relations) && ($periodPos !== false || isset($this->order_relations[$column]))) {
106
            $table = ($periodPos !== false ? substr($column, 0, $periodPos) : $column);
107
            $query = $this->joinRelatedTable($query, $table);
0 ignored issues
show
Bug introduced by
It seems like joinRelatedTable() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
108
        }
109
110
        return $query;
111
    }
112
}