DBCollection::__sleep()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 7
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 11
ccs 0
cts 8
cp 0
crap 6
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Suricate;
6
7
class DBCollection extends Collection
8
{
9
    /* @var string SQL table name */
10
    protected $tableName = '';
11
    /* @var string Item type stored in collection */
12
    protected $itemsType = '';
13
    /* @var string Database configuration identifier */
14
    protected $DBConfig = '';
15
16
    protected $mapping = [];
17
    protected $loadedValues = [];
18
    protected $lazyLoad = false;
19
20
    protected $dbLink = false;
21
    protected $itemOffset = 0;
22
23
    /**
24
     * Get table name
25
     *
26
     * @return string
27
     */
28 2
    public function getTableName(): string
29
    {
30 2
        return $this->tableName;
31
    }
32
33 4
    public function getItemsType(): string
34
    {
35 4
        return $this->itemsType;
36
    }
37
38 1
    public function getDBConfig(): string
39
    {
40 1
        return $this->DBConfig;
41
    }
42
43
    /**
44
     * __sleep magic method, permits an inherited DBObject class to be serialized
45
     * @return Array of properties to serialize
46
     */
47
    public function __sleep()
48
    {
49
        $discardedProps = ['dbLink'];
50
        $reflection = new \ReflectionClass($this);
51
        $props = $reflection->getProperties();
52
        $result = [];
53
        foreach ($props as $currentProperty) {
54
            $result[] = $currentProperty->name;
55
        }
56
57
        return array_diff($result, $discardedProps);
58
    }
59
60
    /**
61
     * Wake up magic method
62
     * restore dblink to initial value
63
     */
64
    public function __wakeup()
65
    {
66
        $this->dbLink = false;
67
    }
68
69
    /**
70
     * Set lazyload flag
71
     *
72
     * @param bool $lazyLoad
73
     * @return DBCollection
74
     */
75 1
    public function setLazyLoad($lazyLoad)
76
    {
77 1
        $this->lazyLoad = $lazyLoad;
78
79 1
        return $this;
80
    }
81
82
    /**
83
     * Get lazyload flag
84
     *
85
     * @return boolean
86
     */
87 1
    public function getLazyLoad(): bool
88
    {
89 1
        return $this->lazyLoad;
90
    }
91
92
    public function purgeItems()
93
    {
94
        $this->items = [];
95
        $this->mapping = [];
96
        $this->itemOffset = 0;
97
    }
98
99
    /**
100
     * Implementation of ArrayAccess Interface
101
     * override parent get to lazyLoad item
102
     * @param  mixed $offset Offset to get
103
     * @return mixed
104
     */
105 2
    public function offsetGet($offset)
106
    {
107 2
        if (!$this->lazyLoad) {
108 2
            return parent::offsetGet($offset);
109
        }
110
111
        if (
112
            isset($this->loadedValues[$offset]) &&
113
            $this->loadedValues[$offset]
114
        ) {
115
            return $this->items[$offset];
116
        }
117
118
        $itemType = $this->itemsType;
119
        $itemToLoad = new $itemType();
120
        $itemToLoad->load($this->items[$offset]);
121
122
        $this->items[$offset] = $itemToLoad;
123
        $this->loadedValues[$offset] = true;
124
125
        return $this->items[$offset];
126
    }
127
128
    /**
129
     * Load entire table into collection
130
     * @return DBCollection Loaded collection
131
     */
132 1
    public static function loadAll()
133
    {
134 1
        $calledClass = get_called_class();
135 1
        $collection = new $calledClass();
136
137 1
        $sqlParams = [];
138
139 1
        $sql = "SELECT *";
140 1
        $sql .= "   FROM `" . $collection->getTableName() . "`";
141
142 1
        $collection->loadFromSql($sql, $sqlParams);
143
144 1
        return $collection;
145
    }
146
147
    /**
148
     * Static wrapper for loadFromSql
149
     * @param  string     $sql       SQL Statement
150
     * @param  array      $sqlParams SQL Parameters
151
     * @return DBCollection Loaded collection
152
     */
153 1
    public static function buildFromSql($sql, $sqlParams = [])
154
    {
155 1
        $calledClass = get_called_class();
156 1
        $collection = new $calledClass();
157
158 1
        $collection->loadFromSql($sql, $sqlParams);
159
160 1
        return $collection;
161
    }
162
163
    /**
164
     * Load collection from SQL query
165
     *
166
     * @param string $sql       SQL query
167
     * @param array  $sqlParams associative array of SQL params
168
     * @return DBCollection
169
     */
170 3
    public function loadFromSql($sql, $sqlParams = [])
171
    {
172
        if (
173 3
            !in_array(
174 3
                Interfaces\IDBObject::class,
175 3
                class_implements($this->itemsType)
176
            )
177
        ) {
178
            throw new \BadMethodCallException(
179
                'Item type does not implement IDBObject interface'
180
            );
181
        }
182
183 3
        $this->connectDB();
184 3
        $results = $this->dbLink->query($sql, $sqlParams)->fetchAll();
185
186 3
        if ($results !== false) {
187 3
            foreach ($results as $currentResult) {
188 3
                $itemName = $this->getItemsType();
189 3
                $item = $itemName::instanciate($currentResult);
190 3
                $item->setLoaded();
191 3
                $this->addItem($item);
192
            }
193
        }
194
195 3
        return $this;
196
    }
197
198
    protected function addItemLink($linkId)
199
    {
200
        $this->items[$this->itemOffset] = $linkId;
201
        // add mapping between item->index and $position in items pool
202
        $this->mapping[$this->itemOffset] = $linkId;
203
        $this->loadedValues[$this->itemOffset] = false;
204
        $this->itemOffset++;
205
    }
206
207
    public function lazyLoadFromSql($sql, $sqlParams = [])
208
    {
209
        $this->connectDB();
210
        $results = $this->dbLink->query($sql, $sqlParams)->fetchAll();
211
212
        if ($results !== false) {
213
            foreach ($results as $currentResult) {
214
                $this->addItemLink(current($currentResult));
215
            }
216
        }
217
218
        return $this;
219
    }
220
221
    public function craftItem($itemData)
222
    {
223
        $itemName = $this->itemsType;
224
225
        foreach ($itemData as $data) {
226
            $newItem = new $itemName();
227
            $hasData = false;
228
            foreach ($data as $field => $value) {
229
                $newItem->$field = $value;
230
                if ($value != '') {
231
                    $hasData = true;
232
                }
233
            }
234
235
            // Only add item if there's data inside
236
            if ($hasData) {
237
                $this->addItem($newItem);
238
            }
239
        }
240
    }
241
242
    public function save()
243
    {
244
        foreach ($this->items as $currentItem) {
245
            $currentItem->save(true); // Force insert
246
        }
247
    }
248
249 3
    public function addItem(Interfaces\IDBObject $item)
250
    {
251 3
        $key = $item->getTableIndex();
252
        // Add item to items pool
253 3
        $this->items[$this->itemOffset] = $item;
254
255
        // add mapping between item->index and $position in items pool
256 3
        $this->mapping[$this->itemOffset] = $item->$key;
257
258 3
        $this->itemOffset++;
259
260 3
        return $this;
261
    }
262
263
    /**
264
     * Connect to database layer
265
     *
266
     * @return void
267
     * @SuppressWarnings(PHPMD.StaticAccess)
268
     */
269 3
    protected function connectDB()
270
    {
271 3
        if (!$this->dbLink) {
272
            $this->dbLink = Suricate::Database();
273
            if ($this->getDBConfig() !== '') {
274
                $this->dbLink->setConfig($this->getDBConfig());
275
            }
276
        }
277 3
    }
278
}
279