Completed
Push — master ( 9c7e8e...65e25f )
by Valentin
15s
created

SingularRelation::isPlaceholderNeeded()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
/**
3
 * Spiral, Core Components
4
 *
5
 * @author Wolfy-J
6
 */
7
8
namespace Spiral\ORM\Entities\Relations;
9
10
use Spiral\Database\Exceptions\QueryException;
11
use Spiral\ORM\Entities\Relations\Traits\SyncedTrait;
12
use Spiral\ORM\Exceptions\SelectorException;
13
use Spiral\ORM\Helpers\AliasDecorator;
14
use Spiral\ORM\ORMInterface;
15
use Spiral\ORM\Record;
16
use Spiral\ORM\RecordInterface;
17
18
/**
19
 * Provides ability to create cached instances of related data.
20
 */
21
abstract class SingularRelation extends AbstractRelation
22
{
23
    use SyncedTrait;
24
25
    /**
26
     * Create placeholder model when relation is empty.
27
     */
28
    const CREATE_PLACEHOLDER = false;
29
30
    /**
31
     * @var RecordInterface
32
     */
33
    protected $instance;
34
35
    /**
36
     * {@inheritdoc}
37
     */
38
    public function hasRelated(): bool
39
    {
40
        if (!$this->isLoaded()) {
41
            //Lazy loading our relation data
42
            $this->loadData();
43
        }
44
45
        return !empty($this->instance);
46
    }
47
48
    /**
49
     * {@inheritdoc}
50
     *
51
     * Returns associated parent or NULL if none associated.
52
     */
53
    public function getRelated()
54
    {
55
        if ($this->instance instanceof RecordInterface) {
56
            return $this->instance;
57
        }
58
59
        if (!$this->isLoaded()) {
60
            //Lazy loading our relation data
61
            $this->loadData();
62
        }
63
64
        if (!empty($this->instance)) {
65
            return $this->instance;
66
        }
67
68
        if (!empty($this->data)) {
69
            $this->instance = $this->orm->make(
70
                $this->getClass(),
71
                $this->data,
72
                ORMInterface::STATE_LOADED,
73
                true
74
            );
75
        } elseif ($this->isPlaceholderNeeded()) {
76
            //Stub instance
77
            $this->instance = $this->orm->make(
78
                $this->getClass(),
79
                [],
80
                ORMInterface::STATE_NEW
81
            );
82
        }
83
84
        return $this->instance;
85
    }
86
87
    /**
88
     * {@inheritdoc}
89
     *
90
     * @throws SelectorException
91
     * @throws QueryException
92
     */
93
    protected function loadData()
94
    {
95
        $this->loaded = true;
96
97
        $innerKey = $this->key(Record::INNER_KEY);
98
        if (empty($this->parent->getField($innerKey))) {
99
            //Unable to load
100
            return;
101
        }
102
103
        $selector = $this->orm->selector($this->getClass());
104
        $decorator = new AliasDecorator($selector, 'where', $selector->getAlias());
105
        $decorator->where($this->whereStatement());
106
107
        $this->data = $selector->fetchData();
108
109
        if (!empty($this->data[0])) {
110
            //Use first result
111
            $this->data = $this->data[0];
112
        }
113
    }
114
115
    /**
116
     * Where statement to load outer record.
117
     *
118
     * @return array
119
     */
120
    protected function whereStatement(): array
121
    {
122
        return [
123
            $this->key(Record::OUTER_KEY) => $this->parent->getField($this->key(Record::INNER_KEY))
124
        ];
125
    }
126
127
    /**
128
     * @return bool
129
     */
130
    protected function isPlaceholderNeeded(): bool
131
    {
132
        return static::CREATE_PLACEHOLDER;
133
    }
134
}