Partition::result()   A
last analyzed

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 1
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Arcanedev\LaravelMetrics\Metrics;
6
7
use Arcanedev\LaravelMetrics\Metrics\Concerns\HasRoundedValue;
8
use Arcanedev\LaravelMetrics\Results\PartitionResult;
9
use Illuminate\Support\Facades\DB;
10
11
/**
12
 * Class     Partition
13
 *
14
 * @author   ARCANEDEV <[email protected]>
15
 */
16
abstract class Partition extends Metric
17
{
18
    /* -----------------------------------------------------------------
19
     |  Traits
20
     | -----------------------------------------------------------------
21
     */
22
23
    use HasRoundedValue;
24
25
    /* -----------------------------------------------------------------
26
     |  Getters
27
     | -----------------------------------------------------------------
28
     */
29
30
    /**
31
     * Get the metric type.
32
     *
33
     * @return string
34
     */
35 28
    public function type(): string
36
    {
37 28
        return 'partition';
38
    }
39
40
    /* -----------------------------------------------------------------
41
     |  Main Methods
42
     | -----------------------------------------------------------------
43
     */
44
45
    /**
46
     * Calculate the `count` of the metric.
47
     *
48
     * @param  \Illuminate\Database\Eloquent\Builder|string  $model
49
     * @param  string                                        $groupBy
50
     * @param  string|null                                   $column
51
     *
52
     * @return \Arcanedev\LaravelMetrics\Results\PartitionResult|mixed
53
     */
54 12
    public function count($model, string $groupBy, $column = null)
55
    {
56 12
        return $this->aggregate('count', $model, $column, $groupBy);
57
    }
58
59
    /**
60
     * Calculate the `average` of the metric.
61
     *
62
     * @param  \Illuminate\Database\Eloquent\Builder|string  $model
63
     * @param  string                                        $column
64
     * @param  string                                        $groupBy
65
     *
66
     * @return \Arcanedev\LaravelMetrics\Results\PartitionResult|mixed
67
     */
68 4
    public function average($model, string $column, string $groupBy)
69
    {
70 4
        return $this->aggregate('avg', $model, $column, $groupBy);
71
    }
72
73
    /**
74
     * Calculate the `sum` of the metric.
75
     *
76
     * @param  \Illuminate\Database\Eloquent\Builder|string  $model
77
     * @param  string                                        $column
78
     * @param  string                                        $groupBy
79
     *
80
     * @return \Arcanedev\LaravelMetrics\Results\PartitionResult|mixed
81
     */
82 4
    public function sum($model, string $column, string $groupBy)
83
    {
84 4
        return $this->aggregate('sum', $model, $column, $groupBy);
85
    }
86
87
    /**
88
     * Calculate the `max` of the metric.
89
     *
90
     * @param  \Illuminate\Database\Eloquent\Builder|string  $model
91
     * @param  string                                        $column
92
     * @param  string                                        $groupBy
93
     *
94
     * @return \Arcanedev\LaravelMetrics\Results\PartitionResult|mixed
95
     */
96 4
    public function max($model, string $column, string $groupBy)
97
    {
98 4
        return $this->aggregate('max', $model, $column, $groupBy);
99
    }
100
101
    /**
102
     * Calculate the `min` of the metric.
103
     *
104
     * @param  \Illuminate\Database\Eloquent\Builder|string  $model
105
     * @param  string                                        $column
106
     * @param  string                                        $groupBy
107
     *
108
     * @return \Arcanedev\LaravelMetrics\Results\PartitionResult|mixed
109
     */
110 4
    public function min($model, string $column, string $groupBy)
111
    {
112 4
        return $this->aggregate('min', $model, $column, $groupBy);
113
    }
114
115
    /* -----------------------------------------------------------------
116
     |  Other Methods
117
     | -----------------------------------------------------------------
118
     */
119
120
    /**
121
     * Handle the aggregate calculation of the metric.
122
     *
123
     * @param  string                                        $method
124
     * @param  \Illuminate\Database\Eloquent\Builder|string  $model
125
     * @param  string                                        $column
126
     * @param  string                                        $groupBy
127
     *
128
     * @return \Arcanedev\LaravelMetrics\Results\PartitionResult|mixed
129
     */
130 28
    protected function aggregate($method, $model, $column, $groupBy)
131
    {
132 28
        $query         = static::getQuery($model);
133 28
        $wrappedColumn = $query->getQuery()->getGrammar()->wrap(
134 28
            $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...
135
        );
136
137 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...
138 28
            ->groupBy($groupBy)
139 28
            ->get()
140 28
            ->mapWithKeys(function ($result) use ($groupBy, $method) {
141 28
                return array_map(function ($value) use ($method) {
142 28
                    return $method === 'count' ? $value : $this->roundValue($value);
143 28
                }, $this->formatAggregateResult($result, $groupBy));
144 28
            })
145 28
            ->all();
146
147 28
        return $this->result($value);
148
    }
149
150
    /**
151
     * Format the aggregate result for the partition.
152
     *
153
     * @param  \Illuminate\Database\Eloquent\Model  $result
154
     * @param  string                               $groupBy
155
     *
156
     * @return array
157
     */
158 28
    protected function formatAggregateResult($result, $groupBy): array
159
    {
160 28
        $key = $result->getAttribute(last(explode('.', $groupBy)));
161
162
        return [
163 28
            $key => $result->getAttribute('aggregate'),
164
        ];
165
    }
166
167
    /**
168
     * Make a new result instance.
169
     *
170
     * @param  mixed|null  $value
171
     *
172
     * @return \Arcanedev\LaravelMetrics\Results\PartitionResult|mixed
173
     */
174 28
    protected function result($value = null)
175
    {
176 28
        return new PartitionResult($value);
177
    }
178
}
179