Completed
Push — master ( 9ecb5e...97e3cb )
by Sherif
13:30
created

AbstractRepository::find()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 3
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
                $column = 'LOWER(' . array_shift($conditionColumns) . ')';
71
                if (str_contains($column, '->')) 
72
                {
73
                    $column = $this->wrapJsonSelector($column);
74
                }
75
76
                /**
77
                 * Use the first element in the model columns to construct the first condition.
78
                 */
79
                $q->where(\DB::raw($column), 'LIKE', '%' . strtolower($query) . '%');
80
            }
81
82
            /**
83
             * Loop through the rest of the columns to construct or where conditions.
84
             */
85 View Code Duplication
            foreach ($conditionColumns as $column) 
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...
86
            {
87
                $column = 'LOWER(' . $column . ')';
88
                if (str_contains($column, '->')) 
89
                {
90
                    $column = $this->wrapJsonSelector($column);
91
                }
92
93
                $q->orWhere(\DB::raw($column), 'LIKE', '%' . strtolower($query) . '%');
94
            }
95
96
            /**
97
             * Loop through the model relations.
98
             */
99
            foreach ($relations as $relation) 
100
            {
101
                /**
102
                 * Remove the sub relation if exists.
103
                 */
104
                $relation = explode('.', $relation)[0];
105
106
                /**
107
                 * Try to fetch the relation repository from the core.
108
                 */
109
                if (\Core::$relation()) 
110
                {
111
                    /**
112
                     * Construct the relation condition.
113
                     */
114
                    $q->orWhereHas($relation, function ($subModel) use ($query, $relation){
115
116
                        $subModel->where(function ($q) use ($query, $relation){
117
118
                            /**
119
                             * Get columns of the relation.
120
                             */
121
                            $subConditionColumns = \Core::$relation()->model->searchable;
122
123 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...
124
                            {
125
126
                                $column = 'LOWER(' . array_shift($subConditionColumns) . ')';
127
                                if (str_contains($column, '->')) 
128
                                {
129
                                    $column = $this->wrapJsonSelector($column);
130
                                }
131
132
                                /**
133
                                * Use the first element in the relation model columns to construct the first condition.
134
                                 */
135
                                $q->where(\DB::raw($column), 'LIKE', '%' . strtolower($query) . '%');
136
                            }
137
138
                            /**
139
                             * Loop through the rest of the columns to construct or where conditions.
140
                             */
141 View Code Duplication
                            foreach ($subConditionColumns as $subConditionColumn)
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...
142
                            {
143
                                $column = 'LOWER(' . $subConditionColumn . ')';
144
                                if (str_contains($column, '->')) 
145
                                {
146
                                    $column = $this->wrapJsonSelector($column);
147
                                }
148
                                
149
                                $q->orWhere(\DB::raw($column), 'LIKE', '%' . strtolower($query) . '%');
150
                            } 
151
                        });
152
153
                    });
154
                }
155
            }
156
        });
157
        
158
        return $model->orderBy($sortBy, $sort)->paginate($perPage, $columns);
159
    }
160
    
161
    /**
162
     * Fetch all records with relations from storage in pages.
163
     * 
164
     * @param  integer $perPage
165
     * @param  array   $relations
166
     * @param  string  $sortBy
167
     * @param  boolean $desc
168
     * @param  array   $columns
169
     * @return collection
170
     */
171
    public function paginate($perPage = 15, $relations = [], $sortBy = 'created_at', $desc = 1, $columns = array('*'))
172
    {
173
        $sort = $desc ? 'desc' : 'asc';
174
        return call_user_func_array("{$this->getModel()}::with", array($relations))->orderBy($sortBy, $sort)->paginate($perPage, $columns);
175
    }
176
177
    /**
178
     * Fetch all records with relations based on
179
     * the given condition from storage in pages.
180
     * 
181
     * @param  array   $conditions array of conditions
182
     * @param  integer $perPage
183
     * @param  array   $relations
184
     * @param  string  $sortBy
185
     * @param  boolean $desc
186
     * @param  array   $columns
187
     * @return collection
188
     */
189
    public function paginateBy($conditions, $perPage = 15, $relations = [], $sortBy = 'created_at', $desc = 1, $columns = array('*'))
190
    {
191
        unset($conditions['page']);
192
        $conditions = $this->constructConditions($conditions, $this->model);
193
        $sort       = $desc ? 'desc' : 'asc';
194
        return call_user_func_array("{$this->getModel()}::with", array($relations))->whereRaw($conditions['conditionString'], $conditions['conditionValues'])->orderBy($sortBy, $sort)->paginate($perPage, $columns);
195
    }
196
    
197
    /**
198
     * Save the given model to the storage.
199
     * 
200
     * @param  array   $data
201
     * @return void
202
     */
203
    public function save(array $data)
204
    {
205
        $model      = false;
206
        $modelClass = $this->model;
207
        $relations  = [];
208
209
        \DB::transaction(function () use (&$model, &$relations, $data, $modelClass) {
210
            /**
211
             * If the id is present in the data then select the model for updating,
212
             * else create new model.
213
             * @var array
214
             */
215
            $model = array_key_exists('id', $data) ? $modelClass->lockForUpdate()->find($data['id']) : new $modelClass;
216
            if ( ! $model) 
217
            {
218
                \ErrorHandler::notFound(class_basename($modelClass) . ' with id : ' . $data['id']);
219
            }
220
221
            /**
222
             * Construct the model object with the given data,
223
             * and if there is a relation add it to relations array,
224
             * then save the model.
225
             */
226
            foreach ($data as $key => $value) 
227
            {
228
                /**
229
                 * If the attribute is a relation.
230
                 */
231
                $relation = camel_case($key);
232
                if (method_exists($model, $relation) && \Core::$relation())
233
                {
234
                    /**
235
                     * Check if the relation is a collection.
236
                     */
237
                    if (class_basename($model->$relation) == 'Collection') 
238
                    {   
239
                        /**
240
                         * If the relation has no value then marke the relation data 
241
                         * related to the model to be deleted.
242
                         */
243
                        if ( ! $value || ! count($value)) 
244
                        {
245
                            $relations[$relation] = 'delete';
246
                        }   
247
                    }
248
                    if (is_array($value)) 
249
                    {
250
                        /**
251
                         * Loop through the relation data.
252
                         */
253
                        foreach ($value as $attr => $val) 
254
                        {
255
                            /**
256
                             * Get the relation model.
257
                             */
258
                            $relationBaseModel = \Core::$relation()->model;
259
260
                            /**
261
                             * Check if the relation is a collection.
262
                             */
263
                            if (class_basename($model->$relation) == 'Collection')
264
                            {
265
                                /**
266
                                 * If the id is present in the data then select the relation model for updating,
267
                                 * else create new model.
268
                                 */
269
                                $relationModel = array_key_exists('id', $val) ? $relationBaseModel->lockForUpdate()->find($val['id']) : new $relationBaseModel;
270
271
                                /**
272
                                 * If model doesn't exists.
273
                                 */
274
                                if ( ! $relationModel) 
275
                                {
276
                                    \ErrorHandler::notFound(class_basename($relationBaseModel) . ' with id : ' . $val['id']);
277
                                }
278
279
                                /**
280
                                 * Loop through the relation attributes.
281
                                 */
282
                                foreach ($val as $attr => $val) 
283
                                {
284
                                    /**
285
                                     * Prevent the sub relations or attributes not in the fillable.
286
                                     */
287
                                    if (gettype($val) !== 'object' && gettype($val) !== 'array' &&  array_search($attr, $relationModel->getFillable(), true) !== false)
288
                                    {
289
                                        $relationModel->$attr = $val;
290
                                    }
291
                                }
292
293
                                $relations[$relation][] = $relationModel;
294
                            }
295
                            /**
296
                             * If not collection.
297
                             */
298
                            else
299
                            {
300
                                /**
301
                                 * Prevent the sub relations.
302
                                 */
303
                                if (gettype($val) !== 'object' && gettype($val) !== 'array') 
304
                                {
305
306
                                    /**
307
                                     * If the id is present in the data then select the relation model for updating,
308
                                     * else create new model.
309
                                     */
310
                                    $relationModel = array_key_exists('id', $value) ? $relationBaseModel->lockForUpdate()->find($value['id']) : new $relationBaseModel;
311
312
                                    /**
313
                                     * If model doesn't exists.
314
                                     */
315
                                    if ( ! $relationModel) 
316
                                    {
317
                                        \ErrorHandler::notFound(class_basename($relationBaseModel) . ' with id : ' . $value['id']);
318
                                    }
319
320
                                    foreach ($value as $relationAttribute => $relationValue) 
321
                                    {
322
                                        /**
323
                                         * Prevent attributes not in the fillable.
324
                                         */
325
                                        if (array_search($relationAttribute, $relationModel->getFillable(), true) !== false) 
326
                                        {
327
                                            $relationModel->$relationAttribute = $relationValue;
328
                                        }
329
                                    }
330
331
                                    $relations[$relation] = $relationModel;
332
                                }
333
                            }
334
                        }
335
                    }
336
                }
337
                /**
338
                 * If the attribute isn't a relation and prevent attributes not in the fillable.
339
                 */
340
                else if (array_search($key, $model->getFillable(), true) !== false)
341
                {
342
                    $model->$key = $value;   
343
                }
344
            }
345
            /**
346
             * Save the model.
347
             */
348
            $model->save();
349
350
            /**
351
             * Loop through the relations array.
352
             */
353
            foreach ($relations as $key => $value) 
354
            {
355
                /**
356
                 * If the relation is marked for delete then delete it.
357
                 */
358
                if ($value == 'delete' && $model->$key()->count())
359
                {
360
                    $model->$key()->delete();
361
                }
362
                /**
363
                 * If the relation is an array.
364
                 */
365
                else if (gettype($value) == 'array') 
366
                {
367
                    $ids = [];
368
                    /**
369
                     * Loop through the relations.
370
                     */
371
                    foreach ($value as $val) 
372
                    {
373
                        switch (class_basename($model->$key())) 
374
                        {
375
                            /**
376
                             * If the relation is one to many then update it's foreign key with
377
                             * the model id and save it then add its id to ids array to delete all 
378
                             * relations who's id isn't in the ids array.
379
                             */
380
                            case 'HasMany':
381
                                $foreignKeyName       = $model->$key()->getForeignKeyName();
382
                                $val->$foreignKeyName = $model->id;
383
                                $val->save();
384
                                $ids[] = $val->id;
385
                                break;
386
387
                            /**
388
                             * If the relation is many to many then add it's id to the ids array to
389
                             * attache these ids to the model.
390
                             */
391
                            case 'BelongsToMany':
392
                                $val->save();
393
                                $ids[] = $val->id;
394
                                break;
395
                        }
396
                    }
397
                    switch (class_basename($model->$key())) 
398
                    {
399
                        /**
400
                         * If the relation is one to many then delete all 
401
                         * relations who's id isn't in the ids array.
402
                         */
403
                        case 'HasMany':
404
                            $model->$key()->whereNotIn('id', $ids)->delete();
405
                            break;
406
407
                        /**
408
                         * If the relation is many to many then 
409
                         * detach the previous data and attach 
410
                         * the ids array to the model.
411
                         */
412
                        case 'BelongsToMany':
413
                            $model->$key()->detach();
414
                            $model->$key()->attach($ids);
415
                            break;
416
                    }
417
                }
418
                /**
419
                 * If the relation isn't array.
420
                 */
421
                else
422
                {
423
                    switch (class_basename($model->$key())) 
424
                    {
425
                        /**
426
                         * If the relation is one to many or one to one.
427
                         */
428
                        case 'HasOne':
429
                            $foreignKeyName         = $model->$key()->getForeignKeyName();
430
                            $value->$foreignKeyName = $model->id;
431
                            $value->save();
432
                            break;
433
                    }
434
                }
435
            }
436
        });
437
            
438
        return $model->id;
439
    }
440
    
441
    /**
442
     * Update record in the storage based on the given
443
     * condition.
444
     * 
445
     * @param  var $value condition value
446
     * @param  array $data
447
     * @param  string $attribute condition column name
448
     * @return void
449
     */
450
    public function update($value, array $data, $attribute = 'id')
451
    {
452
        if ($attribute == 'id') 
453
        {
454
            $model = $this->model->lockForUpdate()->find($value);
455
            $model ? $model->update($data) : 0;
456
        }
457
        else
458
        {
459
            call_user_func_array("{$this->getModel()}::where", array($attribute, '=', $value))->lockForUpdate()->get()->each(function ($model) use ($data){
460
                $model->update($data);
461
            });
462
        }
463
    }
464
465
    /**
466
     * Delete record from the storage based on the given
467
     * condition.
468
     * 
469
     * @param  var $value condition value
470
     * @param  string $attribute condition column name
471
     * @return void
472
     */
473
    public function delete($value, $attribute = 'id')
474
    {
475
        if ($attribute == 'id') 
476
        {
477
            \DB::transaction(function () use ($value, $attribute, &$result) {
478
                $model = $this->model->lockForUpdate()->find($value);
479
                if ( ! $model) 
480
                {
481
                    \ErrorHandler::notFound(class_basename($this->model) . ' with id : ' . $value);
482
                }
483
                
484
                $model->delete();
485
            });
486
        }
487
        else
488
        {
489
            \DB::transaction(function () use ($value, $attribute, &$result) {
490
                call_user_func_array("{$this->getModel()}::where", array($attribute, '=', $value))->lockForUpdate()->get()->each(function ($model){
491
                    $model->delete();
492
                });
493
            });   
494
        }
495
    }
496
    
497
    /**
498
     * Fetch records from the storage based on the given
499
     * id.
500
     * 
501
     * @param  integer $id
502
     * @param  array   $relations
503
     * @param  array   $columns
504
     * @return object
505
     */
506
    public function find($id, $relations = [], $columns = array('*'))
507
    {
508
        return call_user_func_array("{$this->getModel()}::with", array($relations))->find($id, $columns);
509
    }
510
    
511
    /**
512
     * Fetch records from the storage based on the given
513
     * condition.
514
     * 
515
     * @param  array   $conditions array of conditions
516
     * @param  array   $relations
517
     * @param  string  $sortBy
518
     * @param  boolean $desc
519
     * @param  array   $columns
520
     * @return collection
521
     */
522
    public function findBy($conditions, $relations = [], $sortBy = 'created_at', $desc = 1, $columns = array('*'))
523
    {
524
        $conditions = $this->constructConditions($conditions, $this->model);
525
        $sort       = $desc ? 'desc' : 'asc';
526
        return call_user_func_array("{$this->getModel()}::with",  array($relations))->whereRaw($conditions['conditionString'], $conditions['conditionValues'])->orderBy($sortBy, $sort)->get($columns);
527
    }
528
529
    /**
530
     * Fetch the first record from the storage based on the given
531
     * condition.
532
     *
533
     * @param  array   $conditions array of conditions
534
     * @param  array   $relations
535
     * @param  array   $columns
536
     * @return object
537
     */
538
    public function first($conditions, $relations = [], $columns = array('*'))
539
    {
540
        $conditions = $this->constructConditions($conditions, $this->model);
541
        return call_user_func_array("{$this->getModel()}::with", array($relations))->whereRaw($conditions['conditionString'], $conditions['conditionValues'])->first($columns);  
542
    }
543
544
    /**
545
     * Return the deleted models in pages based on the given conditions.
546
     * 
547
     * @param  array   $conditions array of conditions
548
     * @param  integer $perPage
549
     * @param  string  $sortBy
550
     * @param  boolean $desc
551
     * @param  array   $columns
552
     * @return collection
553
     */
554
    public function deleted($conditions, $perPage = 15, $sortBy = 'created_at', $desc = 1, $columns = array('*'))
555
    {
556
        unset($conditions['page']);
557
        $conditions = $this->constructConditions($conditions, $this->model);
558
        $sort       = $desc ? 'desc' : 'asc';
559
        $model      = $this->model->onlyTrashed();
560
561
        if (count($conditions['conditionValues']))
562
        {
563
            $model->whereRaw($conditions['conditionString'], $conditions['conditionValues']);
564
        }
565
566
        return $model->orderBy($sortBy, $sort)->paginate($perPage, $columns);;
567
    }
568
569
    /**
570
     * Restore the deleted model.
571
     * 
572
     * @param  integer $id
573
     * @return void
574
     */
575
    public function restore($id)
576
    {
577
        $model = $this->model->onlyTrashed()->find($id);
578
579
        if ( ! $model) 
580
        {
581
            \ErrorHandler::notFound(class_basename($this->model) . ' with id : ' . $id);
582
        }
583
584
        $model->restore();
585
    }
586
587
    /**
588
     * Build the conditions recursively for the retrieving methods.
589
     * @param  array $conditions
590
     * @return array
591
     */
592
    protected function constructConditions($conditions, $model)
593
    {   
594
        $conditionString = '';
595
        $conditionValues = [];
596
        foreach ($conditions as $key => $value) 
597
        {
598
            if (str_contains($key, '->')) 
599
            {
600
                $key = $this->wrapJsonSelector($key);
601
            }
602
603
            if ($key == 'and') 
604
            {
605
                $conditions       = $this->constructConditions($value, $model);
606
                $conditionString .= str_replace('{op}', 'and', $conditions['conditionString']) . ' {op} ';
607
                $conditionValues  = array_merge($conditionValues, $conditions['conditionValues']);
608
            }
609
            else if ($key == 'or')
610
            {
611
                $conditions       = $this->constructConditions($value, $model);
612
                $conditionString .= str_replace('{op}', 'or', $conditions['conditionString']) . ' {op} ';
613
                $conditionValues  = array_merge($conditionValues, $conditions['conditionValues']);
614
            }
615
            else
616
            {
617
                if (is_array($value)) 
618
                {
619
                    $operator = $value['op'];
620
                    if (strtolower($operator) == 'between') 
621
                    {
622
                        $value1 = $value['val1'];
623
                        $value2 = $value['val2'];
624
                    }
625
                    else
626
                    {
627
                        $value = array_key_exists('val', $value) ? $value['val'] : '';
628
                    }
629
                }
630
                else
631
                {
632
                    $operator = '=';
633
                }
634
                
635
                if (strtolower($operator) == 'between') 
636
                {
637
                    $conditionString  .= $key . ' >= ? and ';
638
                    $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...
639
640
                    $conditionString  .= $key . ' <= ? {op} ';
641
                    $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...
642
                }
643
                elseif (strtolower($operator) == 'in') 
644
                {
645
                    $conditionValues  = array_merge($conditionValues, $value);
646
                    $inBindingsString = rtrim(str_repeat('?,', count($value)), ',');
647
                    $conditionString .= $key . ' in (' . rtrim($inBindingsString, ',') . ') {op} ';
648
                }
649
                elseif (strtolower($operator) == 'null') 
650
                {
651
                    $conditionString .= $key . ' is null {op} ';
652
                }
653
                elseif (strtolower($operator) == 'not null') 
654
                {
655
                    $conditionString .= $key . ' is not null {op} ';
656
                }
657
                elseif (strtolower($operator) == 'has') 
658
                {
659
                    $sql              = $model->withTrashed()->has($key)->toSql();
660
                    $conditions       = $this->constructConditions($value, $model->$key()->getRelated());
661
                    $conditionString .= rtrim(substr($sql, strpos($sql, 'exists')), ')') . ' and ' . $conditions['conditionString'] . ') {op} ';
662
                    $conditionValues  = array_merge($conditionValues, $conditions['conditionValues']);
663
                }
664
                else
665
                {
666
                    $conditionString  .= $key . ' ' . $operator . ' ? {op} ';
667
                    $conditionValues[] = $value;
668
                }
669
            }
670
        }
671
        $conditionString = '(' . rtrim($conditionString, '{op} ') . ')';
672
        return ['conditionString' => $conditionString, 'conditionValues' => $conditionValues];
673
    }
674
675
    /**
676
     * Wrap the given JSON selector.
677
     *
678
     * @param  string  $value
679
     * @return string
680
     */
681
    protected function wrapJsonSelector($value)
682
    {
683
        $removeLast = strpos($value, ')');
684
        $value      = $removeLast === false ? $value : substr($value, 0, $removeLast);
685
        $path       = explode('->', $value);
686
        $field      = array_shift($path);
687
        $result     = sprintf('%s->\'$.%s\'', $field, collect($path)->map(function ($part) {
688
            return '"'.$part.'"';
689
        })->implode('.'));
690
        
691
        return $removeLast === false ? $result : $result . ')';
692
    }
693
694
    /**
695
     * Abstract method that return the necessary 
696
     * information (full model namespace)
697
     * needed to preform the previous actions.
698
     * 
699
     * @return string
700
     */
701
    abstract protected function getModel();
702
}