Completed
Push — master ( 3e728c...994056 )
by Jared
01:32
created

Polymorphic::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 5
1
<?php
2
3
/**
4
 * @author Jared King <[email protected]>
5
 *
6
 * @see http://jaredtking.com
7
 *
8
 * @copyright 2015 Jared King
9
 * @license MIT
10
 */
11
12
namespace Pulsar\Relation;
13
14
use Pulsar\Model;
15
use Pulsar\Query;
16
17
final class Polymorphic extends AbstractRelation
18
{
19
    /** @var string */
20
    private $localTypeKey;
21
22
    /** @var string */
23
    private $localIdKey;
24
25
    /** @var array */
26
    private $modelMapping;
27
28
    public function __construct(Model $localModel, string $localTypeKey, string $localIdKey, array $modelMapping, string $foreignKey)
29
    {
30
        $this->localModel = $localModel;
31
        $this->localTypeKey = $localTypeKey;
32
        $this->localIdKey = $localIdKey;
33
        $this->modelMapping = $modelMapping;
34
        $this->foreignKey = $foreignKey;
35
    }
36
37
    public function getLocalTypeKey(): string
38
    {
39
        return $this->localTypeKey;
40
    }
41
42
    public function getLocalIdKey(): string
43
    {
44
        return $this->localIdKey;
45
    }
46
47
    public function getModelMapping(): array
48
    {
49
        return $this->modelMapping;
50
    }
51
52
    /**
53
     * Returns the query instance for this relation.
54
     */
55
    public function getQuery(): Query
56
    {
57
        $foreignModel = $this->modelMapping[$this->localModel->{$this->localTypeKey}];
58
        if (null === $foreignModel) {
59
            $this->empty = true;
60
61
            return new Query();
62
        }
63
64
        $query = new Query(new $foreignModel());
65
66
        $id = $this->localModel->{$this->localIdKey};
67
68
        if (null === $id) {
69
            $this->empty = true;
70
        }
71
72
        $query->where($this->foreignKey, $id)
73
            ->limit(1);
74
75
        return $query;
76
    }
77
78
    protected function initQuery(Query $query): Query
79
    {
80
        return $query;
81
    }
82
83
    public function getResults()
84
    {
85
        $query = $this->getQuery();
86
        if ($this->empty) {
87
            return null;
88
        }
89
90
        return $query->first();
91
    }
92
93
    public function save(Model $model): Model
94
    {
95
        $model->saveOrFail();
96
        $this->attach($model);
97
98
        return $model;
99
    }
100
101
    public function create(array $values = []): Model
102
    {
103
        $class = $this->modelMapping[$this->localModel->{$this->localTypeKey}];
104
        $model = new $class();
105
        $model->create($values);
106
107
        $this->attach($model);
108
109
        return $model;
110
    }
111
112
    /**
113
     * Attaches this model to an owning model.
114
     *
115
     * @param Model $model owning model
116
     */
117
    public function attach(Model $model): void
118
    {
119
        $type = array_search(get_class($model), $this->modelMapping);
120
        $this->localIdKey->{$this->localTypeKey} = $type;
121
        $this->localModel->{$this->localIdKey} = $model->{$this->foreignKey};
122
        $this->localModel->saveOrFail();
123
    }
124
125
    /**
126
     * Detaches this model from the owning model.
127
     */
128
    public function detach(): void
129
    {
130
        $this->localModel->{$this->localTypeKey} = null;
131
        $this->localModel->{$this->localIdKey} = null;
132
        $this->localModel->saveOrFail();
133
    }
134
}
135