Completed
Push — master ( 634be5...2c8eb1 )
by Sherif
10:27
created

AbstractRepository::deleted()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 14
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 8
nc 4
nop 5
1
<?php namespace App\Modules\V1\Core\AbstractRepositories;
2
3
use App\Modules\V1\Core\Interfaces\RepositoryInterface;
4
5
abstract class AbstractRepository implements RepositoryInterface
6
{
7
    /**
8
     * The model implementation.
9
     * 
10
     * @var model
11
     */
12
    public $model;
13
    
14
    /**
15
     * The config implementation.
16
     * 
17
     * @var config
18
     */
19
    protected $config;
20
    
21
    /**
22
     * Create new AbstractRepository instance.
23
     */
24
    public function __construct()
25
    {   
26
        $this->config = \CoreConfig::getConfig();
27
        $this->model  = \App::make($this->getModel());
28
    }
29
30
    /**
31
     * Fetch all records with relations from the storage.
32
     *
33
     * @param  array   $relations
34
     * @param  string  $sortBy
35
     * @param  boolean $desc
36
     * @param  array   $columns
37
     * @return collection
38
     */
39
    public function all($relations = [], $sortBy = 'created_at', $desc = 1, $columns = array('*'))
40
    {
41
        $sort = $desc ? 'desc' : 'asc';
42
        return call_user_func_array("{$this->getModel()}::with", array($relations))->orderBy($sortBy, $sort)->get($columns);
43
    }
44
45
    /**
46
     * Fetch all records with relations from storage in pages 
47
     * that matche the given query.
48
     * 
49
     * @param  string  $query
50
     * @param  integer $perPage
51
     * @param  array   $relations
52
     * @param  string  $sortBy
53
     * @param  boolean $desc
54
     * @param  array   $columns
55
     * @return collection
56
     */
57
    public function search($query, $perPage = 15, $relations = [], $sortBy = 'created_at', $desc = 1, $columns = array('*'))
58
    {
59
        $model            = call_user_func_array("{$this->getModel()}::with", array($relations));
60
        $conditionColumns = $this->model->searchable;
61
        $sort             = $desc ? 'desc' : 'asc';
62
63
        /**
64
         * Construct the select conditions for the model.
65
         */
66
        $model->where(function ($q) use ($query, $conditionColumns, $relations){
67
68 View Code Duplication
            if (count($conditionColumns)) 
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
69
            {
70
                /**
71
                 * Use the first element in the model columns to construct the first condition.
72
                 */
73
                $q->where(\DB::raw('LOWER(' . array_shift($conditionColumns) . ')'), 'LIKE', '%' . strtolower($query) . '%');
74
            }
75
76
            /**
77
             * Loop through the rest of the columns to construct or where conditions.
78
             */
79
            foreach ($conditionColumns as $column) 
80
            {
81
                $q->orWhere(\DB::raw('LOWER(' . $column . ')'), 'LIKE', '%' . strtolower($query) . '%');
82
            }
83
84
            /**
85
             * Loop through the model relations.
86
             */
87
            foreach ($relations as $relation) 
88
            {
89
                /**
90
                 * Remove the sub relation if exists.
91
                 */
92
                $relation = explode('.', $relation)[0];
93
94
                /**
95
                 * Try to fetch the relation repository from the core.
96
                 */
97
                if (\Core::$relation()) 
98
                {
99
                    /**
100
                     * Construct the relation condition.
101
                     */
102
                    $q->orWhereHas($relation, function ($subModel) use ($query, $relation){
103
104
                        $subModel->where(function ($q) use ($query, $relation){
105
106
                            /**
107
                             * Get columns of the relation.
108
                             */
109
                            $subConditionColumns = \Core::$relation()->model->searchable;
110
111 View Code Duplication
                            if (count($subConditionColumns)) 
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
112
                            {
113
                                /**
114
                                * Use the first element in the relation model columns to construct the first condition.
115
                                 */
116
                                $q->where(\DB::raw('LOWER(' . array_shift($subConditionColumns) . ')'), 'LIKE', '%' . strtolower($query) . '%');
117
                            }
118
119
                            /**
120
                             * Loop through the rest of the columns to construct or where conditions.
121
                             */
122
                            foreach ($subConditionColumns as $subConditionColumn)
123
                            {
124
                                $q->orWhere(\DB::raw('LOWER(' . $subConditionColumn . ')'), 'LIKE', '%' . strtolower($query) . '%');
125
                            } 
126
                        });
127
128
                    });
129
                }
130
            }
131
        });
132
        
133
        return $model->orderBy($sortBy, $sort)->paginate($perPage, $columns);
134
    }
135
    
136
    /**
137
     * Fetch all records with relations from storage in pages.
138
     * 
139
     * @param  integer $perPage
140
     * @param  array   $relations
141
     * @param  string  $sortBy
142
     * @param  boolean $desc
143
     * @param  array   $columns
144
     * @return collection
145
     */
146
    public function paginate($perPage = 15, $relations = [], $sortBy = 'created_at', $desc = 1, $columns = array('*'))
147
    {
148
        $sort = $desc ? 'desc' : 'asc';
149
        return call_user_func_array("{$this->getModel()}::with", array($relations))->orderBy($sortBy, $sort)->paginate($perPage, $columns);
150
    }
151
152
    /**
153
     * Fetch all records with relations based on
154
     * the given condition from storage in pages.
155
     * 
156
     * @param  array   $conditions array of conditions
157
     * @param  integer $perPage
158
     * @param  array   $relations
159
     * @param  string  $sortBy
160
     * @param  boolean $desc
161
     * @param  array   $columns
162
     * @return collection
163
     */
164
    public function paginateBy($conditions, $perPage = 15, $relations = [], $sortBy = 'created_at', $desc = 1, $columns = array('*'))
165
    {
166
        unset($conditions['page']);
167
        $conditions = $this->constructConditions($conditions);
168
        $sort       = $desc ? 'desc' : 'asc';
169
        return call_user_func_array("{$this->getModel()}::with", array($relations))->whereRaw($conditions['conditionString'], $conditions['conditionValues'])->orderBy($sortBy, $sort)->paginate($perPage, $columns);
170
    }
171
    
172
    /**
173
     * Save the given model to the storage.
174
     * 
175
     * @param  array   $data
176
     * @param  boolean $saveLog
177
     * @return void
178
     */
179
    public function save(array $data, $saveLog = true)
180
    {
181
        $model      = false;
182
        $modelClass = $this->model;
183
        $relations  = [];
184
185
        \DB::transaction(function () use (&$model, &$relations, $data, $saveLog, $modelClass) {
186
            /**
187
             * If the id is present in the data then select the model for updating,
188
             * else create new model.
189
             * @var array
190
             */
191
            $model = array_key_exists('id', $data) ? $modelClass->lockForUpdate()->find($data['id']) : new $modelClass;
192
            if ( ! $model) 
193
            {
194
                \ErrorHandler::notFound(class_basename($modelClass) . ' with id : ' . $data['id']);
195
            }
196
197
            /**
198
             * Construct the model object with the given data,
199
             * and if there is a relation add it to relations array,
200
             * then save the model.
201
             */
202
            foreach ($data as $key => $value) 
203
            {
204
                /**
205
                 * If the attribute is a relation.
206
                 */
207
                $relation = camel_case($key);
208
                if (method_exists($model, $relation) && \Core::$relation())
209
                {
210
                    /**
211
                     * Check if the relation is a collection.
212
                     */
213
                    if (class_basename($model->$relation) == 'Collection') 
214
                    {   
215
                        /**
216
                         * If the relation has no value then marke the relation data 
217
                         * related to the model to be deleted.
218
                         */
219
                        if ( ! $value || ! count($value)) 
220
                        {
221
                            $relations[$relation] = 'delete';
222
                        }   
223
                    }
224
                    if (is_array($value)) 
225
                    {
226
                        /**
227
                         * Loop through the relation data.
228
                         */
229
                        foreach ($value as $attr => $val) 
230
                        {
231
                            /**
232
                             * Get the relation model.
233
                             */
234
                            $relationBaseModel = \Core::$relation()->model;
235
236
                            /**
237
                             * Check if the relation is a collection.
238
                             */
239
                            if (class_basename($model->$relation) == 'Collection')
240
                            {
241
                                /**
242
                                 * If the id is present in the data then select the relation model for updating,
243
                                 * else create new model.
244
                                 */
245
                                $relationModel = array_key_exists('id', $val) ? $relationBaseModel->lockForUpdate()->find($val['id']) : new $relationBaseModel;
246
247
                                /**
248
                                 * If model doesn't exists.
249
                                 */
250
                                if ( ! $relationModel) 
251
                                {
252
                                    \ErrorHandler::notFound(class_basename($relationBaseModel) . ' with id : ' . $val['id']);
253
                                }
254
255
                                /**
256
                                 * Loop through the relation attributes.
257
                                 */
258
                                foreach ($val as $attr => $val) 
259
                                {
260
                                    /**
261
                                     * Prevent the sub relations or attributes not in the fillable.
262
                                     */
263
                                    if (gettype($val) !== 'object' && gettype($val) !== 'array' &&  array_search($attr, $relationModel->getFillable(), true) !== false)
264
                                    {
265
                                        $relationModel->$attr = $val;
266
                                    }
267
                                }
268
269
                                $relations[$relation][] = $relationModel;
270
                            }
271
                            /**
272
                             * If not collection.
273
                             */
274
                            else
275
                            {
276
                                /**
277
                                 * Prevent the sub relations.
278
                                 */
279
                                if (gettype($val) !== 'object' && gettype($val) !== 'array') 
280
                                {
281
282
                                    /**
283
                                     * If the id is present in the data then select the relation model for updating,
284
                                     * else create new model.
285
                                     */
286
                                    $relationModel = array_key_exists('id', $value) ? $relationBaseModel->lockForUpdate()->find($value['id']) : new $relationBaseModel;
287
288
                                    /**
289
                                     * If model doesn't exists.
290
                                     */
291
                                    if ( ! $relationModel) 
292
                                    {
293
                                        \ErrorHandler::notFound(class_basename($relationBaseModel) . ' with id : ' . $value['id']);
294
                                    }
295
296
                                    foreach ($value as $relationAttribute => $relationValue) 
297
                                    {
298
                                        /**
299
                                         * Prevent attributes not in the fillable.
300
                                         */
301
                                        if (array_search($relationAttribute, $relationModel->getFillable(), true) !== false) 
302
                                        {
303
                                            $relationModel->$relationAttribute = $relationValue;
304
                                        }
305
                                    }
306
307
                                    $relations[$relation] = $relationModel;
308
                                }
309
                            }
310
                        }
311
                    }
312
                }
313
                /**
314
                 * If the attribute isn't a relation and prevent attributes not in the fillable.
315
                 */
316
                else if (array_search($key, $model->getFillable(), true) !== false)
317
                {
318
                    $model->$key = $value;   
319
                }
320
            }
321
            /**
322
             * Save the model.
323
             */
324
            $model->save();
325
326
            /**
327
             * Loop through the relations array.
328
             */
329
            foreach ($relations as $key => $value) 
330
            {
331
                /**
332
                 * If the relation is marked for delete then delete it.
333
                 */
334
                if ($value == 'delete' && $model->$key()->count())
335
                {
336
                    $model->$key()->delete();
337
                }
338
                /**
339
                 * If the relation is an array.
340
                 */
341
                else if (gettype($value) == 'array') 
342
                {
343
                    $ids = [];
344
                    /**
345
                     * Loop through the relations.
346
                     */
347
                    foreach ($value as $val) 
348
                    {
349
                        switch (class_basename($model->$key())) 
350
                        {
351
                            /**
352
                             * If the relation is one to many then update it's foreign key with
353
                             * the model id and save it then add its id to ids array to delete all 
354
                             * relations who's id isn't in the ids array.
355
                             */
356 View Code Duplication
                            case 'HasMany':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
357
                                $foreignKeyName       = explode('.', $model->$key()->getForeignKey())[1];
358
                                $val->$foreignKeyName = $model->id;
359
                                $val->save();
360
                                $ids[] = $val->id;
361
                                break;
362
363
                            /**
364
                             * If the relation is many to many then add it's id to the ids array to
365
                             * attache these ids to the model.
366
                             */
367
                            case 'BelongsToMany':
368
                                $val->save();
369
                                $ids[] = $val->id;
370
                                break;
371
                        }
372
                    }
373
                    switch (class_basename($model->$key())) 
374
                    {
375
                        /**
376
                         * If the relation is one to many then delete all 
377
                         * relations who's id isn't in the ids array.
378
                         */
379
                        case 'HasMany':
380
                            $model->$key()->whereNotIn('id', $ids)->delete();
381
                            break;
382
383
                        /**
384
                         * If the relation is many to many then 
385
                         * detach the previous data and attach 
386
                         * the ids array to the model.
387
                         */
388
                        case 'BelongsToMany':
389
                            $model->$key()->detach();
390
                            $model->$key()->attach($ids);
391
                            break;
392
                    }
393
                }
394
                /**
395
                 * If the relation isn't array.
396
                 */
397
                else
398
                {
399
                    switch (class_basename($model->$key())) 
400
                    {
401
                        /**
402
                         * If the relation is one to many or one to one.
403
                         */
404 View Code Duplication
                        case 'HasOne':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
405
406
                            $foreignKeyName         = explode('.', $model->$key()->getForeignKey())[1];
407
                            $value->$foreignKeyName = $model->id;
408
                            $value->save();
409
                            break;
410
                    }
411
                }
412
            }
413
414
            $saveLog ? \Logging::saveLog(array_key_exists('id', $data) ? 'update' : 'create', class_basename($modelClass), $this->getModel(), $model->id, $model) : false;
415
        });
416
    }
417
    
418
    /**
419
     * Update record in the storage based on the given
420
     * condition.
421
     * 
422
     * @param  [type] $value condition value
0 ignored issues
show
Documentation introduced by
The doc-type [type] could not be parsed: Unknown type name "" at position 0. [(view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
423
     * @param  array $data
424
     * @param  string $attribute condition column name
425
     * @return void
426
     */
427
    public function update($value, array $data, $attribute = 'id', $saveLog = true)
428
    {
429
        if ($attribute == 'id') 
430
        {
431
            $model = $this->model->lockForUpdate()->find($value);
432
            $model ? $model->update($data) : 0;
433
            $saveLog ? \Logging::saveLog('update', class_basename($this->model), $this->getModel(), $value, $model) : false;
434
        }
435 View Code Duplication
        else
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
436
        {
437
            call_user_func_array("{$this->getModel()}::where", array($attribute, '=', $value))->lockForUpdate()->get()->each(function ($model) use ($data, $saveLog){
438
                $model->update($data);
439
                $saveLog ? \Logging::saveLog('update', class_basename($this->model), $this->getModel(), $model->id, $model) : false;
440
            });
441
        }
442
    }
443
444
    /**
445
     * Delete record from the storage based on the given
446
     * condition.
447
     * 
448
     * @param  var $value condition value
449
     * @param  string $attribute condition column name
450
     * @return void
451
     */
452
    public function delete($value, $attribute = 'id', $saveLog = true)
453
    {
454
        if ($attribute == 'id') 
455
        {
456
            \DB::transaction(function () use ($value, $attribute, &$result, $saveLog) {
457
                $model = $this->model->lockForUpdate()->find($value);
458
                if ( ! $model) 
459
                {
460
                    \ErrorHandler::notFound(class_basename($this->model) . ' with id : ' . $value);
461
                }
462
                
463
                $model->delete();
464
                $saveLog ? \Logging::saveLog('delete', class_basename($this->model), $this->getModel(), $value, $model) : false;
465
            });
466
        }
467 View Code Duplication
        else
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
468
        {
469
            \DB::transaction(function () use ($value, $attribute, &$result, $saveLog) {
470
                call_user_func_array("{$this->getModel()}::where", array($attribute, '=', $value))->lockForUpdate()->get()->each(function ($model){
471
                    $model->delete();
472
                    $saveLog ? \Logging::saveLog('delete', class_basename($this->model), $this->getModel(), $model->id, $model) : false;
0 ignored issues
show
Bug introduced by
The variable $saveLog does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
473
                });
474
            });   
475
        }
476
    }
477
    
478
    /**
479
     * Fetch records from the storage based on the given
480
     * id.
481
     * 
482
     * @param  integer $id
483
     * @param  array   $relations
484
     * @param  array   $columns
485
     * @return object
486
     */
487
    public function find($id, $relations = [], $columns = array('*'))
488
    {
489
        return call_user_func_array("{$this->getModel()}::with", array($relations))->find($id, $columns);
490
    }
491
    
492
    /**
493
     * Fetch records from the storage based on the given
494
     * condition.
495
     * 
496
     * @param  array   $conditions array of conditions
497
     * @param  array   $relations
498
     * @param  string  $sortBy
499
     * @param  boolean $desc
500
     * @param  array   $columns
501
     * @return collection
502
     */
503
    public function findBy($conditions, $relations = [], $sortBy = 'created_at', $desc = 1, $columns = array('*'))
504
    {
505
        $conditions = $this->constructConditions($conditions);
506
        $sort       = $desc ? 'desc' : 'asc';
507
        return call_user_func_array("{$this->getModel()}::with",  array($relations))->whereRaw($conditions['conditionString'], $conditions['conditionValues'])->orderBy($sortBy, $sort)->get($columns);
508
    }
509
510
    /**
511
     * Fetch the first record from the storage based on the given
512
     * condition.
513
     *
514
     * @param  array   $conditions array of conditions
515
     * @param  array   $relations
516
     * @param  array   $columns
517
     * @return object
518
     */
519
    public function first($conditions, $relations = [], $columns = array('*'))
520
    {
521
        $conditions = $this->constructConditions($conditions);
522
        return call_user_func_array("{$this->getModel()}::with", array($relations))->whereRaw($conditions['conditionString'], $conditions['conditionValues'])->first($columns);  
523
    }
524
525
    /**
526
     * Return the deleted models in pages based on the given conditions.
527
     * 
528
     * @param  array   $conditions array of conditions
529
     * @param  integer $perPage
530
     * @param  string  $sortBy
531
     * @param  boolean $desc
532
     * @param  array   $columns
533
     * @return collection
534
     */
535
    public function deleted($conditions, $perPage = 15, $sortBy = 'created_at', $desc = 1, $columns = array('*'))
536
    {
537
        unset($conditions['page']);
538
        $conditions = $this->constructConditions($conditions);
539
        $sort       = $desc ? 'desc' : 'asc';
540
        $model      = $this->model->onlyTrashed();
541
542
        if (count($conditions['conditionValues']))
543
        {
544
            $model->whereRaw($conditions['conditionString'], $conditions['conditionValues']);
545
        }
546
547
        return $model->orderBy($sortBy, $sort)->paginate($perPage, $columns);;
548
    }
549
550
    /**
551
     * Restore the deleted model.
552
     * 
553
     * @param  integer $id
554
     * @param  string  $attribute condition column name
0 ignored issues
show
Bug introduced by
There is no parameter named $attribute. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
555
     * @return void
556
     */
557
    public function restore($id)
558
    {
559
        $model = $this->model->onlyTrashed()->find($id);
560
561
        if ( ! $model) 
562
        {
563
            \ErrorHandler::notFound(class_basename($this->model) . ' with id : ' . $id);
564
        }
565
566
        $model->restore();
567
    }
568
569
    /**
570
     * Build the conditions recursively for the retrieving methods.
571
     * @param  array $conditions
572
     * @return array
573
     */
574
    protected function constructConditions($conditions)
575
    {   
576
        $conditionString = '';
577
        $conditionValues = [];
578
        foreach ($conditions as $key => $value) 
579
        {
580
            if ($key == 'and') 
581
            {
582
                $conditionString  .= str_replace('{op}', 'and', $this->constructConditions($value)['conditionString']) . ' {op} ';
583
                $conditionValues   = array_merge($conditionValues, $this->constructConditions($value)['conditionValues']);
584
            }
585
            else if ($key == 'or')
586
            {
587
                $conditionString  .= str_replace('{op}', 'or', $this->constructConditions($value)['conditionString']) . ' {op} ';
588
                $conditionValues   = array_merge($conditionValues, $this->constructConditions($value)['conditionValues']);
589
            }
590
            else
591
            {
592
                if (is_array($value)) 
593
                {
594
                    $operator = $value['op'];
595
                    if (strtolower($operator) == 'between') 
596
                    {
597
                        $value1 = $value['val1'];
598
                        $value2 = $value['val2'];
599
                    }
600
                    else
601
                    {
602
                        $value = $value['val'];
603
                    }
604
                }
605
                else
606
                {
607
                    $operator = '=';
608
                }
609
                
610
                if (strtolower($operator) == 'between') 
611
                {
612
                    $conditionString  .= $key . ' >= ? and ';
613
                    $conditionValues[] = $value1;
0 ignored issues
show
Bug introduced by
The variable $value1 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...
614
615
                    $conditionString  .= $key . ' <= ? {op} ';
616
                    $conditionValues[] = $value2;
0 ignored issues
show
Bug introduced by
The variable $value2 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...
617
                }
618
                else
619
                {
620
                    $conditionString  .= $key . ' ' . $operator . ' ? {op} ';
621
                    $conditionValues[] = $value;
622
                }
623
            }
624
        }
625
        $conditionString = '(' . rtrim($conditionString, '{op} ') . ')';
626
        return ['conditionString' => $conditionString, 'conditionValues' => $conditionValues];
627
    }
628
629
    /**
630
     * Abstract method that return the necessary 
631
     * information (full model namespace)
632
     * needed to preform the previous actions.
633
     * 
634
     * @return string
635
     */
636
    abstract protected function getModel();
637
}