ManageRegisteredKey::getLastErrorString()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 4
cp 0
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 2
1
<?php
2
declare(strict_types = 1);
3
/**
4
 * Contains class ManageRegisteredKey.
5
 *
6
 * PHP version 7.0+
7
 *
8
 * LICENSE:
9
 * This file is part of Yet Another Php Eve Api Library also know as Yapeal
10
 * which can be used to access the Eve Online API data and place it into a
11
 * database.
12
 * Copyright (C) 2016-2017 Michael Cummings
13
 *
14
 * This program is free software: you can redistribute it and/or modify it
15
 * under the terms of the GNU Lesser General Public License as published by the
16
 * Free Software Foundation, either version 3 of the License, or (at your
17
 * option) any later version.
18
 *
19
 * This program is distributed in the hope that it will be useful, but WITHOUT
20
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
22
 * for more details.
23
 *
24
 * You should have received a copy of the GNU Lesser General Public License
25
 * along with this program. If not, see
26
 * <http://spdx.org/licenses/LGPL-3.0.html>.
27
 *
28
 * You should be able to find a copy of this license in the COPYING-LESSER.md
29
 * file. A copy of the GNU GPL should also be available in the COPYING.md file.
30
 *
31
 * @author    Michael Cummings <[email protected]>
32
 * @copyright 2016-2017 Michael Cummings
33
 * @license   LGPL-3.0+
34
 */
35
namespace Yapeal\AdminTools;
36
37
use Yapeal\Event\MediatorInterface;
38
use Yapeal\Sql\CommonSqlQueries;
39
use Yapeal\Sql\ConnectionInterface;
40
41
/**
42
 * Class ManageRegisteredKey provides CRUD access to the RegisteredKey table.
43
 */
44
class ManageRegisteredKey
45
{
46
    /**
47
     * ManageRegisteredKey constructor.
48
     *
49
     * @param CommonSqlQueries    $csq
50
     * @param ConnectionInterface $pdo
51
     * @param MediatorInterface   $yem
52
     */
53
    public function __construct(CommonSqlQueries $csq, ConnectionInterface $pdo, MediatorInterface $yem)
54
    {
55
        $this->csq = $csq;
56
        $this->pdo = $pdo;
57
        $this->yem = $yem;
58
        $this->columnNames = ['active', 'activeAPIMask', 'keyID', 'vCode'];
59
    }
60
    /**
61
     * @return bool
62
     * @throws \InvalidArgumentException
63
     * @throws \PDOException
64
     * @throws \UnexpectedValueException
65
     */
66
    public function commit(): bool
67
    {
68
        $columnNames = ['active', 'activeAPIMask', 'keyID', 'vCode'];
69
        try {
70
            switch ($this->command) {
71
                case 'create':
72
                    $sql = $this->csq->getInsert('yapealRegisteredKey', $columnNames, 1);
73
                    break;
74
                case 'read':
75
                    $sql = $this->csq->getSelect('yapealRegisteredKey', $columnNames, ['keyID' => $this->keyID]);
76
                    return $this->readFromTable($sql);
77
                case 'update':
78
                    $sql = $this->csq->getUpsert('yapealRegisteredKey', $columnNames, 1);
79
                    break;
80
                case 'delete':
81
                    $sql = $this->csq->getDeleteFromTableWithKeyID('yapealRegisteredKey', $this->keyID);
82
                    break;
83
                default:
84
                    $this->lastErrorString = 'Unknown command';
85
                    return false;
86
                    break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
87
            }
88
        } catch (\BadMethodCallException $exc) {
89
            $this->lastErrorString = 'Failed to get SQL for ' . $this->command;
90
            return false;
91
        }
92
        if (!$this->executeCommandSql($sql)) {
93
            return false;
94
        }
95
        $this->command = '';
96
        $this->lastErrorString = '';
97
        $this->setDirty(false);
98
        return true;
99
    }
100
    /** @noinspection PhpTooManyParametersInspection */
101
    /**
102
     * @param int    $keyID
103
     * @param bool   $active
104
     * @param int    $activeAPIMask
105
     * @param string $vCode
106
     *
107
     * @return self Fluent interface.
108
     */
109
    public function create(int $keyID, bool $active, int $activeAPIMask, string $vCode): self
110
    {
111
        $this->active = $active;
112
        $this->activeAPIMask = $activeAPIMask;
113
        $this->keyID = $keyID;
114
        $this->vCode = $vCode;
115
        $this->command = 'create';
116
        $this->setDirty();
117
        return $this;
118
    }
119
    /**
120
     * @param int $keyID
121
     *
122
     * @return self Fluent interface.
123
     */
124
    public function delete(int $keyID): self
125
    {
126
        $this->keyID = $keyID;
127
        $this->command = 'delete';
128
        $this->setDirty();
129
        return $this;
130
    }
131
    /**
132
     * @return string
133
     */
134
    public function getLastErrorString(): string
135
    {
136
        return $this->lastErrorString;
137
    }
138
    /**
139
     * @return bool
140
     */
141
    public function hasError(): bool
142
    {
143
        return '' === $this->lastErrorString;
144
    }
145
    /**
146
     * @return bool
147
     */
148
    public function isDirty(): bool
149
    {
150
        return $this->dirty;
151
    }
152
    /**
153
     * @param int  $keyID
154
     *
155
     * @param bool $refresh
156
     *
157
     * @return array
158
     * @throws \InvalidArgumentException
159
     * @throws \PDOException
160
     * @throws \UnexpectedValueException
161
     */
162
    public function read(int $keyID, bool $refresh = false): array
163
    {
164
        if ($keyID !== $this->keyID) {
165
            $this->keyID = $keyID;
166
            $refresh = true;
167
        }
168
        if ($refresh) {
169
            $this->command = 'read';
170
            $this->setDirty(true);
171
            $this->commit();
172
        }
173
        return [
174
            'active' => $this->active,
175
            'activeAPIMask' => $this->activeAPIMask,
176
            'keyID' => $keyID,
177
            'vCode' => $this->vCode
178
        ];
179
    }
180
    /**
181
     * @param bool|null   $active
182
     * @param int|null    $activeAPIMask
183
     * @param string|null $vCode
184
     *
185
     * @return self Fluent interface.
186
     */
187
    public function update(bool $active = null, int $activeAPIMask = null, string $vCode = null): self
188
    {
189
        $this->active = $active;
190
        $this->activeAPIMask = $activeAPIMask;
191
        $this->vCode = $vCode;
192
        $this->command = 'update';
193
        $this->setDirty();
194
        return $this;
195
    }
196
    /**
197
     * @param array $columns
198
     *
199
     * @return array
200
     * @throws \InvalidArgumentException
201
     * @throws \UnexpectedValueException
202
     */
203
    private function enforceColumnTypesAndStructure(array $columns): array
204
    {
205
        array_walk($columns,
206
            function (&$value, $key) {
207
                switch ($key) {
208
                    case 'active':
209
                        $value = (bool)$value;
210
                        break;
211
                    case 'activeAPIMask':
212
                    case 'keyID':
213
                        $value = (int)$value;
214
                        break;
215
                    case 'vCode':
216
                        $value = (string)$value;
217
                        break;
218
                    default:
219
                        $mess = 'Given unknown value ' . $key;
220
                        throw new \UnexpectedValueException($mess);
221
                }
222
            });
223
        if (count($this->columnNames) > count($columns)) {
224
            $mess = 'Missing one or more of the required values: "' . implode('","', $this->columnNames) . '"';
225
            $mess .= ' Was given "' . implode('","', array_keys($columns)) . '"';
226
            throw new \InvalidArgumentException($mess);
227
        }
228
        return $columns;
229
    }
230
    /**
231
     * @param string $sql
232
     *
233
     * @return bool
234
     * @throws \PDOException
235
     */
236
    private function executeCommandSql(string $sql)
237
    {
238
        try {
239
            if (!$this->pdo->beginTransaction()) {
240
                $this->lastErrorString = 'Failed to start transaction for ' . $this->command;
241
                return false;
242
            }
243
            $stmt = $this->pdo->prepare($sql);
244
            if (!$stmt->execute([$this->active ?: 0, $this->activeAPIMask, $this->keyID, $this->vCode])) {
245
                if ($this->pdo->inTransaction()) {
246
                    $this->pdo->rollBack();
247
                }
248
                $this->lastErrorString = 'Failed to execute prepared query for ' . $this->command;
249
                return false;
250
            }
251
            if (!$this->pdo->commit()) {
252
                if ($this->pdo->inTransaction()) {
253
                    $this->pdo->rollBack();
254
                }
255
                $this->lastErrorString = 'Failed to commit the transaction for ' . $this->command;
256
                return false;
257
            }
258
        } catch (\PDOException $exc) {
259
            if ($this->pdo->inTransaction()) {
260
                $this->pdo->rollBack();
261
            }
262
            $this->lastErrorString = $exc->getMessage();
263
            return false;
264
        }
265
        return true;
266
    }
267
    /**
268
     * @param string $sql
269
     *
270
     * @return bool
271
     * @throws \InvalidArgumentException
272
     * @throws \PDOException
273
     * @throws \UnexpectedValueException
274
     */
275
    private function readFromTable(string $sql): bool
276
    {
277
        $stmt = $this->pdo->query($sql);
278
        $columns = $stmt->fetchAll(\PDO::FETCH_ASSOC);
279
        if (1 !== count($columns)) {
280
            $this->lastErrorString = 'Expected to fetch a single row for ' . $this->command;
281
            return false;
282
        }
283
        $columns = $this->enforceColumnTypesAndStructure($columns[0]);
284
        foreach ($columns as $index => $column) {
285
            /** @noinspection PhpVariableVariableInspection */
286
            $this->$index = $column;
287
        }
288
        $this->command = '';
289
        $this->setDirty(false);
290
        return true;
291
    }
292
    /**
293
     * @param bool $value
294
     *
295
     * @return self Fluent interface.
296
     */
297
    private function setDirty(bool $value = true): self
298
    {
299
        $this->dirty = $value;
300
        return $this;
301
    }
302
    /**
303
     * @var bool $active
304
     */
305
    private $active = false;
306
    /**
307
     * @var int $activeAPIMask
308
     */
309
    private $activeAPIMask = 0;
310
    /**
311
     * @var array $columnNames
312
     */
313
    private $columnNames;
314
    /**
315
     * @var string $command
316
     */
317
    private $command = '';
318
    /**
319
     * @var CommonSqlQueries $csq
320
     */
321
    private $csq;
322
    /**
323
     * Used to track if the current class data is not synced with the table yet.
324
     *
325
     * @var bool $dirty
326
     */
327
    private $dirty = true;
328
    /**
329
     * @var int $keyID
330
     */
331
    private $keyID;
332
    /**
333
     * @var string $lastErrorString
334
     */
335
    private $lastErrorString = '';
336
    /**
337
     * @var ConnectionInterface $pdo
338
     */
339
    private $pdo;
340
    /**
341
     * @var string $vCode
342
     */
343
    private $vCode = '';
344
    /**
345
     * @var MediatorInterface $yem
346
     */
347
    private $yem;
348
}
349