Completed
Push — master ( 6bb3cd...396d48 )
by James Ekow Abaka
03:46
created

RecordWrapper::isValid()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 0
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
31
class RecordWrapper implements \ArrayAccess, \Countable, \Iterator
32
{
33
    use \ntentan\utils\DependencyInjector;
34
    
35
    protected $hasMany = [];
36
    protected $belongsTo = [];
37
    protected $manyHaveMany = [];
38
    protected $behaviours = [];
39
    protected $table;
40
    private $modelData = [];
41
    private $invalidFields;
42
    private $dynamicOperations;
43
    private $index = 0;
44
    private $dataSet = false;
45
    private $adapter;
46
47
    public function __construct()
48 36
    {
49
        Utils::factory(
50 36
            $this->table,
51 36
            function() {
52
                return Nibii::getModelTable($this);
53 36
            }
54
        );
55 36
        foreach($this->behaviours as $behaviour) {
56 36
            $behaviourInstance = $this->loadDependency($behaviour);
57
            $behaviourInstance->setModel($this);
58
        }
59 36
    }
60 36
61
    /**
62
     *
63
     * @return \ntentan\nibii\DriverAdapter
64
     */
65
    protected function getDataAdapter()
66 34
    {
67
        if(!$this->adapter)
68 34
        {
69 34
            $this->adapter = DriverAdapter::getDefaultInstance();
70 34
        }
71 34
        return $this->adapter;
72 34
    }
73
74
    /**
75
     * 
76
     * @return ModelDescription
77
     */
78
    public function getDescription()
79 28
    {
80
        return Cache::read(
81 28
            (new \ReflectionClass($this))->getName() . '::desc',
82 28
            function() 
83
            {
84
                return new ModelDescription($this);
85 8
            }
86
        );
87 28
    }
88
    
89
    public function count()
90 10
    {
91
        if ($this->dataSet) {
92 10
            return count($this->getData());
93 10
        } else {
94
            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...
95
        }
96
    }
97
98
    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...
99 12
    {
100
        $relationships = $this->getDescription()->getRelationships();
101 12
        if(isset($relationships[$key])) {
102 12
            return $this->fetchRelatedFields($relationships[$key]);
103 8
        } else {
104
            return isset($this->modelData[$key]) ? $this->modelData[$key] : null;
105 4
        }
106
    }
107
108
    /**
109
     * Create a new instance of this Model
110
     * @return \ntentan\nibii\RecordWrapper
111
     */
112
    public static function createNew()
113 34
    {
114
        $class = get_called_class();
115 34
        return new $class();
116 34
    }
117
118
    /**
119
     * @method
120
     * @param type $name
121
     * @param type $arguments
122
     * @return type
123
     */
124
    public function __call($name, $arguments)
125 34
    {
126
        return Utils::factory($this->dynamicOperations,
127 34
            function() {
128 34
                return new Operations($this, $this->getDataAdapter());
129 34
            }
130
        )->perform($name, $arguments);
131 34
    }
132
133
    public static function __callStatic($name, $arguments)
134 26
    {
135
        return call_user_func_array([self::createNew(), $name], $arguments);
136 26
    }
137
138
    public function __set($name, $value)
139 8
    {
140
        $this->dataSet = true;
141 8
        $this->modelData[\ntentan\utils\Text::deCamelize($name)] = $value;
142 8
    }
143 8
144
    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...
145 12
    {
146
        return $this->retrieveItem(\ntentan\utils\Text::deCamelize($name));
147 12
    }
148
149
    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...
150 32
    {
151
        return $this->table;
152 32
    }
153
    
154
    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...
155 4
    {
156
        foreach($relationships as $name => $relationship) {
157 4
            $array[$name] = $this->fetchRelatedFields($relationship, $index)->toArray($depth);
158 4
        }
159 4
        return $array;
160 4
    }
161
162
    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...
163 16
    {
164
        $relationships = $this->getDescription()->getRelationships();
165 16
        $array = $this->modelData;
166 16
        if($depth > 0) {
167 16
            if($this->hasMultipleData()) {
168 4
                foreach($array as $i => $value) {
169
                    $array[$i] = $this->expandArrayValue($value, $relationships, $depth - 1, $i);
170
                }
171
            } else {
172
                $array = $this->expandArrayValue($array, $relationships, $depth - 1);
173 4
            }
174
        }
175 4
        return $array;
176 16
    }
177
    
178
    public function save()
179 10
    {
180
        $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...
181 10
        $this->invalidFields = $this->dynamicOperations->getInvalidFields();
182 10
        return $return;
183 10
    }
184
    
185
    public function isValid()
186 18
    {
187
        return $this->__call('isValid', []);
0 ignored issues
show
Documentation introduced by
'isValid' 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...
188 18
    }
189 16
190
    private function hasMultipleData()
191 2
    {
192
        if(count($this->modelData) > 0) {
193
            return is_numeric(array_keys($this->modelData)[0]);
194
        } else {
195 14
            return false;
196
        }
197 14
    }
198
199 14
    public function getData()
200 6
    {
201 14
        $data = [];
202 2
                
203 12
        if(count($this->modelData) == 0) {
204 12
            $data = $this->modelData;
205 12
        } else if($this->hasMultipleData()) {
206
            $data = $this->modelData;
207 14
        } else if(count($this->modelData) > 0) {
208
            $data[] = $this->modelData;
209
        }
210 26
        
211
        return $data;
212 26
    }
213 26
214 26
    public function setData($data)
215
    {
216
        $this->dataSet = true;
217
        $this->modelData = $data;
218
    }
219
    
220
    public function mergeData($data)
221
    {
222
        foreach($data as $key => $value) {
223
            $this->modelData[$key] = $value;
224 2
        }
225
        $this->dataSet = true;
226 2
    }
227
228
    public function offsetExists($offset)
229 2
    {
230
        return isset($this->modelData[$offset]);
231 2
    }
232 2
233
    public function offsetGet($offset)
234 2
    {
235
        if (is_numeric($offset)) {
236
            return $this->wrap($offset);
237
        } else {
238 2
            return $this->retrieveItem($offset);
239
        }
240 2
    }
241 2
242 2
    public function offsetSet($offset, $value)
243
    {
244
        $this->dataSet = true;
245
        $this->modelData[$offset] = $value;
246
    }
247
248
    public function offsetUnset($offset)
249 6
    {
250
        unset($this->modelData[$offset]);
251 6
    }
252 6
253 6
    private function wrap($offset)
254 6
    {
255
        if(isset($this->modelData[$offset])) {
256
            $newInstance = $this->createNew();
257
            $newInstance->setData($this->modelData[$offset]);
258
            return $newInstance;
259
        } else {
260 4
            return null;
261
        }
262 4
    }
263
264
    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...
265
    {
266
        return $this->invalidFields;
267
    }
268
269
    public function getHasMany()
270
    {
271
        return $this->hasMany;
272
    }
273
274
    public function getBelongsTo()
275 4
    {
276
        return $this->belongsTo;
277 4
    }
278
279
    public function current()
280
    {
281
        return $this->wrap($this->index);
282
    }
283
284
    public function key()
285 4
    {
286
        return $this->index;
287 4
    }
288 4
289
    public function next()
290 4
    {
291
        $this->index++;
292 4
    }
293 4
294
    public function rewind()
295 4
    {
296
        $this->index = 0;
297 4
    }
298
299
    public function valid()
300 12
    {
301
        return isset($this->modelData[$this->index]);
302 12
    }
303 12
304 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...
305
    {
306
        if($index === null) {
307 12
            $data = $this->modelData;
308 12
        } else {
309
            $data = $this->modelData[$index];
310
        }
311 12
        $model = $relationship->getModelInstance();
312
        if(empty($data)) {
313
            return $model;
314
        } else {
315 8
            return $model->fetch($relationship->getQuery($data));
316
        }
317
    }
318 8
319 8
    public function getRelationships()
320 8
    {
321 8
        return [
322
            'HasMany' => $this->hasMany,
323
            'BelongsTo' => $this->belongsTo,
324
            'ManyHaveMany' => $this->manyHaveMany
325
        ];
326
    }
327
    
328
    public function usetField($field)
329 8
    {
330
        unset($this->modelData[$field]);
331
    }
332 8
    
333
    public function preSaveCallback()
334 4
    {
335
        
336
    }
337 4
    
338
    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...
339 2
    {
340
        
341
    }
342 2
    
343
    public function preUpdateCallback()
344 2
    {
345
        
346
    }
347 2
    
348
    public function postUpdateCallback()
349 10
    {
350
        
351 10
    }
352
    
353
    public function getBehaviours()
354
    {
355
        return $this->loadedDependencies;
356
    }
357
}
358