Completed
Push — 5.1 ( c7eca6...1f8916 )
by Jarek
05:49
created

Builder::aggregate()   B

Complexity

Conditions 4
Paths 8

Size

Total Lines 34
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
c 2
b 1
f 0
dl 0
loc 34
rs 8.5806
cc 4
eloc 14
nc 8
nop 2
1
<?php
2
3
namespace Sofa\Eloquence\Query;
4
5
use Sofa\Eloquence\Subquery;
6
7
class Builder extends \Illuminate\Database\Query\Builder
8
{
9
    /**
10
     * Execute an aggregate function on the database.
11
     *
12
     * @param  string  $function
13
     * @param  array   $columns
14
     * @return float|int
15
     */
16
    public function aggregate($function, $columns = ['*'])
17
    {
18
        $this->aggregate = compact('function', 'columns');
19
20
        $previousColumns = $this->columns;
21
22
        if (!$this->from instanceof Subquery) {
23
            // We will also back up the select bindings since the select clause will be
24
            // removed when performing the aggregate function. Once the query is run
25
            // we will add the bindings back onto this query so they can get used.
26
            $previousSelectBindings = $this->bindings['select'];
27
28
            $this->bindings['select'] = [];
29
        }
30
31
        $results = $this->get($columns);
32
33
        // Once we have executed the query, we will reset the aggregate property so
34
        // that more select queries can be executed against the database without
35
        // the aggregate value getting in the way when the grammar builds it.
36
        $this->aggregate = null;
0 ignored issues
show
Documentation Bug introduced by
It seems like null of type null is incompatible with the declared type array of property $aggregate.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
37
38
        $this->columns = $previousColumns;
39
40
        if (!$this->from instanceof Subquery) {
41
            $this->bindings['select'] = $previousSelectBindings;
0 ignored issues
show
Bug introduced by
The variable $previousSelectBindings does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
42
        }
43
44
        if (isset($results[0])) {
45
            $result = array_change_key_case((array) $results[0]);
46
47
            return $result['aggregate'];
48
        }
49
    }
50
51
    /**
52
     * Backup some fields for the pagination count.
53
     *
54
     * @return void
55
     */
56
    protected function backupFieldsForCount()
57
    {
58
        foreach (['orders', 'limit', 'offset', 'columns'] as $field) {
59
            $this->backups[$field] = $this->{$field};
60
61
            $this->{$field} = null;
62
        }
63
64
        $bindings = ($this->from instanceof Subquery) ? ['order'] : ['order', 'select'];
65
66
        foreach ($bindings as $key) {
67
            $this->bindingBackups[$key] = $this->bindings[$key];
68
69
            $this->bindings[$key] = [];
70
        }
71
    }
72
73
    /**
74
     * Restore some fields after the pagination count.
75
     *
76
     * @return void
77
     */
78
    protected function restoreFieldsForCount()
79
    {
80
        foreach ($this->backups as $field => $value) {
81
            $this->{$field} = $value;
82
        }
83
84
        foreach ($this->bindingBackups as $key => $value) {
85
            $this->bindings[$key] = $value;
86
        }
87
88
        $this->backups = $this->bindingBackups = [];
89
    }
90
}
91