RequestCriteria::setCrossSearchClosure()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 20
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
cc 1
eloc 17
c 2
b 1
f 0
nc 1
nop 0
dl 0
loc 20
rs 9.7
1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: guoliang
5
 * Date: 2019/3/11
6
 * Time: 上午10:11.
7
 */
8
9
namespace Modules\Core\Criteria;
10
11
use Closure;
12
use Illuminate\Database\Eloquent\Builder;
13
use Illuminate\Http\Request;
14
use Modules\Core\Traits\Criteria\ParseFilterTrait;
15
use Modules\Core\Traits\Criteria\ParseOrderByTrait;
16
use Modules\Core\Traits\Criteria\ParseSearchableTrait;
17
use Modules\Core\Traits\Criteria\ParseWithTrait;
18
use Prettus\Repository\Contracts\CriteriaInterface;
19
use Prettus\Repository\Contracts\RepositoryInterface;
20
21
class RequestCriteria implements CriteriaInterface
22
{
23
    /** @var \Illuminate\Http\Request $request */
24
    protected $request;
25
    /** @var \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|\Illuminate\Database\Query\Builder $model */
26
    protected $model;
27
    /** @var \Prettus\Repository\Contracts\RepositoryInterface $repository */
28
    protected $repository;
29
    protected $search;
30
    protected $searchData;
31
    protected $searchFields;
32
    protected $isFirstField;
33
    protected $modelForceAndWhere;
34
    protected $fieldsSearchable;
35
    protected $fields;
36
    protected $filter;
37
    protected $orderBy;
38
    protected $sortedBy;
39
    protected $with;
40
    protected $searchJoin;
41
    protected $acceptedConditions;
42
    protected $originalFields;
43
    protected $searchClosures;
44
45
    use ParseSearchableTrait;
46
    use ParseOrderByTrait;
47
    use ParseFilterTrait;
48
    use ParseWithTrait;
49
50
    public function __construct(Request $request)
51
    {
52
        $this->request = $request;
53
        $this->isFirstField = true;
54
55
        $this->setCrossSearchClosure();
56
        $this->setBetweenSearchClosure();
57
        $this->setInSearchClosure();
58
    }
59
60
    /**
61
     * @param \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|\Illuminate\Database\Query\Builder $model
62
     * @param \Prettus\Repository\Contracts\RepositoryInterface                                                            $repository
63
     *
64
     * @throws \Exception
65
     *
66
     * @return mixed
67
     */
68
    public function apply($model, RepositoryInterface $repository)
69
    {
70
        $this->model = $model;
71
        $this->repository = $repository;
72
73
        $this->parseSearchable();
74
        $this->parseOrderBy();
75
        $this->parseFilter();
76
        $this->parseWith();
77
78
        return $this->model;
79
    }
80
81
    public function setSearchClosure(string $condition, Closure $closure)
82
    {
83
        $this->searchClosures[$condition] = $closure;
84
    }
85
86
    protected function setCrossSearchClosure()
87
    {
88
        $crossMin = config('repository.criteria.cross.min', 'min');
89
        $crossMax = config('repository.criteria.cross.min', 'max');
90
91
        $this->setSearchClosure('cross', function (...$attributes) use ($crossMin, $crossMax) {
92
            return $attributes[0]->where(function (Builder $query) use ($attributes, $crossMin, $crossMax) {
93
                $query->where(function (Builder $query) use ($attributes, $crossMin, $crossMax) {
94
                    $query->where("{$attributes[2]}_{$crossMin}", '<=', (int) $attributes[3][0])
95
                        ->where("{$attributes[2]}_{$crossMax}", '>=', (int) $attributes[3][1]);
96
                })->orWhere(function (Builder $query) use ($attributes, $crossMin, $crossMax) {
97
                    $query->where("{$attributes[2]}_{$crossMin}", '<=', (int) $attributes[3][0])
98
                        ->where("{$attributes[2]}_{$crossMax}", '>=', (int) $attributes[3][0]);
99
                })->orWhere(function (Builder $query) use ($attributes, $crossMin, $crossMax) {
100
                    $query->where("{$attributes[2]}_{$crossMin}", '>=', (int) $attributes[3][0])
101
                        ->where("{$attributes[2]}_{$crossMax}", '<=', (int) $attributes[3][1]);
102
                })->orWhere(function (Builder $query) use ($attributes, $crossMin, $crossMax) {
103
                    $query->where("{$attributes[2]}_{$crossMin}", '>=', (int) $attributes[3][0])
104
                        ->where("{$attributes[2]}_{$crossMax}", '>=', (int) $attributes[3][1])
105
                        ->where("{$attributes[2]}_{$crossMin}", '<=', (int) $attributes[3][1]);
106
                });
107
            });
108
        });
109
    }
110
111
    protected function setBetweenSearchClosure()
112
    {
113
        $this->setSearchClosure('between', function (...$attributes) {
114
            return $attributes[0]->whereBetween($attributes[2], $attributes[3]);
115
        });
116
    }
117
118
    protected function setInSearchClosure()
119
    {
120
        $this->setSearchClosure('in', function (...$attributes) {
121
            return $attributes[0]->whereIn($attributes[2], $attributes[3]);
122
        });
123
    }
124
}
125