Completed
Push — master ( c45db1...5d2dfa )
by ARCANEDEV
05:49
created

Partition::max()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 3
crap 1
1
<?php namespace Arcanedev\LaravelMetrics\Metrics;
2
3
use Arcanedev\LaravelMetrics\Results\PartitionResult;
4
use Illuminate\Support\Facades\DB;
5
6
/**
7
 * Class     Partition
8
 *
9
 * @package  Arcanedev\LaravelMetrics\Metrics
10
 * @author   ARCANEDEV <[email protected]>
11
 */
12
abstract class Partition extends Metric
13
{
14
    /* -----------------------------------------------------------------
15
     |  Getters
16
     | -----------------------------------------------------------------
17
     */
18
19
    /**
20
     * Get the metric type.
21
     *
22
     * @return string
23
     */
24 28
    public function type(): string
25
    {
26 28
        return 'partition';
27
    }
28
29
    /* -----------------------------------------------------------------
30
     |  Main Methods
31
     | -----------------------------------------------------------------
32
     */
33
34
    /**
35
     * Calculate the `count` of the metric.
36
     *
37
     * @param  \Illuminate\Database\Eloquent\Builder|string  $model
38
     * @param  string                                        $groupBy
39
     * @param  string|null                                   $column
40
     *
41
     * @return \Arcanedev\LaravelMetrics\Results\PartitionResult|mixed
42
     */
43 12
    public function count($model, string $groupBy, $column = null)
44
    {
45 12
        return $this->aggregate('count', $model, $column, $groupBy);
46
    }
47
48
    /**
49
     * Calculate the `average` of the metric.
50
     *
51
     * @param  \Illuminate\Database\Eloquent\Builder|string  $model
52
     * @param  string                                        $column
53
     * @param  string                                        $groupBy
54
     *
55
     * @return \Arcanedev\LaravelMetrics\Results\PartitionResult|mixed
56
     */
57 4
    public function average($model, string $column, string $groupBy)
58
    {
59 4
        return $this->aggregate('avg', $model, $column, $groupBy);
60
    }
61
62
    /**
63
     * Calculate the `sum` of the metric.
64
     *
65
     * @param  \Illuminate\Database\Eloquent\Builder|string  $model
66
     * @param  string                                        $column
67
     * @param  string                                        $groupBy
68
     *
69
     * @return \Arcanedev\LaravelMetrics\Results\PartitionResult|mixed
70
     */
71 4
    public function sum($model, string $column, string $groupBy)
72
    {
73 4
        return $this->aggregate('sum', $model, $column, $groupBy);
74
    }
75
76
    /**
77
     * Calculate the `max` of the metric.
78
     *
79
     * @param  \Illuminate\Database\Eloquent\Builder|string  $model
80
     * @param  string                                        $column
81
     * @param  string                                        $groupBy
82
     *
83
     * @return \Arcanedev\LaravelMetrics\Results\PartitionResult|mixed
84
     */
85 4
    public function max($model, string $column, string $groupBy)
86
    {
87 4
        return $this->aggregate('max', $model, $column, $groupBy);
88
    }
89
90
    /**
91
     * Calculate the `min` of the metric.
92
     *
93
     * @param  \Illuminate\Database\Eloquent\Builder|string  $model
94
     * @param  string                                        $column
95
     * @param  string                                        $groupBy
96
     *
97
     * @return \Arcanedev\LaravelMetrics\Results\PartitionResult|mixed
98
     */
99 4
    public function min($model, string $column, string $groupBy)
100
    {
101 4
        return $this->aggregate('min', $model, $column, $groupBy);
102
    }
103
104
    /* -----------------------------------------------------------------
105
     |  Other Methods
106
     | -----------------------------------------------------------------
107
     */
108
109
    /**
110
     * Handle the aggregate calculation of the metric.
111
     *
112
     * @param  string                                        $method
113
     * @param  \Illuminate\Database\Eloquent\Builder|string  $model
114
     * @param  string                                        $column
115
     * @param  string                                        $groupBy
116
     *
117
     * @return \Arcanedev\LaravelMetrics\Results\PartitionResult|mixed
118
     */
119 28
    protected function aggregate($method, $model, $column, $groupBy)
120
    {
121 28
        $query         = static::getQuery($model);
122 28
        $wrappedColumn = $query->getQuery()->getGrammar()->wrap(
123 28
            $column = $column ?? $query->getModel()->getQualifiedKeyName()
0 ignored issues
show
Bug introduced by
The method getQualifiedKeyName does only exist in Illuminate\Database\Eloquent\Model, but not in Illuminate\Database\Eloquent\Builder.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
124
        );
125
126 28
        $value = $query->select([$groupBy, DB::raw("{$method}({$wrappedColumn}) as aggregate")])
0 ignored issues
show
Bug introduced by
The method select() does not exist on Illuminate\Database\Eloquent\Builder. Did you maybe mean createSelectWithConstraint()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
127 28
            ->groupBy($groupBy)
128 28
            ->get()
129
            ->mapWithKeys(function ($result) use ($groupBy, $method) {
130
                return array_map(function ($value) use ($method) {
131 28
                    return $method === 'count' ? $value : round($value, 0);
132 28
                }, $this->formatAggregateResult($result, $groupBy));
133 28
            })
134 28
            ->all();
135
136 28
        return $this->result($value);
137
    }
138
139
    /**
140
     * Format the aggregate result for the partition.
141
     *
142
     * @param  \Illuminate\Database\Eloquent\Model  $result
143
     * @param  string                               $groupBy
144
     *
145
     * @return array
146
     */
147 28
    protected function formatAggregateResult($result, $groupBy): array
148
    {
149 28
        $key = $result->getAttribute(last(explode('.', $groupBy)));
150
151
        return [
152 28
            $key => $result->getAttribute('aggregate')
153
        ];
154
    }
155
156
    /**
157
     * Make a new result instance.
158
     *
159
     * @param mixed|null $value
160
     *
161
     * @return \Arcanedev\LaravelMetrics\Results\PartitionResult|mixed
162
     */
163 28
    protected function result($value = null)
164
    {
165 28
        return new PartitionResult($value);
166
    }
167
}
168