Completed
Push — master ( a88a56...6eb92f )
by CodexShaper
11:55
created

QueryBuilderTrait   B

Complexity

Total Complexity 50

Size/Duplication

Total Lines 395
Duplicated Lines 18.73 %

Coupling/Cohesion

Components 1
Dependencies 0

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 50
lcom 1
cbo 0
dl 74
loc 395
rs 8.4
c 0
b 0
f 0
ccs 0
cts 111
cp 0

17 Methods

Rating   Name   Duplication   Size   Complexity  
A all() 0 13 3
A find() 0 12 3
A create() 0 12 3
A update() 12 12 3
A delete() 0 12 3
A batch() 12 12 3
A get() 12 12 3
A first() 0 13 3
A withOriginal() 8 8 1
A withCollection() 8 8 1
A withLazyCollection() 8 8 1
A options() 0 16 4
B where() 0 19 7
A orderBy() 0 7 1
B paginate() 0 46 6
A count() 0 11 2
A save() 14 14 3

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like QueryBuilderTrait 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. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

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 QueryBuilderTrait, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Codexshaper\WooCommerce\Traits;
4
5
use Codexshaper\WooCommerce\Facades\WooCommerce;
6
use Illuminate\Support\LazyCollection;
7
8
trait QueryBuilderTrait
9
{
10
    /**
11
     * @var
12
     */
13
    protected $options = [];
14
15
    /**
16
     * @var
17
     */
18
    protected $where = [];
19
20
    /**
21
     * @var
22
     */
23
    protected $properties = [];
24
25
    /**
26
     * @var
27
     */
28
    protected $isLazyCollection = false;
29
30
    /**
31
     * @var
32
     */
33
    protected $isCollection = true;
34
35
    /**
36
     * @var
37
     */
38
    protected $isOriginal = false;
39
40
    /**
41
     * Retrieve all Items.
42
     *
43
     * @param array $options
44
     *
45
     * @return array
46
     */
47
    protected function all($options = [])
48
    {
49
        if ($this->isLazyCollection) {
50
            return LazyCollection::make(WooCommerce::all($this->endpoint, $options));
0 ignored issues
show
Bug introduced by
The property endpoint does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
51
        }
52
53
        if ($this->isCollection) {
54
            return collect(WooCommerce::all($this->endpoint, $options));
55
        }
56
57
        return WooCommerce::all($this->endpoint, $options);
58
        
59
    }
60
61
    /**
62
     * Retrieve single Item.
63
     *
64
     * @param int   $id
65
     * @param array $options
66
     *
67
     * @return object
68
     */
69
    protected function find($id, $options = [])
70
    {
71
        if ($this->isLazyCollection) {
72
            return LazyCollection::make(WooCommerce::find("{$this->endpoint}/{$id}", $options));
73
        }
74
75
        if ($this->isCollection) {
76
            return collect(WooCommerce::find("{$this->endpoint}/{$id}", $options));
77
        }
78
79
        return WooCommerce::find("{$this->endpoint}/{$id}", $options);
80
    }
81
82
    /**
83
     * Create new Item.
84
     *
85
     * @param array $data
86
     *
87
     * @return object
88
     */
89
    protected function create($data)
90
    {
91
        if ($this->isLazyCollection) {
92
            return LazyCollection::make(WooCommerce::create($this->endpoint, $data));
93
        }
94
95
        if ($this->isCollection) {
96
            return collect(WooCommerce::create($this->endpoint, $data));
97
        }
98
99
        return WooCommerce::create($this->endpoint, $data);
100
    }
101
102
    /**
103
     * Update Existing Item.
104
     *
105
     * @param int   $id
106
     * @param array $data
107
     *
108
     * @return object
109
     */
110 View Code Duplication
    protected function update($id, $data)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
111
    {
112
        if ($this->isLazyCollection) {
113
            return LazyCollection::make(WooCommerce::update("{$this->endpoint}/{$id}", $data));
114
        }
115
116
        if ($this->isCollection) {
117
            return collect(WooCommerce::update("{$this->endpoint}/{$id}", $data));
118
        }
119
120
        return WooCommerce::update("{$this->endpoint}/{$id}", $data);
121
    }
122
123
    /**
124
     * Destroy Item.
125
     *
126
     * @param int   $id
127
     * @param array $options
128
     *
129
     * @return object
130
     */
131
    protected function delete($id, $options = [])
132
    {
133
        if ($this->isLazyCollection) {
134
            return LazyCollection::make(WooCommerce::delete("{$this->endpoint}/{$id}", $options));
135
        }
136
137
        if ($this->isCollection) {
138
            return collect(WooCommerce::delete("{$this->endpoint}/{$id}", $options));
139
        }
140
141
        return WooCommerce::delete("{$this->endpoint}/{$id}", $options);
142
    }
143
144
    /**
145
     * Batch Update.
146
     *
147
     * @param array $data
148
     *
149
     * @return object
150
     */
151 View Code Duplication
    protected function batch($data)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
152
    {
153
        if ($this->isLazyCollection) {
154
            return LazyCollection::make(WooCommerce::create("{$this->endpoint}/batch", $data));
155
        }
156
157
        if ($this->isCollection) {
158
            return collect(WooCommerce::create("{$this->endpoint}/batch", $data));
159
        }
160
161
        return WooCommerce::create("{$this->endpoint}/batch", $data);
162
    }
163
164
    /**
165
     * Retrieve data.
166
     *
167
     * @return array
168
     */
169 View Code Duplication
    protected function get()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
170
    {
171
        if ($this->isLazyCollection) {
172
            return LazyCollection::make(WooCommerce::all($this->endpoint, $this->options));
173
        }
174
175
        if ($this->isCollection) {
176
            return collect(WooCommerce::all($this->endpoint, $this->options));
177
        }
178
179
        return WooCommerce::all($this->endpoint, $this->options);
180
    }
181
182
    /**
183
     * Retrieve data.
184
     *
185
     * @return object
186
     */
187
    protected function first()
188
    {
189
190
        if ($this->isLazyCollection) {
191
            return LazyCollection::make($this->get()[0] ?? new \stdClass());
192
        }
193
194
        if ($this->isCollection) {
195
            return collect($this->get()[0] ?? new \stdClass());
196
        }
197
198
        return collect($this->get()[0] ?? new \stdClass());
199
    }
200
201
    /**
202
     * Set original.
203
     *
204
     * @return object $this
205
     */
206 View Code Duplication
    protected function withOriginal()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
207
    {
208
        $this->isOriginal = true;
209
        $this->isCollection = false;
210
        $this->isLazyCollection = false;
211
212
        return $this;
213
    }
214
215
    /**
216
     * Set collection.
217
     *
218
     * @return object $this
219
     */
220 View Code Duplication
    protected function withCollection()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
221
    {
222
        $this->isOriginal = false;
223
        $this->isCollection = true;
224
        $this->isLazyCollection = false;
225
226
        return $this;
227
    }
228
229
    /**
230
     * Set lazy collection.
231
     *
232
     * @return object $this
233
     */
234 View Code Duplication
    protected function withLazyCollection()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
235
    {
236
        $this->isOriginal = false;
237
        $this->isCollection = false;
238
        $this->isLazyCollection = true;
239
240
        return $this;
241
    }
242
243
    /**
244
     * Set options for woocommerce request.
245
     *
246
     * @param array $parameters
247
     *
248
     * @return object $this
249
     */
250
    protected function options($parameters)
251
    {
252
        if (!is_array($parameters)) {
253
            throw new \Exception('Options must be an array', 1);
254
        }
255
256
        if (empty($parameters)) {
257
            throw new \Exception('Options must be pass at least one element', 1);
258
        }
259
260
        foreach ($parameters as $key => $value) {
261
            $this->options[$key] = $value;
262
        }
263
264
        return $this;
265
    }
266
267
    /**
268
     * Join options for woocommerce request.
269
     *
270
     * @param array $parameters
271
     *
272
     * @return object $this
273
     */
274
    protected function where(...$parameters)
275
    {
276
        if (count($parameters) < 2 || count($parameters) > 3) {
277
            throw new \Exception('You can pass minimum 2 and maximum 3 paramneters');
278
        }
279
        $field = strtolower($parameters[0]);
280
        $value = count($parameters) == 3 ? $parameters[2] : $parameters[1];
281
282
        switch ($field) {
283
            case 'name': case 'title': case 'description':
284
                $this->options['search'] = $value;
285
                break;
286
            default:
287
                $this->options[$field] = $value;
288
                break;
289
        }
290
291
        return $this;
292
    }
293
294
    /**
295
     * Set order direction.
296
     *
297
     * @param string $name
298
     * @param string $direction
299
     *
300
     * @return object $this
301
     */
302
    protected function orderBy($name, $direction = 'desc')
303
    {
304
        $this->options['orderby'] = $name;
305
        $this->options['order'] = $direction;
306
307
        return $this;
308
    }
309
310
    /**
311
     * Paginate results.
312
     *
313
     * @param int $per_page
314
     * @param int $current_page
315
     * @param array $options
316
     *
317
     * @return array
318
     */
319
    protected function paginate($per_page = 10, $current_page = 1, $options = [])
320
    {
321
        try {
322
            $this->options['per_page'] = (int) $per_page;
323
324
            if ($current_page > 0) {
325
                $this->options['page'] = (int) $current_page;
326
            }
327
328
            foreach ($options as $option => $value) {
329
                $this->options[$option] = $value;
330
            }
331
332
            $results = $this->get();
333
            $totalResults = WooCommerce::countResults();
334
            $totalPages = WooCommerce::countPages();
335
            $currentPage = WooCommerce::current();
336
            $previousPage = WooCommerce::previous();
337
            $nextPage = WooCommerce::next();
338
339
            $pagination = [
340
                'total_results' => $totalResults,
341
                'total_pages'   => $totalPages,
342
                'current_page'  => $currentPage,
343
                'previous_page' => $previousPage,
344
                'next_page'     => $nextPage,
345
                'first_page'    => 1,
346
                'last_page'     => $totalResults,
347
            ];
348
349
            $results['pagination'] = $pagination;
350
351
            if ($this->isLazyCollection) {
352
                return LazyCollection::make($results);
353
            }
354
355
            if ($this->isCollection) {
356
                return collect($results);
357
            }
358
359
            return $results;
360
361
        } catch (\Exception $ex) {
362
            throw new \Exception($ex->getMessage(), 1);
363
        }
364
    }
365
366
    /**
367
     * Count all results.
368
     *
369
     * @return int
370
     */
371
    protected function count()
372
    {
373
        try {
374
            $results = WooCommerce::all($this->endpoint, $this->options);
0 ignored issues
show
Unused Code introduced by
$results is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
375
            $totalResults = WooCommerce::countResults();
376
377
            return $totalResults;
378
        } catch (\Exception $ex) {
379
            throw new \Exception($ex->getMessage(), 1);
380
        }
381
    }
382
383
    /**
384
     * Store data.
385
     *
386
     * @return array
387
     */
388 View Code Duplication
    public function save()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
389
    {
390
        $this->results = WooCommerce::create($this->endpoint, $this->properties);
0 ignored issues
show
Bug introduced by
The property results does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
391
392
        if ($this->isLazyCollection) {
393
            return LazyCollection::make($this->results);
394
        }
395
396
        if ($this->isCollection) {
397
            return collect($this->results);
398
        }
399
400
        return $this->results;
401
    }
402
}
403