AbstractMapper::selectOneModel()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 5
ccs 3
cts 3
cp 1
rs 9.4285
cc 1
eloc 3
nc 1
nop 3
crap 1
1
<?php
2
3
namespace SpeckCatalog\Mapper;
4
5
use SpeckCatalog\Model\AbstractModel;
6
use Zend\Stdlib\Hydrator\ClassMethods;
7
use Zend\Stdlib\Hydrator\HydratorInterface;
8
use SpeckCatalog\Mapper\DbAdapterAwareInterface;
9
use SpeckCatalog\Adapter\PaginatorDbSelect;
10
use Zend\ServiceManager\ServiceLocatorAwareInterface;
11
use Zend\ServiceManager\ServiceLocatorAwareTrait;
12
use Zend\Db\Adapter\Adapter;
13
use Zend\Db\Sql\Select;
14
use Zend\Db\Sql\Sql;
15
use Zend\Paginator\Paginator;
16
use Zend\Db\ResultSet;
17
18
class AbstractMapper implements
19
    DbAdapterAwareInterface,
20
    ServiceLocatorAwareInterface,
21
    ProvidesTableMetadataInterface
22
{
23
    use ServiceLocatorAwareTrait;
24
    use ProvidesTableMetadataTrait;
25
26
    protected $hydrator;
27
    protected $dbAdapter;
28
    protected $model;
29
    protected $tableFields;
30
    protected $tableName;
31
    protected $tableKeyFields;
32
    protected $sql;
33
    protected $usePaginator;
34
    protected $paginatorOptions;
35
    protected $enabledOnly = false;
36
37 34
    public function getSelect($tableName = null)
38 1
    {
39 34
        return $this->getSql()->select($tableName ?: $this->getTableName());
40
    }
41
42 2
    public function getAll()
43
    {
44 2
        $select = $this->getSelect();
45 2
        return $this->selectManyModels($select);
46
    }
47
48 10
    public function find(array $data)
49
    {
50 10
        $select = $this->getSelect()
51 10
            ->where($data);
52 10
        return $this->selectOneModel($select);
53
    }
54
55
    public function findMany(array $data)
56
    {
57
        $select = $this->getSelect()
58
            ->where($data);
59
        return $this->selectManyModels($select);
60
    }
61
62 2
    public function findRow(array $data)
63
    {
64 2
        $select = $this->getSelect()
65 2
            ->where($data);
66 2
        return $this->selectOne($select);
67 1
    }
68
69
    public function findRows(array $data)
70
    {
71
        $select = $this->getSelect()
72
            ->where($data);
73
        return $this->select($select);
74
    }
75
76
    //return array or null
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
77 35
    public function select(Select $select, ResultSet\ResultSetInterface $resultSet = null)
78
    {
79 35
        $stmt = $this->getSql()->prepareStatementForSqlObject($select);
80
81 35
        $resultSet = $resultSet ?: new ResultSet\ResultSet(ResultSet\ResultSet::TYPE_ARRAY);
82 35
        $resultSet->initialize($stmt->execute());
83
84 34
        return $resultSet;
85
    }
86
87
    //return deleted nuber of rows
88 1
    public function delete(array $where, $tableName = null)
89
    {
90 1
        $tableName = $tableName ?: $this->getTableName();
91 1
        $sql = $this->getSql();
92 1
        $delete = $sql->delete($tableName);
93
94 1
        $delete->where($where);
95
96 1
        $statement = $sql->prepareStatementForSqlObject($delete);
97
98 1
        return $statement->execute();
99
    }
100
101
    //returns lastInsertId or null
102 10
    public function insert($dataOrModel, $tableName = null, HydratorInterface $hydrator = null)
103
    {
104 10
        $tableName = $tableName ?: $this->getTableName();
105 9
        $data = $this->extract($dataOrModel, $hydrator);
106
107 9
        if ($tableName === $this->getTableName()) {
108 4
            $data = $this->cleanData($data);
109 4
        }
110
111 9
        if ($tableName === $this->getTableName() && $this->findRow($this->dataToKeyData($data))) {
112
            throw new \RuntimeException('row already exists');
113
        }
114
115 8
        $sql = $this->getSql();
116 7
        $insert = $sql->insert($tableName);
117
118 7
        $insert->values($data);
119
120 7
        $statement = $sql->prepareStatementForSqlObject($insert);
121 7
        $result = $statement->execute();
122
123 5
        return $result->getGeneratedValue();
124
    }
125
126 4
    public function dataToKeyData($data)
127
    {
128 4
        if (!is_array($this->getTableKeyFields())) {
129
            throw new \RuntimeException('no key fields for:' . $this->getTableName());
130
        }
131 4
        foreach ($this->getTableKeyFields() as $field) {
132 4
            $return[$field] = $data[$field];
0 ignored issues
show
Coding Style Comprehensibility introduced by
$return was never initialized. Although not strictly required by PHP, it is generally a good practice to add $return = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
133 2
        }
134 2
        return $return;
0 ignored issues
show
Bug introduced by
The variable $return does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
135
    }
136
137
    //returns affected number of rows
138 4
    public function update($dataOrModel, array $where, $tableName = null, HydratorInterface $hydrator = null)
139
    {
140 4
        $tableName = $tableName ?: $this->getTableName();
141 4
        $data = $this->extract($dataOrModel, $hydrator);
142 4
        if ($tableName === $this->getTableName()) {
143 2
            $data = $this->cleanData($data);
144 2
        }
145
146 4
        $sql = $this->getSql();
147 4
        $update = $sql->update($tableName);
148
149 4
        $update->set($data)
150 4
            ->where($where);
151
152 4
        $statement = $sql->prepareStatementForSqlObject($update);
153
154 4
        return $statement->execute();
155
    }
156
157
    //returns row or null
158 21
    public function selectOne(Select $select, ResultSet\ResultSetInterface $resultSet = null)
159
    {
160 21
        $select->limit(1);
161
        //var_dump($select->getSqlString()); die();
0 ignored issues
show
Unused Code Comprehensibility introduced by
79% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
162 21
        return $this->select($select, $resultSet)->current();
163
    }
164
165
    //returns array of rows
166 15
    public function selectMany(Select $select, ResultSet\ResultSetInterface $resultSet = null)
167
    {
168 15
        if ($this->usePaginator) {
169 1
            $this->usePaginator = false;
170 1
            $rows = $this->initPaginator($select, $resultSet);
171 1
        } else {
172 14
            $result = $this->select($select, $resultSet);
173 13
            $rows = array();
174 13
            foreach ($result as $row) {
175 13
                $rows[] = $row;
176 13
            }
177
        }
178 14
        return $rows;
179
    }
180
181
    //returns model or null
182 11
    public function selectOneModel(Select $select, HydratorInterface $hydrator = null, AbstractModel $model = null)
0 ignored issues
show
Unused Code introduced by
The parameter $hydrator is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $model is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
183
    {
184 11
        $resultSet = new ResultSet\HydratingResultSet($this->getHydrator(), $this->getModel());
185 11
        return $this->selectOne($select, $resultSet);
186
    }
187
188
    //returns array of models
189 14
    public function selectManyModels(Select $select, HydratorInterface $hydrator = null, AbstractModel $model = null)
0 ignored issues
show
Unused Code introduced by
The parameter $hydrator is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $model is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
190
    {
191 14
        $resultSet = new ResultSet\HydratingResultSet($this->getHydrator(), $this->getModel());
192 14
        return $this->selectMany($select, $resultSet);
193
    }
194
195 13
    public function extract($dataOrModel, HydratorInterface $hydrator = null)
196
    {
197 13
        if (is_array($dataOrModel)) {
198 10
            return $dataOrModel;
199
        }
200 3
        if (!$dataOrModel instanceof AbstractModel) {
201
            throw new \InvalidArgumentException('need nstance of AbstractModel got: ' . getType($dataOrModel));
202
        }
203 3
        $hydrator = $hydrator ?: $this->getHydrator();
204 3
        return $hydrator->extract($dataOrModel);
205
    }
206
207 6
    public function cleanData($data)
208
    {
209 6
        if (!is_array($this->getTableFields()) || !count($this->getTableFields())) {
210
            return $data;
211
        }
212 6
        foreach ($data as $key => $val) {
213 6
            if (!in_array($key, $this->getTableFields())) {
214
                unset($data[$key]);
215
            }
216 6
        }
217 6
        return $data;
218
    }
219
220
    public function hydrate(array $data, AbstractModel $model = null, HydratorInterface $hydrator = null)
221
    {
222
        $hydrator = $hydrator ?: $this->getHydrator();
223
        $model    = $model    ?: $this->getModel();
224
225
        return $hydrator->hydrate($data, $model);
226
    }
227
228 1
    public function initPaginator($select, ResultSet\ResultSetInterface $resultSet = null)
229
    {
230 1
        $paginator = new Paginator(new PaginatorDbSelect($select, $this->getDbAdapter(), $resultSet));
231
232 1
        $options = $this->getPaginatorOptions();
233 1
        if (isset($options['n'])) {
234 1
            $paginator->setItemCountPerPage($options['n']);
235 1
        }
236 1
        if (isset($options['p'])) {
237 1
            $paginator->setCurrentPageNumber($options['p']);
238 1
        }
239
240 1
        return $paginator;
241
    }
242
243
    /**
244
     * @return hydrator
245
     */
246 28
    public function getHydrator()
247
    {
248 28
        if (is_string($this->hydrator) && class_exists($this->hydrator)) {
249
            return new $this->hydrator();
250
        } else {
251 28
            return new ClassMethods();
0 ignored issues
show
Deprecated Code introduced by
The class Zend\Stdlib\Hydrator\ClassMethods has been deprecated with message: Use Zend\Hydrator\ClassMethods from zendframework/zend-hydrator instead.

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
252
        }
253
    }
254
255
    /**
256
     * @param $hydrator
257
     * @return self
258
     */
259
    public function setHydrator(HydratorInterface $hydrator)
260
    {
261
        $this->hydrator = $hydrator;
262
        return $this;
263
    }
264
265
    /**
266
     * @return model
267
     */
268 25
    public function getModel(array $data = null)
269
    {
270 25
        if (is_string($this->model) && class_exists($this->model)) {
271 25
            if ($data) {
272
                $hydrator = $this->getHydrator();
273
                return $hydrator->hydrate($data, new $this->model);
274
            }
275 25
            return new $this->model;
276
        } else {
277
            throw new \RuntimeException('could not instantiate model - ' . $this->model);
278
        }
279
    }
280
281
    /**
282
     * @param $model
283
     * @return self
284
     */
285
    public function setModel(AbstractModel $model)
286
    {
287
        $this->model = $model;
288
        return $this;
289
    }
290
291
    /**
292
     * @return Sql
293
     */
294 38
    protected function getSql()
295
    {
296 38
        if (!$this->sql instanceof Sql) {
297 23
            $this->sql = new Sql($this->getDbAdapter());
298 23
        }
299
300 38
        return $this->sql;
301
    }
302
303
    /**
304
     * @param Sql
305
     * @return AbstractDbMapper
306
     */
307
    protected function setSql(Sql $sql)
308
    {
309
        $this->sql = $sql;
310
        return $this;
311
    }
312
313 1
    public function usePaginator(array $paginatorOptions = array())
314
    {
315 1
        $this->usePaginator = true;
316 1
        $this->paginatorOptions = $paginatorOptions;
317 1
        return $this;
318
    }
319
320
    /**
321
     * @return paginatorOptions
322
     */
323 2
    public function getPaginatorOptions()
324
    {
325 2
        return $this->paginatorOptions;
326
    }
327
328
    /**
329
     * @param $paginatorOptions
330
     * @return self
331
     */
332 1
    public function setPaginatorOptions($paginatorOptions)
333
    {
334 1
        $this->paginatorOptions = $paginatorOptions;
335 1
        return $this;
336
    }
337
338
    /**
339
     * @return dbAdapter
340
     */
341 23
    public function getDbAdapter()
342
    {
343 23
        return $this->dbAdapter;
344
    }
345
346
    /**
347
     * @param $dbAdapter
348
     * @return self
349
     */
350 28
    public function setDbAdapter(Adapter $dbAdapter)
351
    {
352 28
        $this->dbAdapter = $dbAdapter;
353 28
        return $this;
354
    }
355
356
    /**
357
     * @return tableName
358
     */
359 40
    public function getTableName()
360
    {
361 40
        return $this->tableName;
362
    }
363
364
    /**
365
     * @param $tableName
366
     * @return self
367
     */
368 1
    public function setTableName($tableName)
369
    {
370 1
        $this->tableName = $tableName;
371 1
        return $this;
372
    }
373
374
    /**
375
     * @return tableFields
376
     */
377 6
    public function getTableFields()
378
    {
379 6
        return $this->tableFields;
380
    }
381
382
    /**
383
     * @param $tableFields
384
     * @return self
385
     */
386
    public function setTableFields($tableFields)
387
    {
388
        $this->tableFields = $tableFields;
389
        return $this;
390
    }
391
392
    /**
393
     * @return tableKeyFields
394
     */
395 4
    public function getTableKeyFields()
396
    {
397 4
        return $this->tableKeyFields;
398
    }
399
400
    /**
401
     * @param $tableKeyFields
402
     * @return self
403
     */
404
    public function setTableKeyFields($tableKeyFields)
405
    {
406
        $this->tableKeyFields = $tableKeyFields;
407
        return $this;
408
    }
409
410 4
    public function enabledOnly()
411
    {
412 4
        return $this->enabledOnly;
413
    }
414
415
    public function setEnabledOnly($bool)
416
    {
417
        $this->enabledOnly = $bool;
418
        return $this;
419
    }
420
}
421