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 ( fe0287...bef35d )
by James Ekow Abaka
01:41
created

DataOperations::saveRecord()   C

Complexity

Conditions 10
Paths 52

Size

Total Lines 68
Code Lines 39

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 32
CRAP Score 10.0203

Importance

Changes 3
Bugs 0 Features 0
Metric Value
c 3
b 0
f 0
dl 0
loc 68
ccs 32
cts 34
cp 0.9412
rs 6.0995
cc 10
eloc 39
nc 52
nop 2
crap 10.0203

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
use ntentan\atiaa\Driver;
30
31
/**
32
 * Description of DataOperations
33
 *
34
 * @author ekow
35
 */
36
class DataOperations
37
{
38
39
    private $wrapper;
40
41
    /**
42
     * Private instance of driver adapter
43
     *
44
     * @var DriverAdapter
45
     */
46
    private $adapter;
47
48
    /**
49
     * Copy of data to be manipulated in the operations.
50
     * @var array
51
     */
52
    private $data;
53
54
    /**
55
     * Fields that contained errors after save or update operations were performed.
56
     * @var array
57
     */
58
    private $invalidFields;
59
60
    /**
61
     * Set to true when the model holds multiple records.
62
     * @var bool
63
     */
64
    private $hasMultipleData;
65
66
    /**
67
     * An instance of the atiaa driver.
68
     * @var Driver
69
     */
70
    private $driver;
71
72
    const MODE_SAVE = 0;
73
    const MODE_UPDATE = 1;
74
75 34
    public function __construct(RecordWrapper $wrapper, Driver $driver)
76
    {
77 34
        $this->wrapper = $wrapper;
78 34
        $this->adapter = $wrapper->getAdapter();
79 34
        $this->driver = $driver;
80 34
    }
81
82 10
    public function doSave(bool $hasMultipleData): bool
83
    {
84 10
        $this->hasMultipleData = $hasMultipleData;
85 10
        $invalidFields = [];
86 10
        $data = $this->wrapper->getData();
87
88 10
        $primaryKey = $this->wrapper->getDescription()->getPrimaryKey();
89 10
        $succesful = true;
90
91
        // Assign an empty array to force a validation error for empty models
92 10
        if (empty($data)) {
93 2
            $data = [[]];
94
        }
95
96 10
        $this->driver->beginTransaction();
97
98 10
        foreach ($data as $i => $datum) {
99 10
            $status = $this->saveRecord($datum, $primaryKey);
100 10
            $data[$i] = $datum;
101
102 10
            if (!$status['success']) {
103 4
                $succesful = false;
104 4
                $invalidFields[$i] = $status['invalid_fields'];
105 4
                $this->driver->rollback();
106 10
                break;
107
            }
108
        }
109
110 10
        if ($succesful) {
111 6
            $this->driver->commit();
112
        } else {
113 4
            $this->assignValue($this->invalidFields, $invalidFields);
114
        }
115
116 10
        $this->wrapper->setData($hasMultipleData ? $data : $data[0]);
117
118 10
        return $succesful;
119
    }
120
121
    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...
122
    {
123
        $record = $this->wrapper->getData()[0];
124
        $primaryKey = $this->wrapper->getDescription()->getPrimaryKey();
125
        $pkSet = $this->isPrimaryKeySet($primaryKey, $record);
126
        return $this->validate(
127
            $record, $pkSet ? DataOperations::MODE_UPDATE : DataOperations::MODE_SAVE
128
        );
129
    }
130
131
    /**
132
     * Save an individual record.
133
     * 
134
     * @param array $record The record to be saved
135
     * @param array $primaryKey The primary keys of the record
136
     * @return array
137
     */
138 10
    private function saveRecord(array &$record, array $primaryKey): array
139
    {
140
        $status = [
141 10
            'success' => true,
142
            'pk_assigned' => null,
143
            'invalid_fields' => []
144
        ];
145
146
        // Determine if the primary key of the record is set.
147 10
        $pkSet = $this->isPrimaryKeySet($primaryKey, $record);
148
149
        // Reset the data in the model to contain only the data to be saved
150 10
        $this->wrapper->setData($record);
151
152
        // Run preUpdate or preSave callbacks on models and behaviours
153 10
        if ($pkSet) {
154 2
            $this->wrapper->preUpdateCallback();
155 2
            $record = $this->wrapper->getData();
156 2
            $record = reset($record) === false ? [] : reset($record);
157
        } else {
158 8
            $this->wrapper->preSaveCallback();
159 8
            $record = $this->wrapper->getData();
160 8
            $record = reset($record) === false ? [] : reset($record);
161
        }
162
163
        // Validate the data
164 10
        $validity = $this->validate($record, $pkSet ? DataOperations::MODE_UPDATE : DataOperations::MODE_SAVE);
165
166
        // Exit if data is invalid
167 10
        if ($validity !== true) {
168 4
            $status['invalid_fields'] = $validity;
169 4
            $status['success'] = false;
170 4
            return $status;
171
        }
172
173
        // Save any relationships that are attached to the data
174 6
        $relationships = $this->wrapper->getDescription()->getRelationships();
175 6
        $presentRelationships = [];
176
177 6
        foreach ($relationships ?? [] as $model => $relationship) {
178 6
            if (isset($record[$model])) {
179
                $relationship->preSave($record, $record[$model]);
180 6
                $presentRelationships[$model] = $relationship;
181
            }
182
        }
183
184
        // Assign the data to the wrapper again
185 6
        $this->wrapper->setData($record);
186
187
        // Update or save the data and run post callbacks
188 6
        if ($pkSet) {
189 2
            $this->adapter->update($record);
190 2
            $this->wrapper->postUpdateCallback();
191
        } else {
192 4
            $this->adapter->insert($record);
193 4
            $keyValue = $this->driver->getLastInsertId();
194 4
            $this->wrapper->{$primaryKey[0]} = $keyValue;
195 4
            $this->wrapper->postSaveCallback($keyValue);
196
        }
197
198
        // Reset the data so it contains any modifications made by callbacks
199 6
        $record = $this->wrapper->getData()[0];
200 6
        foreach ($presentRelationships as $model => $relationship) {
201
            $relationship->postSave($record);
202
        }
203
204 6
        return $status;
205
    }
206
207 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...
208
    {
209 10
        $validator = ORMContext::getInstance()->getModelValidatorFactory()->createModelValidator($this->wrapper, $mode);
210 10
        $errors = [];
211
212 10
        if (!$validator->validate($data)) {
213 4
            $errors = $validator->getInvalidFields();
214
        }
215 10
        $errors = $this->wrapper->onValidate($errors);
216 10
        return empty($errors) ? true : $errors;
217
    }
218
219 10
    private function isPrimaryKeySet($primaryKey, $data)
220
    {
221 10
        if (is_string($primaryKey) && ($data[$primaryKey] !== null || $data[$primaryKey] !== '')) {
222
            return true;
223
        }
224 10
        foreach ($primaryKey as $keyField) {
225 10
            if (!isset($data[$keyField]) || $data[$keyField] === null || $data[$keyField] === '') {
226 10
                return false;
227
            }
228
        }
229 2
        return true;
230
    }
231
232 4
    private function assignValue(&$property, $value)
233
    {
234 4
        if ($this->hasMultipleData) {
235
            $property = $value;
236
        } else {
237 4
            $property = $value[0];
238
        }
239 4
    }
240
241
    public function getData()
242
    {
243
        return $this->data;
244
    }
245
246 10
    public function getInvalidFields()
247
    {
248 10
        return $this->invalidFields;
249
    }
250
251
    public function isItemDeletable($primaryKey, $data)
252
    {
253
        if ($this->isPrimaryKeySet($primaryKey, $data)) {
254
            return true;
255
        } else {
256
            return false;
257
        }
258
    }
259
260
}
261