Completed
Branch feature/pre-split (4ff102)
by Anton
03:27
created

SingularRelation::loadData()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 11
nc 3
nop 0
dl 0
loc 20
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * components
4
 *
5
 * @author    Wolfy-J
6
 */
7
namespace Spiral\ORM\Entities\Relations;
8
9
use Spiral\Database\Exceptions\QueryException;
10
use Spiral\ORM\Exceptions\RelationException;
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
     * Returns associated parent or NULL if none associated.
35
     */
36
    public function getRelated()
37
    {
38
        if ($this->instance instanceof RecordInterface) {
39
            return $this->instance;
40
        }
41
42
        if (!$this->isLoaded()) {
43
            //Lazy loading our relation data
44
            $this->loadData();
45
        }
46
47
        if (empty($this->data)) {
48
            if (static::CREATE_PLACEHOLDER) {
49
                //Stub instance
50
                return $this->instance = $this->orm->make(
51
                    $this->class,
52
                    [],
53
                    ORMInterface::STATE_NEW
54
                );
55
            }
56
57
            return null;
58
        }
59
60
        //Create instance based on loaded data
61
        return $this->instance = $this->orm->make(
62
            $this->class,
63
            $this->data,
64
            ORMInterface::STATE_LOADED,
65
            true
66
        );
67
    }
68
69
    /**
70
     * Must load related data using appropriate method.
71
     */
72
    /**
73
     * {@inheritdoc}
74
     *
75
     * @throws SelectorException
76
     * @throws QueryException
77
     */
78
    protected function loadData()
79
    {
80
        $this->loaded = true;
81
82
        $innerKey = $this->schema[Record::INNER_KEY];
83
        if (empty($this->parent->getField($innerKey))) {
84
            //Unable to load
85
            return;
86
        }
87
88
        $this->data = $this->orm->selector($this->class)->where(
89
            $this->schema[Record::OUTER_KEY],
90
            $this->parent->getField($innerKey)
0 ignored issues
show
Unused Code introduced by
The call to RecordSelector::where() has too many arguments starting with $this->parent->getField($innerKey).

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
91
        )->fetchData();
92
93
        if (!empty($this->data[0])) {
94
            //Use first result
95
            $this->data = $this->data[0];
96
        }
97
    }
98
99
    /**
100
     * @param $value
101
     */
102
    protected function assertValid($value)
103
    {
104
        if (is_null($value)) {
105
            if (!$this->schema[Record::NULLABLE]) {
106
                throw new RelationException("Relation is not nullable");
107
            }
108
        } elseif (!is_a($value, $this->class, false)) {
109
            throw new RelationException(
110
                "Must be an instance of '{$this->class}', '" . get_class($value) . "' given"
111
            );
112
        }
113
    }
114
}