Passed
Push — dependabot/github_actions/depe... ( d1016c )
by
unknown
11:16
created

QueriesAranguentRelationships::withAggregate()   B

Complexity

Conditions 8
Paths 21

Size

Total Lines 67
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 29
CRAP Score 8.0526

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 28
c 2
b 0
f 0
dl 0
loc 67
ccs 29
cts 32
cp 0.9063
rs 8.4444
cc 8
nc 21
nop 3
crap 8.0526

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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 IlluminateQueryBuilder;
7
use Illuminate\Database\Query\Expression;
8
use Illuminate\Support\Str;
9
use LaravelFreelancerNL\Aranguent\Query\Builder as QueryBuilder;
10
use LaravelFreelancerNL\FluentAQL\Expressions\FunctionExpression;
11
use LaravelFreelancerNL\FluentAQL\QueryBuilder as ArangoQueryBuilder;
12
13
trait QueriesAranguentRelationships
14
{
15
    /**
16
     * Add a sub-query count clause to this query.
17
     *
18
     * @param  QueryBuilder  $query
19
     * @param  string  $operator
20
     * @param  int  $count
21
     * @param  string  $boolean
22
     * @return IlluminateBuilder
23
     */
24 1
    protected function addWhereCountQuery(
25
        IlluminateQueryBuilder $query,
26
        $operator = '>=',
27
        $count = 1,
28
        $boolean = 'and'
29
    ): IlluminateBuilder {
30 1
        $query->grammar->compileSelect($query);
31
32 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

32
        return $this->/** @scrutinizer ignore-call */ where(
Loading history...
33 1
            $query->aqb->count($query->aqb),
34 1
            $operator,
35 1
            is_numeric($count) ? new Expression($count) : $count,
0 ignored issues
show
introduced by
The condition is_numeric($count) is always true.
Loading history...
36 1
            $boolean
37 1
        );
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 90
    public function withAggregate($relations, $column, $function = null)
50
    {
51 90
        $result = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $result is dead and can be removed.
Loading history...
52
53 90
        if (empty($relations)) {
54 90
            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 1
                $this
83 1
            );
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);
0 ignored issues
show
Bug introduced by
It seems like $function can also be of type null; however, parameter $function of LaravelFreelancerNL\Aran...tAggregateResultQuery() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

99
            $result = $this->getAggregateResultQuery($query, /** @scrutinizer ignore-type */ $function);
Loading history...
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 1
            );
107
108
            /** @phpstan-ignore-next-line */
109 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

109
            $this->/** @scrutinizer ignore-call */ 
110
                   selectSub(
Loading history...
110 1
                $result,
111 1
                $alias
112 1
            );
113
        }
114
115 1
        return $this;
116
    }
117
118 1
    protected function getAggregateResultQuery(QueryBuilder $query, string $function): QueryBuilder|FunctionExpression
119
    {
120 1
        if ($function) {
121 1
            $query->grammar->compileSelect($query);
122 1
            $result = (new ArangoQueryBuilder())->$function($query->aqb);
123
        }
124 1
        if (! $function) {
125
            $query->limit(1);
126
            $result = $query;
127
        }
128
129 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...
130
    }
131
}
132