Issues (6)

src/ComputedProperties.php (6 issues)

1
<?php
2
3
namespace N7olkachev\ComputedProperties;
4
5
use Illuminate\Database\Eloquent\Builder;
6
use Illuminate\Database\Query\Builder as QueryBuilder;
7
8
trait ComputedProperties
9
{
10
    public static function bootComputedProperties()
11
    {
12
        Builder::macro('withComputed', function ($properties) {
13
            collect($properties)->each(function ($property) {
14
                if (!$this->model->hasComputedProperty($property)) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $this seems to be never defined.
Loading history...
Bug Best Practice introduced by
The property model does not exist on N7olkachev\ComputedProperties\ComputedProperties. Since you implemented __get, consider adding a @property annotation.
Loading history...
15
                    throw new \InvalidArgumentException("Computed property [$property] does not exist");
16
                }
17
18
                $query = $this->model->callComputedProperty($property, true);
19
20
                if (is_null($this->query->columns)) {
0 ignored issues
show
Bug Best Practice introduced by
The property query does not exist on N7olkachev\ComputedProperties\ComputedProperties. Since you implemented __get, consider adding a @property annotation.
Loading history...
21
                    $this->query->select([$this->query->from.'.*']);
22
                }
23
24
                $this->selectSub($query, $property);
0 ignored issues
show
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

24
                $this->/** @scrutinizer ignore-call */ 
25
                       selectSub($query, $property);
Loading history...
25
            });
26
27
            return $this;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $this seems to be never defined.
Loading history...
28
        });
29
    }
30
31
    public function __get($key)
32
    {
33
        if (!array_key_exists($key, $this->attributes) && $this->hasComputedProperty($key)) {
34
            $query = $this->callComputedProperty($key, false);
35
            $result = (array) $query->first();
36
            $this->attributes[$key] = array_first($result);
0 ignored issues
show
Bug Best Practice introduced by
The property attributes does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
37
        }
38
39
        return parent::__get($key);
40
    }
41
42
    public function hasComputedProperty($property)
43
    {
44
        return method_exists($this, $this->computedPropertyMethodName($property));
45
    }
46
47
    public function computedPropertyMethodName($property)
48
    {
49
        return 'computed' . ucfirst(camel_case($property));
50
    }
51
52
    public function callComputedProperty($property, $runningInQuery)
53
    {
54
        $method = $this->computedPropertyMethodName($property);
55
        $query = $this->$method(new ModelProxy($this, $runningInQuery));
56
57
        if ($query instanceof Builder) {
58
            $query = $query->toBase();
59
        }
60
61
        if (!$query instanceof QueryBuilder) {
62
            throw new \UnexpectedValueException("Computed property must return EloquentBuilder or QueryBuilder instance");
63
        }
64
65
        return $query;
66
    }
67
}