Passed
Push — master ( ea0818...92b4a6 )
by Adrian
01:28
created

Aggregate   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 85
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
wmc 18
eloc 40
c 1
b 0
f 1
dl 0
loc 85
rs 10

8 Methods

Rating   Name   Duplication   Size   Complexity  
A getQuery() 0 22 2
A attachLazyAggregateToEntity() 0 4 1
A entityMatchesRow() 0 14 5
A attachAggregateToEntity() 0 13 4
A isEagerLoad() 0 4 2
A __construct() 0 5 1
A isLazyLoad() 0 4 2
A getName() 0 3 1
1
<?php
2
declare(strict_types=1);
3
4
namespace Sirius\Orm\Relation;
5
6
use Sirius\Orm\Entity\EntityInterface;
7
use Sirius\Orm\Entity\LazyAggregate;
8
use Sirius\Orm\Entity\Tracker;
9
use Sirius\Orm\Mapper;
10
use Sirius\Orm\Query;
11
12
class Aggregate
13
{
14
    public function __construct(string $name, Relation $relation, array $options)
15
    {
16
        $this->name = $name;
0 ignored issues
show
Bug Best Practice introduced by
The property name does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
17
        $this->relation = $relation;
0 ignored issues
show
Bug Best Practice introduced by
The property relation does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
18
        $this->options = $options;
0 ignored issues
show
Bug Best Practice introduced by
The property options does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
19
    }
20
21
    public function getQuery(Tracker $tracker)
22
    {
23
        $keys = $this->relation->getKeyPairs();
24
25
        /** @var Query $query */
26
        $query = $this->relation->getQuery($tracker);
27
        $query->resetColumns();
28
        $query->columns(...array_values($keys));
29
        $query->columns(sprintf(
30
            '%s as %s',
31
            $this->options[RelationConfig::AGG_FUNCTION],
32
            $this->name
33
        ));
34
35
        $callback = $this->options[RelationConfig::AGG_CALLBACK] ?? null;
36
        if (is_callable($callback)) {
37
            $query = $callback($query);
38
        }
39
40
        $query->groupBy(...array_values($keys));
41
42
        return $query;
43
    }
44
45
    public function attachLazyAggregateToEntity(EntityInterface $entity, Tracker $tracker)
46
    {
47
        $valueLoader = new LazyAggregate($entity, $tracker, $this);
48
        $this->relation->getNativeMapper()->setEntityAttribute($entity, $this->name, $valueLoader);
49
    }
50
51
    public function attachAggregateToEntity(EntityInterface $entity, array $results)
52
    {
53
        $keys = $this->relation->getKeyPairs();
0 ignored issues
show
Unused Code introduced by
The assignment to $keys is dead and can be removed.
Loading history...
54
        $found = null;
55
        foreach ($results as $row) {
56
            if ($this->entityMatchesRow($entity, $row)) {
57
                $found = $row;
58
                break;
59
            }
60
        }
61
        $this->relation
62
            ->getNativeMapper()
63
            ->setEntityAttribute($entity, $this->name, $found ? $found[$this->name] : null);
64
    }
65
66
    public function isLazyLoad()
67
    {
68
        return !isset($this->options[RelationConfig::LOAD_STRATEGY]) ||
69
               $this->options[RelationConfig::LOAD_STRATEGY] == RelationConfig::LOAD_LAZY;
70
    }
71
72
    public function isEagerLoad()
73
    {
74
        return isset($this->options[RelationConfig::LOAD_STRATEGY]) &&
75
               $this->options[RelationConfig::LOAD_STRATEGY] == RelationConfig::LOAD_EAGER;
76
    }
77
78
    public function getName()
79
    {
80
        return $this->name;
81
    }
82
83
    private function entityMatchesRow(EntityInterface $entity, $row)
84
    {
85
        $keys = $this->relation->getKeyPairs();
86
        foreach ($keys as $nativeCol => $foreignCol) {
87
            $entityValue  = $this->relation->getNativeMapper()->getEntityAttribute($entity, $nativeCol);
88
            $rowValue = $row[$foreignCol];
89
            // if both native and foreign key values are present (not unlinked entities) they must be the same
90
            // otherwise we assume that the entities can be linked together
91
            if ($entityValue && $rowValue && $entityValue != $rowValue) {
92
                return false;
93
            }
94
        }
95
96
        return true;
97
    }
98
}
99