Completed
Push — master ( b1eb46...b64ef0 )
by Mathieu
01:30
created

DBCollection::loadForParentId()   D

Complexity

Conditions 9
Paths 17

Size

Total Lines 45
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 9
eloc 28
c 2
b 0
f 0
nc 17
nop 3
dl 0
loc 45
rs 4.909
1
<?php
2
namespace Suricate;
3
4
class DBCollection extends Collection
5
{
6
    const TABLE_NAME            = '';           // Name of SQL table containing items
7
    const ITEM_TYPE             = '';           // Class of items in collection
8
    const DB_CONFIG             = '';           // Database configuration identifier
9
    const PARENT_ID_NAME        = 'parent_id';  // Name of the field referencing to parent_id
10
    const PARENT_OBJECT_TYPE    = '';           // Parent object type
11
12
13
    protected $lazyLoad = false;
14
    protected $parentId;                       // Id of the parent
15
    protected $parentFilterName;                // Name of field used for filtering
16
    protected $parentFilterType;                // Value of filter
17
18
    
19
20
    protected $itemOffset        = 0;
21
22
    public function setLazyLoad($lazyLoad)
23
    {
24
        $this->lazyLoad = $lazyLoad;
25
26
        return $this;
27
    }
28
29
    
30
    public function purgeItems()
31
    {
32
        $this->items        = array();
33
        $this->mapping      = array();
34
        $this->itemOffset   = 0;
35
    }
36
37
    
38
    /**
39
     * Load entire table into collection
40
     * @return Collection Loaded collection
41
     */
42
    public static function loadAll()
43
    {
44
        $calledClass    = get_called_class();
45
        $collection     = new $calledClass;
46
47
        $sqlParams      = array();
48
49
        $sql  = "SELECT *";
50
        $sql .= "   FROM `" . $collection::TABLE_NAME . "`";
51
52
        if ($collection->parentFilterType !== '' && $collection->parentFilterType != null) {
53
            $sql .= "WHERE " . $collection->parentFilterName . "=:type";
54
            $sqlParams['type'] = $collection->parentFilterType;
55
        }
56
        $dbLink = Suricate::Database();
57
        if (static::DB_CONFIG != '') {
58
            $dbLink->setConfig(static::DB_CONFIG);
59
        }
60
        $results = $dbLink->query($sql, $sqlParams)->fetchAll();
61
62
        if ($results !== false) {
63
            foreach ($results as $currentResult) {
64
                $itemName = $collection::ITEM_TYPE;
65
                $collection->addItem($itemName::instanciate($currentResult));
66
            }
67
        }
68
69
        return $collection;
70
    }
71
72
    /**
73
     * Static wrapper for loadFromSql
74
     * @param  string     $sql       SQL Statement
75
     * @param  array      $sqlParams SQL Parameters
76
     * @return Suricate\Collection Loaded collection
77
     */
78
    public static function buildFromSql($sql, $sqlParams = array())
79
    {
80
        $calledClass = get_called_class();
81
        $collection = new $calledClass;
82
83
        $collection->loadFromSql($sql, $sqlParams);
84
85
        return $collection;
86
    }
87
88 View Code Duplication
    public function loadFromSql($sql, $sqlParams = array())
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
89
    {
90
        $dbLink = Suricate::Database();
91
        if (static::DB_CONFIG != '') {
92
            $dbLink->setConfig(static::DB_CONFIG);
93
        }
94
95
        $results = Suricate::Database()->query($sql, $sqlParams)->fetchAll();
96
97
        if ($results !== false) {
98
            foreach ($results as $currentResult) {
99
                $itemName = $this::ITEM_TYPE;
100
                $this->addItem($itemName::instanciate($currentResult));
101
            }
102
        }
103
104
        return $this;
105
    }
106
107 View Code Duplication
    public function lazyLoadFromSql($sql, $sqlParams = array())
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
108
    {
109
        $dbLink = Suricate::Database();
110
        if (static::DB_CONFIG != '') {
111
            $dbLink->setConfig(static::DB_CONFIG);
112
        }
113
114
        $results = $dbLink->query($sql, $sqlParams)
115
            ->fetchAll();
116
117
        if ($results !== false) {
118
            foreach ($results as $currentResult) {
119
                $this->addItemLink(current($currentResult));
0 ignored issues
show
Bug introduced by
The method addItemLink() does not exist on Suricate\DBCollection. Did you maybe mean addItem()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
120
            }
121
        }
122
123
        return $this;
124
    }
125
126
    /**
127
     * Load items linked to a parentId
128
     * @param mixed     $parentId       Parent id description
129
     * @param string    $parentIdField  Name of parent id referencing field
130
     * @param closure   $validate       Callback use to validate add to items collection
131
     */
132
    public static function loadForParentId($parentId, $parentIdField = null, $validate = null)
133
    {
134
        $calledClass   = get_called_class();
135
        $collection     = new $calledClass;
136
137
        if ($parentId != '') {
138
            $sqlParams     = array();
139
            $dbHandler     = Suricate::Database(true);
140
141
            if (static::DB_CONFIG != '') {
142
                $dbHandler->setConfig(static::DB_CONFIG);
143
            }
144
145
            $sql  = "SELECT *";
146
            $sql .= " FROM `" . $collection::TABLE_NAME . "`";
147
            $sql .= " WHERE";
148
            if ($parentIdField !== null) {
149
                $sql .= "   " . $parentIdField . "=:parent_id";
150
            } else {
151
                $sql .= "   " . $collection::PARENT_ID_NAME . "=:parent_id";
152
            }
153
154
            if ($collection->parentFilterType !== null) {
155
                $sql .= "   AND " . $collection->parentFilterName . "=:parent_type";
156
                $sqlParams['parent_type'] = $collection->parentFilterType;
157
            }
158
159
            $sqlParams['parent_id'] = $parentId;
160
            $results = $dbHandler->query($sql, $sqlParams)->fetchAll();
161
162
            if ($results !== false) {
163
                foreach ($results as $currentResult) {
164
                    $itemName = $collection::ITEM_TYPE;
165
                    $item = $itemName::instanciate($currentResult);
166
                    if ($validate === null || $validate($item)) {
167
                        $collection->addItem($item);
168
                    }
169
                }
170
            }
171
172
            $collection->parentId = $parentId;
173
        }
174
175
        return $collection;
176
    }
177
178
    public function setParentIdForAll($parentId)
179
    {
180
        $this->parentId = $parentId;
181
        foreach ($this->items as $key => $currentItem) {
182
            $this->items[$key]->{static::PARENT_ID_NAME} = $parentId;
183
        }
184
    }
185
186
    /**
187
     * Load Parent Item, if item type is defined
188
     * @return item type Parent Object
189
     */
190
    public function loadParent()
191
    {
192
        if (static::PARENT_OBJECT_TYPE != '' && $this->parentId != '') {
193
            $parentObjectType = static::PARENT_OBJECT_TYPE;
194
            $parent = new $parentObjectType();
195
            if (method_exists($parent, 'load')) {
196
                $parent->load($this->parentId);
197
198
                return $parent;
199
            } else {
200
                throw new \BadMethodCallException("Parent object does not have a load(\$id) method");
201
            }
202
        } else {
203
            throw new \BadMethodCallException("PARENT_OBJECT_TYPE is not defined");
204
        }
205
    }
206
207
    public function craftItem($itemData)
208
    {
209
        $itemName = static::ITEM_TYPE;
210
211
        foreach ($itemData as $data) {
212
            $newItem = new $itemName();
213
            $newItem->{static::PARENT_ID_NAME} = $this->parentId;
214
            $hasData = false;
215
            foreach ($data as $field => $value) {
216
                $newItem->$field = $value;
217
                if ($value != '') {
218
                    $hasData = true;
219
                }
220
            }
221
222
            // Only add item if there's data inside
223
            if ($hasData) {
224
                $this->addItem($newItem);
225
            }
226
        }
227
    }
228
229
    public function save()
230
    {
231
        // 1st step : delete all records for current parentId
232
        $sql  = "DELETE FROM `" . static::TABLE_NAME . "`";
233
        if (static::PARENT_ID_NAME != '') {
234
            $sql .= " WHERE";
235
            $sql .= "   " . static::PARENT_ID_NAME . "=:parent_id";
236
237
            $sqlParams = array('parent_id' => $this->parentId);
238
        } else {
239
            $sqlParams = array();
240
        }
241
242
        $dbLink = Suricate::Database();
243
        if (static::DB_CONFIG != '') {
244
            $dbLink->setConfig(static::DB_CONFIG);
245
        }
246
        
247
        $dbLink->query($sql, $sqlParams);
248
249
        // 2nd step : save all current items
250
        foreach ($this->items as $currentItem) {
251
            $currentItem->save(true); // Force insert
252
        }
253
    }
254
255
    public function addItem(Interfaces\IDBObject $item)
256
    {
257
        $key = $item::TABLE_INDEX;
258
        // Add item to items pool
259
        $this->items[$this->itemOffset] = $item;
260
261
        // add mapping between item->index and $position in items pool
262
        $this->mapping[$this->itemOffset] = $item->$key;
263
264
        $this->itemOffset++;
265
    }
266
267
    public function getItemsType()
268
    {
269
        return static::ITEM_TYPE;
270
    }
271
272
    public function getParentIdName()
273
    {
274
        return static::PARENT_ID_NAME;
275
    }
276
277
    public function getParentId()
278
    {
279
        return $this->parentId;
280
    }
281
}
282