GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( 343d0a...c5b636 )
by James Ekow Abaka
02:58
created

DataOperations::doValidate()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 8
ccs 0
cts 6
cp 0
rs 9.4285
cc 2
eloc 6
nc 1
nop 0
crap 6
1
<?php
2
3
/*
4
 * The MIT License
5
 *
6
 * Copyright 2015 ekow.
7
 *
8
 * Permission is hereby granted, free of charge, to any person obtaining a copy
9
 * of this software and associated documentation files (the "Software"), to deal
10
 * in the Software without restriction, including without limitation the rights
11
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
 * copies of the Software, and to permit persons to whom the Software is
13
 * furnished to do so, subject to the following conditions:
14
 *
15
 * The above copyright notice and this permission notice shall be included in
16
 * all copies or substantial portions of the Software.
17
 *
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
 * THE SOFTWARE.
25
 */
26
27
namespace ntentan\nibii;
28
29
/**
30
 * Description of DataOperations
31
 *
32
 * @author ekow
33
 */
34
class DataOperations {
35
36
    private $wrapper;
37
38
    /**
39
     *
40
     * @var DriverAdapter
41
     */
42
    private $adapter;
43
    private $data;
44
    private $invalidFields;
45
    private $hasMultipleData;
46
    private $driver;
47
    private $container;
48
49
    const MODE_SAVE = 0;
50
    const MODE_UPDATE = 1;
51
52 35 View Code Duplication
    public function __construct(ORMContext $context, RecordWrapper $wrapper, DriverAdapter $adapter) {
53 35
        $this->wrapper = $wrapper;
54 35
        $this->adapter = $adapter;
55 35
        $this->driver = $context->getDbContext()->getDriver();
56 35
        $this->container = $context->getContainer();
57 35
    }
58
59 10
    public function doSave($hasMultipleData) {
60 10
        $this->hasMultipleData = $hasMultipleData;
61 10
        $invalidFields = [];
62 10
        $data = $this->wrapper->getData();
63 10
        $primaryKey = $this->wrapper->getDescription()->getPrimaryKey();
64 10
        $singlePrimaryKey = null;
0 ignored issues
show
Unused Code introduced by
$singlePrimaryKey is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
65 10
        $succesful = true;
66
67 10
        if (count($primaryKey) == 1) {
68 10
            $singlePrimaryKey = $primaryKey[0];
0 ignored issues
show
Unused Code introduced by
$singlePrimaryKey is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
69
        }
70
71
        // Assign an empty array to force a validation error for empty models
72 10
        if (empty($data)) {
73 2
            $data = [[]];
74
        }
75
76 10
        $this->driver->beginTransaction();
77
78 10
        foreach ($data as $i => $datum) {
79 10
            $status = $this->saveRecord($datum, $primaryKey);
0 ignored issues
show
Documentation introduced by
$primaryKey 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...
80 10
            $data[$i] = $datum;
81
82 10
            if (!$status['success']) {
83 4
                $succesful = false;
84 4
                $invalidFields[$i] = $status['invalid_fields'];
85 4
                $this->driver->rollback();
86 10
                break;
87
            }
88
        }
89
90 10
        if ($succesful) {
91 6
            $this->driver->commit();
92
        } else {
93 4
            $this->assignValue($this->invalidFields, $invalidFields);
94
        }
95
96 10
        $this->wrapper->setData($hasMultipleData ? $data : $data[0]);
97
98 10
        return $succesful;
99
    }
100
    
101
    public function doValidate() {
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...
102
        $record = $this->wrapper->getData()[0];
103
        $primaryKey = $this->wrapper->getDescription()->getPrimaryKey();
104
        $pkSet = $this->isPrimaryKeySet($primaryKey, $record);
105
        return $this->validate(
106
            $record, $pkSet ? DataOperations::MODE_UPDATE : DataOperations::MODE_SAVE
107
        );
108
    }
109
110
    /**
111
     * Save an individual record.
112
     * 
113
     * @param array $record The record to be saved
114
     * @param type $primaryKey The primary keys of the record
115
     * @return boolean
0 ignored issues
show
Documentation introduced by
Should the return type not be array?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
116
     */
117 10
    private function saveRecord(&$record, $primaryKey) {
118
        $status = [
119 10
            'success' => true,
120
            'pk_assigned' => null,
121
            'invalid_fields' => []
122
        ];
123
124
        // Determine if the primary key of the record is set.
125 10
        $pkSet = $this->isPrimaryKeySet($primaryKey, $record);
126
127
        // Reset the data in the model to contain only the data to be saved
128 10
        $this->wrapper->setData($record);
129
130
        // Run preUpdate or preSave callbacks on models and behaviours
131 10
        if ($pkSet) {
132 2
            $this->wrapper->preUpdateCallback();
133 2
            $record = $this->wrapper->getData();
134 2
            $record = reset($record) === false ? [] : reset($record);
135 2
            $record = $this->runBehaviours('preUpdateCallback', [$record]);
136
        } else {
137 8
            $this->wrapper->preSaveCallback();
138 8
            $record = $this->wrapper->getData();
139 8
            $record = reset($record) === false ? [] : reset($record);
140 8
            $record = $this->runBehaviours('preSaveCallback', [$record]);
141
        }
142
143
        // Validate the data
144 10
        $validity = $this->validate(
145 10
            $record, $pkSet ? DataOperations::MODE_UPDATE : DataOperations::MODE_SAVE
146
        );
147
148
        // Exit if data is invalid
149 10
        if ($validity !== true) {
150 4
            $status['invalid_fields'] = $validity;
151 4
            $status['success'] = false;
152 4
            return $status;
153
        }
154
        
155
        // Save any relationships that are attached to the data
156 6
        $relationships = $this->wrapper->getDescription()->getRelationships();
157 6
        $presentRelationships = [];
158
        
159 6
        foreach($relationships ?? [] as $model => $relationship) {
160 6
            if(isset($record[$model])) {
161
                $relationship->preSave($record, $record[$model]);
162 6
                $presentRelationships[$model] = $relationship;
163
            }
164
        }
165
        
166
        // Assign the data to the wrapper again
167 6
        $this->wrapper->setData($record);
168
169
        // Update or save the data and run post callbacks
170 6
        if ($pkSet) {
171 2
            $this->adapter->update($record);
172 2
            $this->wrapper->postUpdateCallback();
173 2
            $this->runBehaviours('postUpdateCallback', [$record]);
174
        } else {
175 4
            $this->adapter->insert($record);
176 4
            $keyValue = $this->driver->getLastInsertId();
177 4
            $this->wrapper->{$primaryKey[0]} = $keyValue;
178 4
            $this->wrapper->postSaveCallback($keyValue);
179 4
            $this->runBehaviours('postSaveCallback', [$record, $keyValue]);
180
        }
181
        
182 6
        foreach($presentRelationships as $model => $relationship) {
183
            $relationship->postSave($record);
184
        }        
185
186
        // Reset the data so it contains any modifications made by callbacks
187 6
        $record = $this->wrapper->getData()[0];
188 6
        return $status;
189
    }
190
191 10
    private function validate($data, $mode) {
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...
192 10
        $valid = true;
193 10
        $validator = $this->container->resolve(
194 10
            ModelValidator::class, ['model' => $this->wrapper, 'mode' => $mode]
195
        );
196
197 10
        if (!$validator->validate($data)) {
198 4
            $valid = false;
199
        }
200
201 10
        if ($valid) {
202 6
            $valid = $this->wrapper->onValidate();
203
        }
204
205 10
        if ($valid === false) {
206 4
            $valid = $validator->getInvalidFields();
207
        }
208
209 10
        return $valid;
210
    }
211
212 10
    private function isPrimaryKeySet($primaryKey, $data) {
213 10
        if (is_string($primaryKey) && ($data[$primaryKey] !== null || $data[$primaryKey] !== '')) {
214
            return true;
215
        }
216 10
        foreach ($primaryKey as $keyField) {
217 10
            if (!isset($data[$keyField]) || $data[$keyField] === null || $data[$keyField] === '') {
218 10
                return false;
219
            }
220
        }
221 2
        return true;
222
    }
223
224 4
    private function assignValue(&$property, $value) {
225 4
        if ($this->hasMultipleData) {
226
            $property = $value;
227
        } else {
228 4
            $property = $value[0];
229
        }
230 4
    }
231
232
    public function getData() {
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...
233
        return $this->data;
234
    }
235
236 10
    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...
237 10
        return $this->invalidFields;
238
    }
239
240
    public function isItemDeletable($primaryKey, $data) {
241
        if ($this->isPrimaryKeySet($primaryKey, $data)) {
242
            return true;
243
        } else {
244
            return false;
245
        }
246
    }
247
248 10
    private function runBehaviours($event, $args) {
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...
249 10
        foreach ($this->wrapper->getBehaviours() as $behaviour) {
250
            $args[0] = call_user_func_array([$behaviour, $event], $args);
251
        }
252 10
        return $args[0];
253
    }
254
255
}
256