Completed
Branch feature/pre-split (4c50c1)
by Anton
03:17
created

HasManyLoader::configureQuery()   B

Complexity

Conditions 6
Paths 8

Size

Total Lines 37
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 20
nc 8
nop 2
dl 0
loc 37
rs 8.439
c 0
b 0
f 0
1
<?php
2
/**
3
 * components
4
 *
5
 * @author    Wolfy-J
6
 */
7
namespace Spiral\ORM\Entities\Loaders;
8
9
use Spiral\Database\Builders\SelectQuery;
10
use Spiral\Database\Injections\Parameter;
11
use Spiral\ORM\Entities\Nodes\AbstractNode;
12
use Spiral\ORM\Entities\Nodes\ArrayNode;
13
use Spiral\ORM\Helpers\WhereDecorator;
14
use Spiral\ORM\Record;
15
16
/**
17
 * Dedicated to load HAS_MANY relation data, POSTLOAD is preferred loading method. Additional where
18
 * conditions and morph keys are supported.
19
 *
20
 * Please note that OUTER and INNER keys defined from perspective of parent (reversed for our
21
 * purposes).
22
 */
23
class HasManyLoader extends RelationLoader
24
{
25
    /**
26
     * Default set of relation options. Child implementation might defined their of default options.
27
     *
28
     * @var array
29
     */
30
    protected $options = [
31
        'method' => self::POSTLOAD,
32
        'minify' => true,
33
        'alias'  => null,
34
        'using'  => null,
35
        'where'  => null,
36
    ];
37
38
    /**
39
     * {@inheritdoc}
40
     */
41
    protected function configureQuery(SelectQuery $query, array $references = []): SelectQuery
42
    {
43
        if ($this->isJoined()) {
44
            $query->join(
45
                $this->getMethod() == self::JOIN ? 'INNER' : 'LEFT',
46
                "{$this->getTable()} AS {$this->getAlias()}",
47
                [$this->localKey(Record::OUTER_KEY) => $this->parentKey(Record::INNER_KEY)]
48
            );
49
        } else {
50
            //This relation is loaded using external query
51
            $query->where(
52
                $this->localKey(Record::OUTER_KEY),
53
                'IN',
54
                new Parameter($references)
55
            );
56
        }
57
58
        //Let's use where decorator to set conditions, it will automatically route tokens to valid
59
        //destination (JOIN or WHERE)
60
        $decorator = new WhereDecorator(
61
            $query,
62
            $this->isJoined() ? 'onWhere' : 'where',
63
            $this->getAlias()
64
        );
65
66
        if (!empty($this->schema[Record::WHERE])) {
67
            //Relation WHERE conditions
68
            $decorator->where($this->schema[Record::WHERE]);
69
        }
70
71
        //User specified WHERE conditions
72
        if (!empty($this->options['where'])) {
73
            $decorator->where($this->options['where']);
74
        }
75
76
        return parent::configureQuery($query);
77
    }
78
79
    /**
80
     * {@inheritdoc}
81
     */
82
    protected function initNode(): AbstractNode
83
    {
84
        $node = new ArrayNode(
85
            $this->schema[Record::RELATION_COLUMNS],
86
            $this->schema[Record::OUTER_KEY],
87
            $this->schema[Record::INNER_KEY],
88
            $this->schema[Record::SH_PRIMARIES]
89
        );
90
91
        return $node->asJoined($this->isJoined());
92
    }
93
}