Completed
Push — master ( af8e35...1bb9ae )
by James Ekow Abaka
03:11
created

RecordWrapper::offsetSet()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 5
Bugs 1 Features 1
Metric Value
c 5
b 1
f 1
dl 0
loc 5
ccs 4
cts 4
cp 1
rs 9.4285
cc 1
eloc 3
nc 1
nop 2
crap 1
1
<?php
2
/*
3
 * The MIT License
4
 *
5
 * Copyright 2015 ekow.
6
 *
7
 * Permission is hereby granted, free of charge, to any person obtaining a copy
8
 * of this software and associated documentation files (the "Software"), to deal
9
 * in the Software without restriction, including without limitation the rights
10
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
 * copies of the Software, and to permit persons to whom the Software is
12
 * furnished to do so, subject to the following conditions:
13
 *
14
 * The above copyright notice and this permission notice shall be included in
15
 * all copies or substantial portions of the Software.
16
 *
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
 * THE SOFTWARE.
24
 */
25
26
namespace ntentan\nibii;
27
28
use ntentan\utils\Utils;
29
use ntentan\kaikai\Cache;
30
use ntentan\panie\InjectionContainer;
31
32
class RecordWrapper implements \ArrayAccess, \Countable, \Iterator
33
{
34
    use \ntentan\panie\ComponentContainerTrait;
35
    
36
    protected $hasMany = [];
37
    protected $belongsTo = [];
38
    protected $manyHaveMany = [];
39
    protected $behaviours = [];
40
    protected $table;
41
    private $modelData = [];
42
    private $invalidFields;
43
    private $dynamicOperations;
44
    private $index = 0;
45
    private $dataSet = false;
46
    protected $adapter;
47
48 36
    public function __construct(DriverAdapter $adapter)
49
    {
50 36
        $this->table = Nibii::getModelTable($this);
51 36
        $this->adapter = $adapter;
52 36
        foreach($this->behaviours as $behaviour) {
53
            $behaviourInstance = $this->getComponentInstance($behaviour);
54
            $behaviourInstance->setModel($this);
55
        }
56 36
    }
57
58
    /**
59
     * 
60
     * @return ModelDescription
61
     */
62 28
    public function getDescription()
63
    {
64 28
        return Cache::read(
65 28
            (new \ReflectionClass($this))->getName() . '::desc',
66 28
            function() 
67
            {
68 28
                return new ModelDescription($this);
69 28
            }
70
        );
71
    }
72
    
73 10
    public function count()
74
    {
75 10
        if ($this->dataSet) {
76 10
            return count($this->getData());
77
        } else {
78
            return $this->__call('count', []);
0 ignored issues
show
Documentation introduced by
'count' is of type string, but the function expects a object<ntentan\nibii\type>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Documentation introduced by
array() is of type array, but the function expects a object<ntentan\nibii\type>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
79
        }
80
    }
81
82 12
    private function retrieveItem($key)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
83
    {
84 12
        $relationships = $this->getDescription()->getRelationships();
85 12
        if(isset($relationships[$key])) {
86 8
            return $this->fetchRelatedFields($relationships[$key]);
87
        } else {
88 4
            return isset($this->modelData[$key]) ? $this->modelData[$key] : null;
89
        }
90
    }
91
92
    /**
93
     * Create a new instance of this Model
94
     * @return \ntentan\nibii\RecordWrapper
95
     */
96 34
    public static function createNew()
97
    {
98 34
        $class = get_called_class();
99 34
        return InjectionContainer::resolve($class);
100
    }
101
102
    /**
103
     * @method
104
     * @param type $name
105
     * @param type $arguments
106
     * @return type
107
     */
108 34
    public function __call($name, $arguments)
109
    {
110 34
        if($this->dynamicOperations === null) {
111 34
            $this->dynamicOperations = new Operations(
112 34
                $this, InjectionContainer::singleton(DriverAdapter::class)
113
            );
114
        }
115 34
        return $this->dynamicOperations->perform($name, $arguments);
116
    }
117
118 26
    public static function __callStatic($name, $arguments)
119
    {
120 26
        return call_user_func_array([self::createNew(), $name], $arguments);
121
    }
122
123 8
    public function __set($name, $value)
124
    {
125 8
        $this->dataSet = true;
126 8
        $this->modelData[$name] = $value;
127 8
    }
128
129 12
    public function __get($name)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
130
    {
131 12
        return $this->retrieveItem($name);
132
    }
133
134 36
    public function getTable()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
135
    {
136 36
        return $this->table;
137
    }
138
    
139 4
    private function expandArrayValue($array, $relationships, $depth, $index = null)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
140
    {
141 4
        foreach($relationships as $name => $relationship) {
142 4
            $array[$name] = $this->fetchRelatedFields($relationship, $index)->toArray($depth);
143
        }
144 4
        return $array;
145
    }
146
147 16
    public function toArray($depth = 0)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
148
    {
149 16
        $relationships = $this->getDescription()->getRelationships();
150 16
        $array = $this->modelData;
151 16
        if($depth > 0) {
152 4
            if($this->hasMultipleData()) {
153
                foreach($array as $i => $value) {
154
                    $array[$i] = $this->expandArrayValue($value, $relationships, $depth - 1, $i);
155
                }
156
            } else {
157 4
                $array = $this->expandArrayValue($array, $relationships, $depth - 1);
158
            }
159
        }
160 16
        return $array;
161
    }
162
    
163 10
    public function save()
164
    {
165 10
        $return = $this->__call('save', [$this->hasMultipleData()]);
0 ignored issues
show
Documentation introduced by
'save' is of type string, but the function expects a object<ntentan\nibii\type>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Documentation introduced by
array($this->hasMultipleData()) is of type array<integer,boolean,{"0":"boolean"}>, but the function expects a object<ntentan\nibii\type>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
166 10
        $this->invalidFields = $this->dynamicOperations->getInvalidFields();
167 10
        return $return;
168
    }
169
170 18
    private function hasMultipleData()
171
    {
172 18
        if(count($this->modelData) > 0) {
173 16
            return is_numeric(array_keys($this->modelData)[0]);
174
        } else {
175 2
            return false;
176
        }
177
    }
178
179 14
    public function getData()
180
    {
181 14
        $data = [];
182
                
183 14
        if(count($this->modelData) == 0) {
184 6
            $data = $this->modelData;
185 12
        } else if($this->hasMultipleData()) {
186 2
            $data = $this->modelData;
187 12
        } else if(count($this->modelData) > 0) {
188 12
            $data[] = $this->modelData;
189
        }
190
        
191 14
        return $data;
192
    }
193
194 26
    public function setData($data)
195
    {
196 26
        $this->dataSet = true;
197 26
        $this->modelData = $data;
198 26
    }
199
    
200
    public function mergeData($data)
201
    {
202
        foreach($data as $key => $value) {
203
            $this->modelData[$key] = $value;
204
        }
205
        $this->dataSet = true;
206
    }
207
208 2
    public function offsetExists($offset)
209
    {
210 2
        return isset($this->modelData[$offset]);
211
    }
212
213 2
    public function offsetGet($offset)
214
    {
215 2
        if (is_numeric($offset)) {
216 2
            return $this->wrap($offset);
217
        } else {
218 2
            return $this->retrieveItem($offset);
219
        }
220
    }
221
222 2
    public function offsetSet($offset, $value)
223
    {
224 2
        $this->dataSet = true;
225 2
        $this->modelData[$offset] = $value;
226 2
    }
227
228
    public function offsetUnset($offset)
229
    {
230
        unset($this->modelData[$offset]);
231
    }
232
233 6
    private function wrap($offset)
234
    {
235 6
        if(isset($this->modelData[$offset])) {
236 6
            $newInstance = $this->createNew();
237 6
            $newInstance->setData($this->modelData[$offset]);
238 6
            return $newInstance;
239
        } else {
240
            return null;
241
        }
242
    }
243
244 4
    public function getInvalidFields()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
245
    {
246 4
        return $this->invalidFields;
247
    }
248
249
    public function getHasMany()
250
    {
251
        return $this->hasMany;
252
    }
253
254
    public function getBelongsTo()
255
    {
256
        return $this->belongsTo;
257
    }
258
259 4
    public function current()
260
    {
261 4
        return $this->wrap($this->index);
262
    }
263
264
    public function key()
265
    {
266
        return $this->index;
267
    }
268
269 4
    public function next()
270
    {
271 4
        $this->index++;
272 4
    }
273
274 4
    public function rewind()
275
    {
276 4
        $this->index = 0;
277 4
    }
278
279 4
    public function valid()
280
    {
281 4
        return isset($this->modelData[$this->index]);
282
    }
283
    
284 6
    public function onValidate()
285
    {
286 6
        return true;
287
    }
288
289 12
    private function fetchRelatedFields($relationship, $index = null)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
290
    {
291 12
        if($index === null) {
292 12
            $data = $this->modelData;
293
        } else {
294
            $data = $this->modelData[$index];
295
        }
296 12
        $model = $relationship->getModelInstance();
297 12
        if(empty($data)) {
298
            return $model;
299
        } else {
300 12
            return $model->fetch($relationship->getQuery($data));
301
        }
302
    }
303
304 28
    public function getRelationships()
305
    {
306
        return [
307 28
            'HasMany' => $this->hasMany,
308 28
            'BelongsTo' => $this->belongsTo,
309 28
            'ManyHaveMany' => $this->manyHaveMany
310
        ];
311
    }
312
    
313
    public function usetField($field)
314
    {
315
        unset($this->modelData[$field]);
316
    }
317
    
318 8
    public function preSaveCallback()
319
    {
320
        
321 8
    }
322
    
323 4
    public function postSaveCallback($id)
0 ignored issues
show
Unused Code introduced by
The parameter $id is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
324
    {
325
        
326 4
    }
327
    
328 2
    public function preUpdateCallback()
329
    {
330
        
331 2
    }
332
    
333 2
    public function postUpdateCallback()
334
    {
335
        
336 2
    }
337
    
338 10
    public function getBehaviours()
339
    {
340 10
        return $this->loadedComponents;
341
    }
342
}
343