Passed
Push — master ( ef1328...91a1d1 )
by Bas
13:32 queued 09:25
created

QueriesAranguentRelationships   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 123
Duplicated Lines 0 %

Test Coverage

Coverage 87.5%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 13
eloc 42
c 1
b 0
f 0
dl 0
loc 123
ccs 35
cts 40
cp 0.875
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A addWhereCountQuery() 0 14 2
B withAggregate() 0 66 8
A getAggregateResultQuery() 0 12 3
1
<?php
2
3
namespace LaravelFreelancerNL\Aranguent\Eloquent\Concerns;
4
5
use Illuminate\Database\Eloquent\Builder as IlluminateBuilder;
6
use Illuminate\Database\Query\Builder as QueryBuilder;
7
use Illuminate\Database\Query\Expression;
8
use Illuminate\Support\Str;
9
use LaravelFreelancerNL\FluentAQL\QueryBuilder as ArangoQueryBuilder;
10
11
trait QueriesAranguentRelationships
12
{
13
    /**
14
     * Add a sub-query count clause to this query.
15
     *
16
     * @param  QueryBuilder  $query
17
     * @param  string  $operator
18
     * @param  int  $count
19
     * @param  string  $boolean
20
     * @return IlluminateBuilder
21
     */
22 1
    protected function addWhereCountQuery(
23
        QueryBuilder $query,
24
        $operator = '>=',
25
        $count = 1,
26
        $boolean = 'and'
27
    ): IlluminateBuilder {
28
29 1
        $query->grammar->compileSelect($query);
30
31 1
        return $this->where(
0 ignored issues
show
Bug introduced by
It seems like where() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

31
        return $this->/** @scrutinizer ignore-call */ where(
Loading history...
32 1
            $query->aqb->count($query->aqb),
33
            $operator,
34 1
            is_numeric($count) ? new Expression($count) : $count,
0 ignored issues
show
introduced by
The condition is_numeric($count) is always true.
Loading history...
35
            $boolean
36
        );
37
    }
38
39
40
    /**
41
     * Add subselect queries to include an aggregate value for a relationship.
42
     * Overrides method in QueriesRelationships trait
43
     *
44
     * @param  mixed  $relations
45
     * @param  string|null  $column
46
     * @param  string  $function
47
     * @return $this
48
     */
49 72
    public function withAggregate($relations, $column, $function = null)
50
    {
51 72
        $result = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $result is dead and can be removed.
Loading history...
52
53 72
        if (empty($relations)) {
54 72
            return $this;
55
        }
56
57 1
        if (is_null($this->query->columns)) {
58 1
            $this->query->select([$this->query->from . '.*']);
59
        }
60
61 1
        $relations = is_array($relations) ? $relations : [$relations];
62
63 1
        foreach ($this->parseWithRelations($relations) as $name => $constraints) {
0 ignored issues
show
Bug introduced by
It seems like parseWithRelations() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

63
        foreach ($this->/** @scrutinizer ignore-call */ parseWithRelations($relations) as $name => $constraints) {
Loading history...
64
            // First we will determine if the name has been aliased using an "as" clause on the name
65
            // and if it has we will extract the actual relationship name and the desired name of
66
            // the resulting column. This allows multiple aggregates on the same relationships.
67 1
            $segments = explode(' ', $name);
68
69 1
            unset($alias);
70
71 1
            if (count($segments) === 3 && Str::lower($segments[1]) === 'as') {
72
                [$name, $alias] = [$segments[0], $segments[2]];
73
            }
74
75 1
            $relation = $this->getRelationWithoutConstraints($name);
0 ignored issues
show
Bug introduced by
It seems like getRelationWithoutConstraints() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

75
            /** @scrutinizer ignore-call */ 
76
            $relation = $this->getRelationWithoutConstraints($name);
Loading history...
76
77
            // Here, we will grab the relationship sub-query and prepare to add it to the main query
78
            // as a sub-select. First, we'll get the "has" query and use that to get the relation
79
            // sub-query. We'll format this relationship name and append this column if needed.
80 1
            $query = $relation->getRelationExistenceQuery(
81 1
                $relation->getRelated()->newQuery(),
82
                $this
83
            );
84
85 1
            $query->callScope($constraints);
86
87 1
            $query = $query->mergeConstraintsFrom($relation->getQuery())->toBase();
88
89
            // If the query contains certain elements like orderings / more than one column selected
90
            // then we will remove those elements from the query so that it will execute properly
91
            // when given to the database. Otherwise, we may receive SQL errors or poor syntax.
92 1
            $query->orders = null;
93
94 1
            if (count($query->columns) > 1) {
95
                $query->columns = [$query->columns[0]];
96
                $query->bindings['select'] = [];
97
            }
98
99 1
            $result = $this->getAggregateResultQuery($query, $function);
100
101
            // Finally, we will make the proper column alias to the query and run this sub-select on
102
            // the query builder. Then, we will return the builder instance back to the developer
103
            // for further constraint chaining that needs to take place on the query as needed.
104 1
            $alias = $alias ?? Str::snake(
105 1
                preg_replace('/[^[:alnum:][:space:]_]/u', '', "$name $function $column")
106
            );
107
108 1
            $this->selectSub(
0 ignored issues
show
Bug introduced by
It seems like selectSub() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

108
            $this->/** @scrutinizer ignore-call */ 
109
                   selectSub(
Loading history...
109 1
                $result,
110
                $alias
111
            );
112
        }
113
114 1
        return $this;
115
    }
116
117
    /**
118
     * @param $query
119
     * @param $function
120
     * @return mixed
121
     */
122 1
    protected function getAggregateResultQuery($query, $function)
123
    {
124 1
        if ($function) {
125 1
            $query->grammar->compileSelect($query);
126 1
            $result = (new ArangoQueryBuilder())->$function($query->aqb);
127
        }
128 1
        if (! $function) {
129
            $query->limit(1);
130
            $result = $query;
131
        }
132
133 1
        return $result;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $result does not seem to be defined for all execution paths leading up to this point.
Loading history...
134
    }
135
}
136