Completed
Push — master ( 996d38...41ff08 )
by SignpostMarv
01:59
created

RememberDaftObjectData()   C

Complexity

Conditions 10
Paths 80

Size

Total Lines 57
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 30
CRAP Score 10.1626

Importance

Changes 0
Metric Value
cc 10
eloc 34
nc 80
nop 1
dl 0
loc 57
rs 6.7123
c 0
b 0
f 0
ccs 30
cts 34
cp 0.8824
crap 10.1626

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
* Base daft objects.
4
*
5
* @author SignpostMarv
6
*/
7
declare(strict_types=1);
8
9
namespace SignpostMarv\DaftObject;
10
11
use ParagonIE\EasyDB\EasyDB;
12
use Throwable;
13
14
abstract class AbstractDaftObjectEasyDBRepository extends DaftObjectMemoryRepository
15
{
16
    /**
17
    * @var EasyDB
18
    */
19
    protected $db;
20
21 5
    protected function __construct(string $type, EasyDB $db)
22
    {
23 5
        parent::__construct($type);
24 5
        $this->db = $db;
25 5
    }
26
27 9
    public static function DaftObjectRepositoryByType(
28
        string $type,
29
        ? EasyDB $db = null
30
    ) : DaftObjectRepository {
31
        if (
32 9
            false === is_a(
33 9
                $type,
34 9
                DaftObjectCreatedByArray::class,
35 9
                true
36
            )
37
        ) {
38 2
            throw new DaftObjectRepositoryTypeByClassMethodAndTypeException(
39 2
                1,
40 2
                static::class,
41 2
                __FUNCTION__,
42 2
                DaftObjectCreatedByArray::class,
43 2
                $type
44
            );
45
        } elseif (
46 7
            false === is_a(
47 7
                $type,
48 7
                DefinesOwnIdPropertiesInterface::class,
49 7
                true
50
            )
51
        ) {
52 1
            throw new DaftObjectRepositoryTypeByClassMethodAndTypeException(
53 1
                1,
54 1
                static::class,
55 1
                __FUNCTION__,
56 1
                DefinesOwnIdPropertiesInterface::class,
57 1
                $type
58
            );
59 6
        } elseif (false === ($db instanceof EasyDB)) {
60 1
            throw new DatabaseConnectionNotSpecifiedException(
61 1
                2,
62 1
                static::class,
63 1
                __FUNCTION__,
64 1
                EasyDB::class,
65 1
                'null'
66
            );
67
        }
68
69
        /**
70
        * @var EasyDB $db
71
        */
72 5
        $db = $db;
73
74 5
        return new static($type, $db);
75
    }
76
77 5
    public static function DaftObjectRepositoryByDaftObject(
78
        DefinesOwnIdPropertiesInterface $object,
79
        ? EasyDB $db = null
80
    ) : DaftObjectRepository {
81 5
        return static::DaftObjectRepositoryByType(get_class($object), $db);
82
    }
83
84
    /**
85
    * @param mixed $id
86
    */
87 2
    public function RemoveDaftObjectById($id) : void
88
    {
89 2
        $id = array_values(is_array($id) ? $id : [$id]);
90
91
        /**
92
        * @var DefinesOwnIdPropertiesInterface $type
93
        */
94 2
        $type = $this->type;
95 2
        $idkv = [];
96
97
        foreach (
98 2
            array_values($type::DaftObjectIdProperties()) as $i => $prop
99
        ) {
100 2
            $idkv[$prop] = $id[$i];
101
        }
102
103 2
        $where = [];
104 2
        foreach (array_keys($idkv) as $col) {
105 2
            $where[] = $this->db->escapeIdentifier($col) . ' = ?';
106
        }
107
108
        $query = (
109
            'DELETE FROM ' .
110 2
            $this->db->escapeIdentifier(
111 2
                $this->DaftObjectDatabaseTable()
112
            ) .
113 2
            ' WHERE ' .
114 2
            implode(' AND ', $where)
115
        );
116
117 2
        $this->db->safeQuery($query, array_values($idkv));
118
119 2
        $this->ForgetDaftObjectById($id);
120 2
    }
121
122
    abstract protected function DaftObjectDatabaseTable() : string;
123
124 2
    protected function RememberDaftObjectData(
125
        DefinesOwnIdPropertiesInterface $object
126
    ) : void {
127 2
        $id = [];
128
129 2
        foreach ($object::DaftObjectIdProperties() as $prop) {
130 2
            $id[$prop] = $object->$prop;
131
        }
132
133 2
        $autoStartTransaction = (false === $this->db->inTransaction());
134
135 2
        if (true === $autoStartTransaction) {
136 2
            $this->db->beginTransaction();
137
        }
138
139
        try {
140 2
            $exists = $this->DaftObjectExistsInDatabase($id);
141 2
            $cols = $object::DaftObjectExportableProperties();
142 2
            if ($exists) {
143 2
                $changed = $object->ChangedProperties();
144 2
                $cols = array_filter(
145 2
                    $cols,
146 2
                    function (string $prop) use ($changed) : bool {
147 2
                        return in_array($prop, $changed, true);
148 2
                    }
149
                );
150
            }
151 2
            if (count($cols) > 0) {
152 2
                $values = [];
153
154 2
                foreach ($cols as $col) {
155 2
                    $values[$col] = $object->$col;
156
                }
157
158 2
                if (false === $exists) {
159 2
                    $this->db->insert(
160 2
                        $this->DaftObjectDatabaseTable(),
161 2
                        $values
162
                    );
163
                } else {
164 2
                    $this->db->update(
165 2
                        $this->DaftObjectDatabaseTable(),
166 2
                        $values,
167 2
                        $id
168
                    );
169
                }
170
            }
171
172 2
            if (true === $autoStartTransaction) {
173 2
                $this->db->commit();
174
            }
175
        } catch (Throwable $e) {
176
            if (true === $autoStartTransaction) {
177
                $this->db->rollBack();
178
            }
179
180
            throw $e;
181
        }
182 2
    }
183
184
    /**
185
    * @param mixed $id
186
    */
187 2
    protected function RecallDaftObjectFromData($id) : ? DaftObject
188
    {
189
        /**
190
        * @var DefinesOwnIdPropertiesInterface $type
191
        */
192 2
        $type = $this->type;
193 2
        $idkv = [];
194
195
        foreach (
196 2
            array_values($type::DaftObjectIdProperties()) as $i => $prop
197
        ) {
198 2
            $idkv[$prop] = $id[$i];
199
        }
200
201 2
        if (true === $this->DaftObjectExistsInDatabase($idkv)) {
202 2
            $where = [];
203 2
            foreach (array_keys($idkv) as $col) {
204 2
                $where[] = $this->db->escapeIdentifier($col) . ' = ?';
205
            }
206
207 2
            $data = $this->db->safeQuery(
208
                (
209
                    'SELECT * FROM ' .
210 2
                    $this->db->escapeIdentifier(
211 2
                        $this->DaftObjectDatabaseTable()
212
                    ) .
213 2
                    ' WHERE ' .
214 2
                    implode(' AND ', $where) .
215 2
                    ' LIMIT 1'
216
                ),
217 2
                array_values($idkv)
218
            );
219
220
            /**
221
            * @var \SignpostMarv\DaftObject\DaftObjectCreatedByArray $type
222
            */
223 2
            $type = $type;
224
225
            /**
226
            * @var DefinesOwnIdPropertiesInterface $out
227
            */
228 2
            $out = new $type($data[0]);
229
230 2
            return $out;
231
        }
232
233 2
        return null;
234
    }
235
236 2
    private function DaftObjectExistsInDatabase(array $id) : bool
237
    {
238 2
        $where = [];
239 2
        foreach (array_keys($id) as $col) {
240 2
            $where[] = $this->db->escapeIdentifier($col) . ' = ?';
241
        }
242
243
        return
244 2
            (int) $this->db->single(
245
                (
246
                    'SELECT COUNT(*) FROM ' .
247 2
                    $this->db->escapeIdentifier(
248 2
                        $this->DaftObjectDatabaseTable()
249
                    ) .
250 2
                    ' WHERE ' .
251 2
                    implode(' AND ', $where)
252
                ),
253 2
                array_values($id)
254 2
            ) >= 1;
255
    }
256
}
257