Passed
Push — master ( eebb3c...073ade )
by Murilo
01:53
created

Products::validatePagination()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
c 0
b 0
f 0
dl 0
loc 8
rs 10
cc 3
nc 2
nop 1
1
<?php
2
3
namespace Source\Controllers;
4
5
use stdClass;
6
use Source\Core\Request;
7
use Source\Core\Response;
8
use Source\Models\Product;
9
use Source\Models\ProductImage;
10
use Source\Models\Category;
11
12
class Products
13
{
14
    /**
15
     * @var \stdClass $Message
16
     */
17
    private $Message;
18
19
    /**
20
     * @var Request $Request
21
     */
22
    private $Request;
23
24
    /**
25
     * @var array $validExtensions
26
     */
27
    private $validExtensions = [
28
        'image/jpeg',
29
        'image/jpg',
30
        'image/png'
31
    ];
32
33
    /**
34
     * Products model constructor...
35
     */
36
    public function __construct()
37
    {
38
        $this->Message = new stdClass();
39
        $this->Request = new Request();
40
    }
41
42
    /**
43
     * GET the list of all products
44
     *
45
     * @param array|null $data Receive the current page and limit of then
46
     * @return void
47
     */
48
    public function products($data): void
49
    {
50
        $Product = new Product();
51
52
        $data = filter_var_array($data, FILTER_SANITIZE_STRIPPED);
0 ignored issues
show
Bug introduced by
It seems like $data can also be of type null; however, parameter $array of filter_var_array() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

52
        $data = filter_var_array(/** @scrutinizer ignore-type */ $data, FILTER_SANITIZE_STRIPPED);
Loading history...
53
54
        $this->allProductsWithoutFilters($data);
55
        $this->validatePagination($data);
56
57
        $page = filter_var($data['page'], FILTER_VALIDATE_INT);
58
        $limit = filter_var($data['limit'], FILTER_VALIDATE_INT);
59
60
        $this->validateOrderAndDirection($data);
61
62
        if (is_null(($products = $Product->findAll($limit, ($page * $limit) - $limit)))) {
63
            (new Response())->setStatusCode(HTTP_NO_CONTENT)->send($this->Message);
64
        }
65
66
        $this->Message->message = $products;
67
        $this->Message->count = $Product->coluntAllAvailableProducts();
68
69
        (new Response())->setStatusCode(HTTP_OK)->send($this->Message);
70
    }
71
72
    /**
73
     * GET one single product
74
     *
75
     * @param array $data
76
     * @return void
77
     */
78
    public function product($data)
79
    {
80
        $data = filter_var_array($data, FILTER_SANITIZE_STRIPPED);
81
82
        $id = $this->validateSingleProductId($data);
83
84
        $Product = new Product();
85
86
        if (is_null(($product = $Product->findByProductId($id)))) {
87
            (new Response())->setStatusCode(HTTP_NO_CONTENT)->send($this->Message);
88
        }
89
90
        $this->Message->message = $product->data();
91
92
        (new Response())->setStatusCode(HTTP_OK)->send($this->Message);
93
    }
94
95
    /**
96
     * POST insert a new product
97
     *
98
     * @param array $data
99
     * @return void
100
     */
101
    public function addProduct($data)
102
    {
103
        (new Auth())->validateLogin();
104
105
        $Product = new Product();
106
107
        foreach ($Product->getRequired() as $required) {
108
            if (!isset($data[$required])) {
109
                $this->Message->message = "parâmetro '{$required}' é requerido";
110
                (new Response())->setStatusCode(HTTP_BAD_REQUEST)->send($this->Message);
111
                return;
112
            }
113
        }
114
115
        $data = filter_var_array($data, FILTER_SANITIZE_STRIPPED);
116
117
        $name = filter_var(trim($data["name"]), FILTER_SANITIZE_FULL_SPECIAL_CHARS);
0 ignored issues
show
Bug introduced by
The constant Source\Controllers\FILTE...TIZE_FULL_SPECIAL_CHARS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
118
        $value = filter_var($data["value"], FILTER_VALIDATE_FLOAT);
119
        $description = filter_var(trim($data["description"]), FILTER_SANITIZE_FULL_SPECIAL_CHARS);
120
        $available = filter_var($data["available"], FILTER_VALIDATE_INT);
121
        $product_type_id = filter_var($data["product_type_id"], FILTER_VALIDATE_INT);
122
123
        if (!$value || !$available || !$product_type_id || empty($name) || empty($description)) {
124
            $this->Message->message = 'parâmetro inválido';
125
            (new Response())->setStatusCode(HTTP_BAD_REQUEST)->send($this->Message);
126
        }
127
128
        $Category = new Category();
129
130
        if (is_null($Category->findById($product_type_id, 'id'))) {
131
            $this->Message->message = 'esta categoria não existe';
132
            (new Response())->setStatusCode(HTTP_BAD_REQUEST)->send($this->Message);
133
        }
134
135
        $Product = new Product();
136
137
        /** Criar produto */
138
        $Product->name = $name;
139
        $Product->value = $value;
140
        $Product->description = $description;
141
        $Product->available = $available;
142
        $Product->product_type_id = $product_type_id;
143
144
        if (!$Product->save()) {
145
            $this->Message->message = $Product->message();
146
            (new Response())->setStatusCode(HTTP_OK)->send($this->Message);
147
        }
148
149
        $this->Message->message = 'Produto adicionado com sucesso';
150
        (new Response())->setStatusCode(HTTP_OK)->send($this->Message);
151
    }
152
153
    /**
154
     * POST insert a new product image to one product
155
     *
156
     * @param array $data
157
     * @return void
158
     */
159
    public function addProductImage($data)
160
    {
161
        (new Auth())->validateLogin();
162
163
        $data = filter_var_array($data, FILTER_SANITIZE_STRIPPED);
164
165
        $Product = $this->validateProductId($data);
166
167
        $ProductImage = new ProductImage();
168
        $imageName = md5(date('Y-m-dH:i:s', time()));
169
170
        $base64Image = $this->validateImageUpload($data);
171
172
        error_log($Product->id);
173
        error_log($imageName);
174
        // error_log($base64Image);
175
176
        $ProductImage->product_id = $Product->id;
177
        $ProductImage->url_slug = $imageName;
178
        $ProductImage->image = $base64Image;
179
180
        if (!$ProductImage->save()) {
181
            $this->Message->message = $ProductImage->message();
182
            (new Response())->setStatusCode(HTTP_OK)->send($this->Message);
183
        }
184
185
        $this->Message->message = 'Imagem adicionada com sucesso';
186
        (new Response())->setStatusCode(HTTP_OK)->send($this->Message);
187
    }
188
189
    /**
190
     * DELETE delete one product image by id
191
     *
192
     * @param array $data
193
     * @return void
194
     */
195
    public function deleteProductImage($data)
196
    {
197
        (new Auth())->validateLogin();
198
199
        $data = filter_var_array($data, FILTER_SANITIZE_STRIPPED);
200
201
        $ProductImage = new ProductImage();
202
203
        if (!isset($data['id']) || !filter_var($data['id'], FILTER_VALIDATE_INT)) {
204
            $this->Message->message = 'ID da imagem invalida';
205
            (new Response())->setStatusCode(HTTP_BAD_REQUEST)->send($this->Message);
206
        }
207
208
        $id = (int) $data['id'];
209
210
        if (is_null($ProductImage->findById($id, 'id'))) {
211
            $this->Message->message = 'Imagem nao encontrada';
212
            (new Response())->setStatusCode(HTTP_BAD_REQUEST)->send($this->Message);
213
        }
214
215
        if (!$ProductImage->delete('id', $id)) {
216
            $this->Message->message = $ProductImage->message();
217
            (new Response())->setStatusCode(HTTP_OK)->send($this->Message);
218
        }
219
220
        (new Response())->setStatusCode(HTTP_OK)->send($this->Message);
221
    }
222
223
    public function alterProduct($data)
224
    {
225
        (new Auth())->validateLogin();
226
227
        $Product = new Product();
228
229
        $data = filter_var_array($data, FILTER_SANITIZE_STRIPPED);
230
231
        $id = $this->validateSingleProductId($data);
232
233
        if (is_null(($Product = $Product->findById($id, '*')))) {
234
            $this->Message->message = 'este produto não foi encontrado';
235
            (new Response())->setStatusCode(HTTP_BAD_REQUEST)->send($this->Message);
236
        }
237
238
        $productData = &$Product->data();
239
240
        $fields = [
241
            'name' => FILTER_SANITIZE_FULL_SPECIAL_CHARS,
0 ignored issues
show
Bug introduced by
The constant Source\Controllers\FILTE...TIZE_FULL_SPECIAL_CHARS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
242
            'value' => FILTER_VALIDATE_FLOAT,
243
            'description' => FILTER_SANITIZE_FULL_SPECIAL_CHARS,
244
            'available' => FILTER_VALIDATE_INT
245
        ];
246
247
        foreach ($fields as $key => $filter) {
248
            if (!isset($data[$key])) {
249
                continue;
250
            }
251
252
            $$key = filter_var(trim($data[$key]), $filter);
253
254
            if (!$$key) {
255
                $this->Message->message = "Parâmetro {$key} inválido!";
256
                (new Response())->setStatusCode(HTTP_BAD_REQUEST)->send($this->Message);
257
            }
258
259
            $productData->$key = $$key;
260
        }
261
262
        if (isset($data["product_type_id"])) {
263
            $product_type_id = filter_var($data["product_type_id"], FILTER_VALIDATE_INT);
264
265
            if (!$product_type_id) {
266
                $this->Message->message = 'parâmetro inválido';
267
                (new Response())->setStatusCode(HTTP_BAD_REQUEST)->send($this->Message);
268
            }
269
270
            $Category = new Category();
271
272
            if (is_null($Category->findById($product_type_id, 'id'))) {
273
                $this->Message->message = 'esta categoria não existe';
274
                (new Response())->setStatusCode(HTTP_BAD_REQUEST)->send($this->Message);
275
            }
276
277
            $productData->product_type_id = $product_type_id;
278
        }
279
280
        if (!$Product->save()) {
281
            $this->Message->message = $Product->message();
282
            (new Response())->setStatusCode(HTTP_OK)->send($this->Message);
283
        }
284
285
        $this->Message->message = 'Produto atualizado com sucesso';
286
        (new Response())->setStatusCode(HTTP_OK)->send($this->Message);
287
    }
288
289
    private function validateSingleProductId($data)
290
    {
291
        if (empty($data['id'])) {
292
            $this->Message->message = 'ID do produto inválido';
293
            (new Response())->setStatusCode(HTTP_BAD_REQUEST)->send($this->Message);
294
        }
295
    
296
        $id = filter_var($data['id'], FILTER_VALIDATE_INT);
297
298
        if (!$id) {
299
            $this->Message->message = 'parâmetro inválido';
300
            (new Response())->setStatusCode(HTTP_BAD_REQUEST)->send($this->Message);
301
        }
302
303
        return $id;
304
    }
305
306
    private function validateProductId($data)
307
    {
308
        if (!isset($data['id'])) {
309
            $this->Message->message = 'Id do produto inválido!';
310
            (new Response())->setStatusCode(HTTP_BAD_REQUEST)->send($this->Message);
311
        }
312
313
        $id = filter_var($data["id"], FILTER_VALIDATE_INT);
314
315
        if (!$id) {
316
            $this->Message->message = 'Id do produto inválido!';
317
            (new Response())->setStatusCode(HTTP_BAD_REQUEST)->send($this->Message);
318
        }
319
320
        $Product = new Product();
321
        $Product = $Product->findById($id, 'id');
322
        
323
        if (is_null($Product)) {
324
            $this->Message->message = 'Produto não encontrado!';
325
            (new Response())->setStatusCode(HTTP_BAD_REQUEST)->send($this->Message);
326
        }
327
328
        return $Product;
329
    }
330
331
    private function allProductsWithoutFilters($data)
332
    {
333
        if (!empty($data)) {
334
            return; 
335
        }
336
337
        if (is_null(($products = $Product->findAll()))) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $Product seems to be never defined.
Loading history...
338
            (new Response())->setStatusCode(HTTP_NO_CONTENT)->send($this->Message);
339
        }
340
341
        $this->Message->message = $products;
342
        (new Response())->setStatusCode(HTTP_OK)->send($this->Message);
343
    }
344
345
    private function validatePagination($data)
346
    {
347
        if (!isset($data['page']) || !isset($data['limit'])) {
348
            $this->Message->message = [
349
                'message' => 'Missing page or limit argument'
350
            ];
351
352
            (new Response())->setStatusCode(HTTP_BAD_REQUEST)->send($this->Message);
353
        }
354
    }
355
356
    private function validateOrderAndDirection($data)
357
    {
358
        if (!isset($data['order']) || !isset($data['direction'])) {
359
            return;
360
        }
361
362
        $page = filter_var($data['page'], FILTER_VALIDATE_INT);
363
        $limit = filter_var($data['limit'], FILTER_VALIDATE_INT);
364
365
        $find = $this->validateSearchFilters($data);
366
367
        $find = $find->order($data['order'] . ' ' . $data['direction']);
368
        $find = $find->limit($limit);
369
        $find = $find->offset(($page * $limit) - $limit);
370
        $products = $find->fetch(true);
371
372
        if (empty($products)) {
373
            (new Response())->setStatusCode(HTTP_NO_CONTENT)->send($this->Message);
374
        }
375
376
        foreach ($products as $key => $value) {
377
            $products[$key] = $value->data();
378
379
            $products[$key]->category = (new Category())->findById((int) $products[$key]->product_type_id)->data();
380
            $products[$key]->ProductImage = (new ProductImage())->findAllByProductId((int) $products[$key]->id);
381
        }
382
383
        $this->Message->message = $products;
384
        (new Response())->setStatusCode(HTTP_OK)->send($this->Message);
385
    }
386
387
    private function validateSearchFilters($data)
388
    {
389
        $Product = new Product();
390
391
        if (empty($data['filterColumn'])) {
392
            return $Product->find();
393
        }
394
        
395
        if (empty($data['selfId'])) {
396
            return $Product->find("{$data['filterColumn']} = {$data['filterValue']}");
397
        }
398
399
        return $Product->find("{$data['filterColumn']} = {$data['filterValue']} AND id != {$data['selfId']}");
400
    }
401
402
    private function validateImageUpload($data)
403
    {
404
        if (empty($data['image'])) {
405
            $this->Message->message = 'imagem nao encontrada';
406
            (new Response())->setStatusCode(HTTP_BAD_REQUEST)->send($this->Message);
407
        }
408
409
        $base64Image = $data['image'];
410
411
        try {
412
            $base64 = getimagesizefromstring(base64_decode(explode(',', $base64Image)[1]));
413
        } catch (\Exception $e) {
414
            $this->Message->message = 'imagem invalida';
415
            (new Response())->setStatusCode(HTTP_BAD_REQUEST)->send($this->Message);
416
        }
417
418
        if (!$base64) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $base64 of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
419
            $this->Message->message = 'imagem invalida';
420
            (new Response())->setStatusCode(HTTP_BAD_REQUEST)->send($this->Message);
421
        }
422
423
        if (!empty($base64[0]) && !empty($base64[0]) && !empty($base64['mime'])) {
424
            if (!in_array($base64['mime'], $this->validExtensions)) {
425
                $this->Message->message = 'tipo de imagem invalida';
426
                (new Response())->setStatusCode(HTTP_BAD_REQUEST)->send($this->Message);
427
            }
428
        }
429
430
        return $base64Image;
431
    }
432
}
433