Completed
Push — develop ( 2e1df2...27dbda )
by Mathieu
03:22
created

DBCollection   B

Complexity

Total Complexity 45

Size/Duplication

Total Lines 276
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
eloc 126
dl 0
loc 276
ccs 0
cts 131
cp 0
rs 8.8
c 0
b 0
f 0
wmc 45

15 Methods

Rating   Name   Duplication   Size   Complexity  
A loadParent() 0 14 4
A addItem() 0 10 1
A getParentId() 0 3 1
A purgeItems() 0 5 1
A getParentIdName() 0 3 1
A lazyLoadFromSql() 0 17 4
A getItemsType() 0 3 1
A buildFromSql() 0 8 1
A save() 0 23 4
B loadForParentId() 0 44 9
A loadFromSql() 0 17 4
A craftItem() 0 18 5
A setLazyLoad() 0 5 1
A setParentIdForAll() 0 5 2
A loadAll() 0 28 6

How to fix   Complexity   

Complex Class

Complex classes like DBCollection often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use DBCollection, and based on these observations, apply Extract Interface, too.

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();
0 ignored issues
show
Bug introduced by
The method Database() does not exist on Suricate\Suricate. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

56
        /** @scrutinizer ignore-call */ 
57
        $dbLink = Suricate::Database();
Loading history...
57
        if (static::DB_CONFIG != '') {
0 ignored issues
show
introduced by
The condition static::DB_CONFIG != '' is always false.
Loading history...
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
0 ignored issues
show
Bug introduced by
The type Suricate\Suricate\Collection was not found. Did you mean Suricate\Collection? If so, make sure to prefix the type with \.
Loading history...
77
     */
78
    public static function buildFromSql($sql, $sqlParams = [])
79
    {
80
        $calledClass = get_called_class();
81
        $collection = new $calledClass;
82
83
        $collection->loadFromSql($sql, $sqlParams);
84
85
        return $collection;
86
    }
87
88
    public function loadFromSql($sql, $sqlParams = array())
89
    {
90
        $dbLink = Suricate::Database();
91
        if (static::DB_CONFIG != '') {
0 ignored issues
show
introduced by
The condition static::DB_CONFIG != '' is always false.
Loading history...
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
    public function lazyLoadFromSql($sql, $sqlParams = array())
108
    {
109
        $dbLink = Suricate::Database();
110
        if (static::DB_CONFIG != '') {
0 ignored issues
show
introduced by
The condition static::DB_CONFIG != '' is always false.
Loading history...
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()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

119
                $this->/** @scrutinizer ignore-call */ 
120
                       addItemLink(current($currentResult));

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

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|null $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 != '') {
0 ignored issues
show
introduced by
The condition static::DB_CONFIG != '' is always false.
Loading history...
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
0 ignored issues
show
Bug introduced by
The type Suricate\item was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
189
     */
190
    public function loadParent()
191
    {
192
        if (static::PARENT_OBJECT_TYPE != '' && $this->parentId != '') {
0 ignored issues
show
introduced by
The condition static::PARENT_OBJECT_TYPE != '' is always false.
Loading history...
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 != '') {
0 ignored issues
show
introduced by
The condition static::PARENT_ID_NAME != '' is always true.
Loading history...
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 != '') {
0 ignored issues
show
introduced by
The condition static::DB_CONFIG != '' is always false.
Loading history...
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;
0 ignored issues
show
Bug introduced by
The constant Suricate\Interfaces\IDBObject::TABLE_INDEX was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
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