Traversify   B
last analyzed

Complexity

Total Complexity 46

Size/Duplication

Total Lines 259
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 113
c 1
b 0
f 0
dl 0
loc 259
rs 8.72
wmc 46

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __getters() 0 4 3
A __queryOrder() 0 20 6
A loader() 0 5 2
B __queryRange() 0 50 8
C __queryFilter() 0 53 12
A traverse() 0 17 4
A traversify() 0 5 1
A __queryBuilder() 0 9 3
A __queryCustom() 0 5 2
A __querySearch() 0 18 5

How to fix   Complexity   

Complex Class

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

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

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

1
<?php
2
3
namespace Traversify;
4
5
trait Traversify
6
{
7
    public      $search;    # Search keyword (String)
8
9
    public      $filter;    # Query filters (Array)
10
11
    public      $custom;     # Custom queries
12
13
    public      $take;      # For limited show (Integer)
14
15
    public      $order;     # Order of list (Array)
16
17
    public      $range;     # Range of query (Array)
18
19
    public      $limit;     # Limit show - Paginate Prerequesit ()
20
21
    public      $expose;    # Returns all data (Uses get instead of paginate)
22
    
23
    public      $debug;     # For testing;
24
25
    private     $query;     # Query builder
26
27
28
    public static function traversify($custom = NULL)
29
    {
30
        $_traverse = new self;
31
32
        return $_traverse->traverse($custom);
33
    }
34
35
36
    public function traverse($custom = NULL)
37
    {
38
        $custom && $this->custom = $custom;
39
    
40
        $this->__getters();
41
42
        \DB::enableQueryLog();
0 ignored issues
show
Bug introduced by
The type DB was not found. Maybe you did not declare it correctly or list all dependencies?

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

filter:
    dependency_paths: ["lib/*"]

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

Loading history...
43
44
        $result = $this->__queryBuilder();
45
46
        if($this->debug && env('APP_DEBUG')):
0 ignored issues
show
Bug introduced by
The function env was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

46
        if($this->debug && /** @scrutinizer ignore-call */ env('APP_DEBUG')):
Loading history...
47
48
            return \DB::getQueryLog();
49
50
        else:
51
52
            return $result;
53
54
        endif;
55
    }
56
57
    private function __queryBuilder()
58
    {
59
        $this->query = $this->query();
0 ignored issues
show
Bug introduced by
It seems like query() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

59
        /** @scrutinizer ignore-call */ 
60
        $this->query = $this->query();
Loading history...
60
        
61
        $queries = ['Search','Filter','Range', 'Order', 'Custom'];
62
63
        self::loader($queries,'__query');
0 ignored issues
show
Bug Best Practice introduced by
The method Traversify\Traversify::loader() is not static, but was called statically. ( Ignorable by Annotation )

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

63
        self::/** @scrutinizer ignore-call */ 
64
              loader($queries,'__query');
Loading history...
64
       
65
        return ($this->expose || $this->take) ? ['data' => $this->query->take($this->take)->get()] : $this->query->paginate($this->limit);
66
    }
67
68
    private function __queryCustom()
69
    {
70
        if(!isset($this->custom)) return;
71
72
        $this->query->where($this->custom);
73
    }
74
75
    private function __querySearch()
76
    {
77
        if(!isset(self::$searchables)) return;
0 ignored issues
show
Bug introduced by
The property searchables does not exist on Traversify\Traversify. Did you mean search?
Loading history...
78
79
        $this->query->where( function($query)
80
        {
81
            foreach(self::$searchables ?: [] as $searchable):
0 ignored issues
show
Bug introduced by
The property searchables does not exist on Traversify\Traversify. Did you mean search?
Loading history...
82
                
83
                $_searchable = explode('~',$searchable);
84
85
                if(count($_searchable)>1):
86
                    
87
                    $query->with($_searchable[0])->orWhereHas($_searchable[0], function($query) use ( $_searchable )
88
                      {
89
                          $query->where($_searchable[1],'LIKE','%'.$this->search.'%');    
90
                      });
91
                  else:
92
                      $query->orWhere($searchable,'LIKE','%'.$this->search.'%');     
93
                  endif;
94
95
            endforeach;
96
        });
97
    }
98
99
    private function __queryFilter()
100
    {
101
        if(!isset(self::$filterables)) return;
0 ignored issues
show
Bug introduced by
The property filterables does not exist on Traversify\Traversify. Did you mean filter?
Loading history...
102
        
103
        $this->query->where(function($query)
104
        {
105
            foreach($this->filter ?: [] as $attribute => $value):
106
107
                $value == 'null' && $value = null;
108
109
                if(in_array($attribute, self::$filterables)):
0 ignored issues
show
Bug introduced by
The property filterables does not exist on Traversify\Traversify. Did you mean filter?
Loading history...
110
111
                    $relationship = explode('~', $attribute);
112
113
                    if(count($relationship) == 2):
114
115
                        if($value[0]=='!'):
116
117
                            $values = explode(',',substr($value,1));
118
119
                            $value == 'null' && $value = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $value is dead and can be removed.
Loading history...
120
121
                            $query->with($relationship[0])->whereHas($relationship[0],function($query) use ( $relationship, $values)
122
                            {
123
                                $query->whereNotIn($relationship[1],$values);                                    
124
                            });
125
126
                        else:
127
                
128
                            $values = explode(',',$value);
129
130
                            $query->with($relationship[0])->whereHas($relationship[0],function($query) use ( $relationship, $values, $value)
131
                            {
132
                                count($values) > 1 ? $query->whereIn($relationship[1],$values) : $query->where($relationship[1],$value);                            
133
                            });
134
                            
135
                        endif;
136
137
                    else:
138
                        if($value[0]=='!'):
139
140
                            $values = explode(',',substr($value,1));
141
        
142
                            $query->where(function($query) use ($attribute, $values)
143
                            {
144
                                $query->whereNotIn($attribute,$values);
145
                            });
146
                            
147
                        else:
148
                
149
                            $values = explode(',',$value);
150
                            
151
                            count($values) > 1 ? $query->whereIn($attribute,$values) : $query->where($attribute,$value);
152
    
153
                        endif;
154
155
                    endif;
156
157
                endif;
158
    
159
            endforeach;
160
        });
161
    }
162
163
    private function __queryRange()
164
    {
165
        if(!isset(self::$rangables)) return;
0 ignored issues
show
Bug introduced by
The property rangables does not exist on Traversify\Traversify. Did you mean range?
Loading history...
166
167
        $this->query->where(function($query)
168
        {
169
            foreach($this->range ?: [] as $attribute => $value):
170
171
                if(in_array($attribute, self::$rangables)):
0 ignored issues
show
Bug introduced by
The property rangables does not exist on Traversify\Traversify. Did you mean range?
Loading history...
172
173
                    $relationship = explode('~', $attribute);
174
175
                    if(count($relationship) == 2):
176
177
                        if($value[0]=='!'):
178
179
                            $values = explode(',',substr($value,1));
180
181
                            $query->with($relationship[0])->whereHas($relationship[0],function($query) use ( $relationship, $values)
182
                            {
183
                                $query->whereNotBetween($relationship[1],$values);                                    
184
                            });
185
186
                        else:
187
                
188
                            $values = explode(',',$value);
189
190
                            $query->with($relationship[0])->whereHas($relationship[0],function($query) use ( $relationship, $values, $value)
0 ignored issues
show
Unused Code introduced by
The import $value is not used and could be removed.

This check looks for imports that have been defined, but are not used in the scope.

Loading history...
191
                            {
192
                               $query->whereBetween($relationship[1],$values);                            
193
                            });
194
                            
195
                        endif;
196
197
                    else:
198
199
                        if($value[0]=='!'):
200
201
                            $values = explode(',',substr($value,1));
202
        
203
                            $query->where(function($q) use ($attribute, $values)
204
                            {
205
                                $q->whereNotBetween($attribute,$values);
206
                            });
207
                            
208
                        else:
209
210
                            $values = explode(',',$value);
211
        
212
                            $query->whereBetween($attribute,$values);
213
        
214
                        endif;
215
216
                    endif;
217
218
                endif;
219
220
            endforeach;
221
        });
222
    }
223
224
    private function __queryOrder()
225
    {
226
        if(!isset(self::$orderables)) return;
0 ignored issues
show
Bug introduced by
The property orderables does not exist on Traversify\Traversify. Did you mean order?
Loading history...
227
228
        foreach($this->order ?: [] as $attribute => $value):
229
230
            if(in_array($attribute, self::$orderables)):
231
                
232
                $relationship = explode('~', $attribute);
233
234
                if(count($relationship) == 2):
235
                   
236
                    $this->query->with([$relationship[0] => function($query) use ( $relationship, $value)
237
                    {
238
                        $query->orderBy($relationship[1],$value); 
239
                    }]);
240
241
                else:
242
243
                    $this->query->orderBy($attribute, $value);
244
245
                endif;
246
                
247
            endif;
248
249
        endforeach;
250
    }
251
252
    private function __getters ( $getters = ['search', 'filter', 'take', 'order', 'range', 'limit', 'expose', 'debug'] )
253
    {
254
        foreach($getters as $getter):
255
            !$this->$getter && $this->$getter = request()->get($getter);
0 ignored issues
show
Bug introduced by
The function request was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

255
            !$this->$getter && $this->$getter = /** @scrutinizer ignore-call */ request()->get($getter);
Loading history...
256
        endforeach;
257
    }
258
259
    private function loader($loads, $prefix = '__')
260
    {
261
        foreach($loads as $load):
262
            
263
            self::{$prefix.$load}();
264
265
        endforeach;
266
    }
267
}