Completed
Push — develop ( 45ab37...1fc05f )
by Nate
16:44
created

InstanceMutator   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 163
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 24
lcom 1
cbo 3
dl 0
loc 163
ccs 0
cts 94
cp 0
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A setInstanceId() 0 5 1
A getInstanceId() 0 10 3
A setInstance() 0 13 2
A getInstance() 0 18 4
A resolveInstance() 0 12 3
A resolveInstanceFromRelation() 0 13 3
A resolveInstanceFromId() 0 8 2
A internalResolveInstance() 0 23 5
A getInstanceRecord() 0 7 1
1
<?php
2
3
/**
4
 * @copyright  Copyright (c) Flipbox Digital Limited
5
 * @license    https://flipboxfactory.com/software/patron/license
6
 * @link       https://www.flipboxfactory.com/software/patron/
7
 */
8
9
namespace flipbox\patron\records\traits;
10
11
use Craft;
12
use flipbox\ember\helpers\ObjectHelper;
13
use flipbox\patron\records\ProviderInstance;
14
use yii\db\ActiveQueryInterface;
15
16
/**
17
 * @property int|null $instanceId
18
 * @property ProviderInstance|null $instance
19
 * @property ActiveQueryInterface $instanceRecord
20
 *
21
 * @author Flipbox Factory <[email protected]>
22
 * @since 1.0.0
23
 */
24
trait InstanceMutator
25
{
26
    /**
27
     * @var ProviderInstance|null
28
     */
29
    private $instance;
30
31
    /**
32
     * Set associated instanceId
33
     *
34
     * @param $id
35
     * @return $this
36
     */
37
    public function setInstanceId(int $id)
38
    {
39
        $this->instanceId = $id;
40
        return $this;
41
    }
42
43
    /**
44
     * Get associated instanceId
45
     *
46
     * @return int|null
47
     */
48
    public function getInstanceId()
49
    {
50
        $id = $this->getAttribute('instanceId');
0 ignored issues
show
Bug introduced by
It seems like getAttribute() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
51
        if (null === $id && null !== $this->instance) {
52
            $id = $this->instance->id;
53
            $this->setAttribute('instanceId', $id);
0 ignored issues
show
Bug introduced by
It seems like setAttribute() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
54
        }
55
56
        return $id;
57
    }
58
59
    /**
60
     * Associate a instance
61
     *
62
     * @param mixed $instance
63
     * @return $this
64
     */
65
    public function setInstance($instance = null)
66
    {
67
        $this->instance = null;
68
69
        if (null === ($instance = $this->internalResolveInstance($instance))) {
70
            $this->instance = $this->instanceId = null;
71
        } else {
72
            $this->instanceId = $instance->id;
73
            $this->instance = $instance;
0 ignored issues
show
Documentation Bug introduced by
It seems like $instance of type object<yii\db\ActiveRecordInterface> or array is incompatible with the declared type object<flipbox\patron\re...\ProviderInstance>|null of property $instance.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
74
        }
75
76
        return $this;
77
    }
78
79
    /**
80
     * @return ProviderInstance|null
81
     */
82
    public function getInstance()
83
    {
84
        if ($this->instance === null) {
85
            $instance = $this->resolveInstance();
86
            $this->setInstance($instance);
87
            return $instance;
88
        }
89
90
        $instanceId = $this->instanceId;
91
        if ($instanceId !== null &&
92
            $instanceId !== $this->instance->id
93
        ) {
94
            $this->instance = null;
95
            return $this->getInstance();
96
        }
97
98
        return $this->instance;
99
    }
100
101
    /**
102
     * @return ProviderInstance|null
103
     */
104
    protected function resolveInstance()
105
    {
106
        if (null !== ($model = $this->resolveInstanceFromRelation())) {
107
            return $model;
108
        }
109
110
        if (null !== ($model = $this->resolveInstanceFromId())) {
111
            return $model;
112
        }
113
114
        return null;
115
    }
116
117
    /**
118
     * @return ProviderInstance|null
119
     */
120
    private function resolveInstanceFromRelation()
121
    {
122
        if (false === $this->isRelationPopulated('instanceRecord')) {
0 ignored issues
show
Bug introduced by
It seems like isRelationPopulated() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
123
            return null;
124
        }
125
126
        /** @var ProviderInstance $record */
127
        if (null === ($record = $this->getRelation('instanceRecord'))) {
0 ignored issues
show
Bug introduced by
It seems like getRelation() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
128
            return null;
129
        }
130
131
        return $record;
132
    }
133
134
    /**
135
     * @return ProviderInstance|null
136
     */
137
    private function resolveInstanceFromId()
138
    {
139
        if (null === $this->instanceId) {
140
            return null;
141
        }
142
143
        return ProviderInstance::findOne($this->instanceId);
144
    }
145
146
    /**
147
     * @param $instance
148
     * @return ProviderInstance|null
149
     */
150
    protected function internalResolveInstance($instance = null)
151
    {
152
        if ($instance instanceof ProviderInstance) {
153
            return $instance;
154
        }
155
156
        if (is_numeric($instance) || is_string($instance)) {
157
            return ProviderInstance::findOne($instance);
158
        }
159
160
        try {
161
            $object = Craft::createObject(ProviderInstance::class, [$instance]);
162
        } catch (\Exception $e) {
163
            $object = new ProviderInstance();
164
            ObjectHelper::populate(
165
                $object,
166
                $instance
167
            );
168
        }
169
170
        /** @var ProviderInstance $object */
171
        return $object;
172
    }
173
174
    /**
175
     * Returns the associated instance record.
176
     *
177
     * @return ActiveQueryInterface
178
     */
179
    protected function getInstanceRecord(): ActiveQueryInterface
180
    {
181
        return $this->hasOne(
0 ignored issues
show
Bug introduced by
It seems like hasOne() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
182
            ProviderInstance::class,
183
            ['id' => 'instanceId']
184
        );
185
    }
186
}
187