Passed
Push — master ( f2dea1...58a092 )
by Nate
04:47
created

ObjectById::findById()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 28
Code Lines 9

Duplication

Lines 28
Ratio 100 %

Importance

Changes 0
Metric Value
dl 28
loc 28
rs 8.8571
c 0
b 0
f 0
nc 3
cc 3
eloc 9
nop 2
1
<?php
2
3
/**
4
 * @copyright  Copyright (c) Flipbox Digital Limited
5
 * @license    https://github.com/flipbox/spark/blob/master/LICENSE
6
 * @link       https://github.com/flipbox/spark
7
 */
8
9
namespace flipbox\spark\services\traits;
10
11
use flipbox\spark\exceptions\ObjectNotFoundException;
12
use flipbox\spark\objects\ObjectWithId;
13
use flipbox\spark\records\RecordWithId;
14
use yii\base\Object as BaseObject;
15
16
/**
17
 * @author Flipbox Factory <[email protected]>
18
 * @since 1.2.0
19
 *
20
 * @method RecordWithId|null findRecordByCondition($condition, string $toScenario = null)
21
 */
22
trait ObjectById
23
{
24
25
    use Object;
26
27
    /**
28
     * @var BaseObject[]
29
     */
30
    protected $_cacheById = [];
31
32
    /*******************************************
33
     * FIND/GET BY ID
34
     *******************************************/
35
36
    /**
37
     * @param int $id
38
     * @param string|null $toScenario
39
     * @return BaseObject|null
40
     */
41 View Code Duplication
    public function findById(int $id, string $toScenario = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
42
    {
43
44
        // Check cache
45
        if (!$object = $this->findCacheById($id)) {
46
47
            // Find record in db
48
            if ($record = $this->findRecordByCondition(
49
                ['id' => $id]
50
            )
51
            ) {
52
53
                // Perhaps in cache
54
                $object = $this->findByRecord($record, $toScenario);
0 ignored issues
show
Bug introduced by
It seems like findByRecord() 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...
55
56
            } else {
57
58
                $this->_cacheById[$id] = null;
59
60
                return null;
61
62
            }
63
64
        }
65
66
        return $object;
67
68
    }
69
70
    /**
71
     * @param int $id
72
     * @param string|null $toScenario
73
     * @return BaseObject
74
     * @throws ObjectNotFoundException
75
     */
76 View Code Duplication
    public function getById(int $id, string $toScenario = null): BaseObject
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
77
    {
78
79
        // Find by ID
80
        if (!$object = $this->findById($id, $toScenario)) {
81
82
            $this->notFoundByIdException($id);
83
84
        }
85
86
        return $object;
87
88
    }
89
90
    /**
91
     * @param int $id
92
     * @param string|null $toScenario
93
     * @return BaseObject|null
94
     */
95
    public function freshFindById(int $id, string $toScenario = null)
96
    {
97
98
        // Find record in db
99
        if ($record = $this->findRecordByCondition(
100
            ['id' => $id]
101
        )
102
        ) {
103
104
            // Create
105
            return $this->createFromRecord($record, $toScenario);
0 ignored issues
show
Bug introduced by
It seems like createFromRecord() 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...
106
107
        }
108
109
        return null;
110
111
    }
112
113
    /**
114
     * @param int $id
115
     * @param string|null $toScenario
116
     * @return BaseObject
117
     * @throws ObjectNotFoundException
118
     */
119 View Code Duplication
    public function freshGetById(int $id, string $toScenario = null): BaseObject
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
120
    {
121
122
        if (!$object = $this->freshFindById($id, $toScenario)) {
123
124
            $this->notFoundByIdException($id);
125
126
        }
127
128
        return $object;
129
130
    }
131
132
    /**
133
     * Find an existing cache by ID
134
     *
135
     * @param $id
136
     * @return BaseObject|null
137
     */
138
    public function findCacheById(int $id)
139
    {
140
141
        // Check if already in addToCache
142
        if ($this->isCachedById($id)) {
143
144
            return $this->_cacheById[$id];
145
146
        }
147
148
        return null;
149
150
    }
151
152
    /**
153
     * Identify whether in cache by ID
154
     *
155
     * @param $id
156
     * @return bool
157
     */
158
    protected function isCachedById(int $id)
159
    {
160
        return array_key_exists($id, $this->_cacheById);
161
    }
162
163
    /**
164
     * @param ObjectWithId $object
165
     * @return $this
166
     */
167
    protected function cacheById(ObjectWithId $object)
168
    {
169
170
        // Check if already in cache
171
        if (!$id = $this->isCachedById($object->id)) {
172
173
            // Cache it
174
            $this->_cacheById[$id] = $object;
175
176
        }
177
178
        return $this;
179
180
    }
181
182
    /*******************************************
183
     * EXCEPTIONS
184
     *******************************************/
185
186
    /**
187
     * @param int|null $id
188
     * @throws ObjectNotFoundException
189
     */
190
    protected function notFoundByIdException(int $id = null)
191
    {
192
193
        throw new ObjectNotFoundException(
194
            sprintf(
195
                'Object does not exist with the id "%s".',
196
                (string)$id
197
            )
198
        );
199
200
    }
201
202
}