Completed
Branch feature/pre-split (c41c6b)
by Anton
03:19
created

SingularRelation::whereStatement()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

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