Passed
Pull Request — master (#9)
by nguereza
02:20
created

ProductAction::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 18
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 8
c 1
b 0
f 0
nc 1
nop 8
dl 0
loc 18
rs 10

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Platine\App\Http\Action\Product;
6
7
use Exception;
8
use Platine\Http\ResponseInterface;
9
use Platine\Http\ServerRequestInterface;
10
use Platine\Framework\Http\RequestData;
11
use Platine\Framework\Http\Response\TemplateResponse;
12
use Platine\Framework\Http\Response\RedirectResponse;
13
use Platine\Lang\Lang;
14
use Platine\Pagination\Pagination;
15
use Platine\Template\Template;
16
use Platine\Framework\Helper\Flash;
17
use Platine\Framework\Http\RouteHelper;
18
use Platine\Logger\LoggerInterface;
19
use Platine\App\Model\Repository\ProductCategoryRepository;
20
use Platine\App\Model\Repository\ProductRepository;
21
use Platine\App\Model\Entity\Product;
22
use Platine\App\Param\ProductParam;
23
use Platine\App\Validator\ProductValidator;
24
25
/**
26
* @class ProductAction
27
* @package Platine\App\Http\Action\Product
28
*/
29
class ProductAction
30
{
31
    /**
32
    * The Lang instance
33
    * @var Lang
34
    */
35
    protected Lang $lang;
36
37
    /**
38
    * The Pagination instance
39
    * @var Pagination
40
    */
41
    protected Pagination $pagination;
42
43
    /**
44
    * The Template instance
45
    * @var Template
46
    */
47
    protected Template $template;
48
49
    /**
50
    * The Flash instance
51
    * @var Flash
52
    */
53
    protected Flash $flash;
54
55
    /**
56
    * The RouteHelper instance
57
    * @var RouteHelper
58
    */
59
    protected RouteHelper $routeHelper;
60
61
    /**
62
    * The LoggerInterface instance
63
    * @var LoggerInterface
64
    */
65
    protected LoggerInterface $logger;
66
67
    /**
68
    * The ProductCategoryRepository instance
69
    * @var ProductCategoryRepository
70
    */
71
    protected ProductCategoryRepository $productCategoryRepository;
72
73
    /**
74
    * The ProductRepository instance
75
    * @var ProductRepository
76
    */
77
    protected ProductRepository $productRepository;
78
79
80
81
    /**
82
    * Create new instance
83
    * @param Lang $lang
84
    * @param Pagination $pagination
85
    * @param Template $template
86
    * @param Flash $flash
87
    * @param RouteHelper $routeHelper
88
    * @param LoggerInterface $logger
89
    * @param ProductCategoryRepository $productCategoryRepository
90
    * @param ProductRepository $productRepository
91
    */
92
    public function __construct(
93
        Lang $lang,
94
        Pagination $pagination,
95
        Template $template,
96
        Flash $flash,
97
        RouteHelper $routeHelper,
98
        LoggerInterface $logger,
99
        ProductCategoryRepository $productCategoryRepository,
100
        ProductRepository $productRepository
101
    ) {
102
        $this->lang = $lang;
103
        $this->pagination = $pagination;
104
        $this->template = $template;
105
        $this->flash = $flash;
106
        $this->routeHelper = $routeHelper;
107
        $this->logger = $logger;
108
        $this->productCategoryRepository = $productCategoryRepository;
109
        $this->productRepository = $productRepository;
110
    }
111
112
    /**
113
    * List all entities
114
    * @param ServerRequestInterface $request
115
    * @return ResponseInterface
116
    */
117
    public function index(ServerRequestInterface $request): ResponseInterface
118
    {
119
        $context = [];
120
        $param = new RequestData($request);
121
122
        $filters = [];
123
        $filtersParam = [
124
            'category',
125
        ];
126
127
        foreach ($filtersParam as $p) {
128
            $value = $param->get($p);
129
            if (strlen((string) $value) > 0) {
130
                $filters[$p] = $value;
131
            }
132
        }
133
134
        $totalItems = $this->productRepository->query()
135
                                              ->filter($filters)
136
                                               ->count('id');
137
138
        $currentPage = (int) $param->get('page', 1);
139
140
        $this->pagination->setTotalItems($totalItems)
141
                        ->setCurrentPage($currentPage);
142
143
        $limit = $this->pagination->getItemsPerPage();
144
        $offset = $this->pagination->getOffset();
145
146
        $results = $this->productRepository->query()
147
                                            ->with('category')
148
                                            ->filter($filters)
149
                                            ->offset($offset)
150
                                            ->limit($limit)
151
                                            ->orderBy('name', 'ASC')
152
                                            ->all();
153
154
        $categories = $this->productCategoryRepository->orderBy('name')
155
                                                      ->all();
156
157
        $context['categories'] = $categories;
158
159
        $context['filters'] = $filters;
160
        $context['list'] = $results;
161
        $context['pagination'] = $this->pagination->render();
162
163
164
        return new TemplateResponse(
165
            $this->template,
166
            'product/list',
167
            $context
168
        );
169
    }
170
171
    /**
172
    * List entity detail
173
    * @param ServerRequestInterface $request
174
    * @return ResponseInterface
175
    */
176
    public function detail(ServerRequestInterface $request): ResponseInterface
177
    {
178
        $context = [];
179
        $id = (int) $request->getAttribute('id');
180
181
        /** @var Product|null $product */
182
        $product = $this->productRepository->find($id);
183
184
        if ($product === null) {
185
            $this->flash->setError($this->lang->tr('This record doesn\'t exist'));
186
187
            return new RedirectResponse(
188
                $this->routeHelper->generateUrl('product_list')
189
            );
190
        }
191
        $context['product'] = $product;
192
193
        return new TemplateResponse(
194
            $this->template,
195
            'product/detail',
196
            $context
197
        );
198
    }
199
200
    /**
201
    * Create new entity
202
    * @param ServerRequestInterface $request
203
    * @return ResponseInterface
204
    */
205
    public function create(ServerRequestInterface $request): ResponseInterface
206
    {
207
        $context = [];
208
        $param = new RequestData($request);
209
210
        $formParam = new ProductParam($param->posts());
211
        $context['param'] = $formParam;
212
213
        $categories = $this->productCategoryRepository->orderBy('name')
214
                                                      ->all();
215
216
        $context['categories'] = $categories;
217
218
        if ($request->getMethod() === 'GET') {
219
            return new TemplateResponse(
220
                $this->template,
221
                'product/create',
222
                $context
223
            );
224
        }
225
226
        $validator = new ProductValidator($formParam, $this->lang);
227
        if ($validator->validate() === false) {
228
            $context['errors'] = $validator->getErrors();
229
230
            return new TemplateResponse(
231
                $this->template,
232
                'product/create',
233
                $context
234
            );
235
        }
236
237
        $entityExist = $this->productRepository->findBy([
238
                                               'name' => $formParam->getName(),
239
                                           ]);
240
241
        if ($entityExist !== null) {
242
            $this->flash->setError($this->lang->tr('This record already exist'));
243
244
            return new TemplateResponse(
245
                $this->template,
246
                'product/create',
247
                $context
248
            );
249
        }
250
251
        /** @var Product $product */
252
        $product = $this->productRepository->create([
253
           'name' => $formParam->getName(),
254
        'description' => $formParam->getDescription(),
255
        'price' => $formParam->getPrice(),
256
        'quantity' => $formParam->getQuantity(),
257
        'product_category_id' => $formParam->getCategory(),
258
        ]);
259
260
        try {
261
            $this->productRepository->save($product);
262
263
            $this->flash->setSuccess($this->lang->tr('Data successfully created'));
264
265
            return new RedirectResponse(
266
                $this->routeHelper->generateUrl('product_list')
267
            );
268
        } catch (Exception $ex) {
269
            $this->logger->error('Error when saved the data {error}', ['error' => $ex->getMessage()]);
270
271
            $this->flash->setError($this->lang->tr('Data processing error'));
272
273
            return new TemplateResponse(
274
                $this->template,
275
                'product/create',
276
                $context
277
            );
278
        }
279
    }
280
281
    /**
282
    * Update existing entity
283
    * @param ServerRequestInterface $request
284
    * @return ResponseInterface
285
    */
286
    public function update(ServerRequestInterface $request): ResponseInterface
287
    {
288
        $context = [];
289
        $param = new RequestData($request);
290
291
        $id = (int) $request->getAttribute('id');
292
293
        /** @var Product|null $product */
294
        $product = $this->productRepository->find($id);
295
296
        if ($product === null) {
297
            $this->flash->setError($this->lang->tr('This record doesn\'t exist'));
298
299
            return new RedirectResponse(
300
                $this->routeHelper->generateUrl('product_list')
301
            );
302
        }
303
        $context['product'] = $product;
304
        $context['param'] = (new ProductParam())->fromEntity($product);
305
306
        $categories = $this->productCategoryRepository->orderBy('name')
307
                                                      ->all();
308
309
        $context['categories'] = $categories;
310
311
        if ($request->getMethod() === 'GET') {
312
            return new TemplateResponse(
313
                $this->template,
314
                'product/update',
315
                $context
316
            );
317
        }
318
        $formParam = new ProductParam($param->posts());
319
        $context['param'] = $formParam;
320
321
        $validator = new ProductValidator($formParam, $this->lang);
322
        if ($validator->validate() === false) {
323
            $context['errors'] = $validator->getErrors();
324
325
            return new TemplateResponse(
326
                $this->template,
327
                'product/update',
328
                $context
329
            );
330
        }
331
332
        $entityExist = $this->productRepository->findBy([
333
                                               'name' => $formParam->getName(),
334
                                           ]);
335
336
        if ($entityExist !== null && $entityExist->id !== $id) {
337
            $this->flash->setError($this->lang->tr('This record already exist'));
338
339
            return new TemplateResponse(
340
                $this->template,
341
                'product/update',
342
                $context
343
            );
344
        }
345
346
        $product->name = $formParam->getName();
0 ignored issues
show
Bug Best Practice introduced by
The property name does not exist on Platine\App\Model\Entity\Product. Since you implemented __set, consider adding a @property annotation.
Loading history...
347
        $product->description = $formParam->getDescription();
0 ignored issues
show
Bug Best Practice introduced by
The property description does not exist on Platine\App\Model\Entity\Product. Since you implemented __set, consider adding a @property annotation.
Loading history...
348
        $product->price = $formParam->getPrice();
0 ignored issues
show
Bug Best Practice introduced by
The property price does not exist on Platine\App\Model\Entity\Product. Since you implemented __set, consider adding a @property annotation.
Loading history...
349
        $product->quantity = $formParam->getQuantity();
0 ignored issues
show
Bug Best Practice introduced by
The property quantity does not exist on Platine\App\Model\Entity\Product. Since you implemented __set, consider adding a @property annotation.
Loading history...
350
        $product->product_category_id = $formParam->getCategory();
0 ignored issues
show
Bug Best Practice introduced by
The property product_category_id does not exist on Platine\App\Model\Entity\Product. Since you implemented __set, consider adding a @property annotation.
Loading history...
351
352
        try {
353
            $this->productRepository->save($product);
354
355
            $this->flash->setSuccess($this->lang->tr('Data successfully updated'));
356
357
            return new RedirectResponse(
358
                $this->routeHelper->generateUrl('product_detail', ['id' => $id])
359
            );
360
        } catch (Exception $ex) {
361
            $this->logger->error('Error when saved the data {error}', ['error' => $ex->getMessage()]);
362
363
            $this->flash->setError($this->lang->tr('Data processing error'));
364
365
            return new TemplateResponse(
366
                $this->template,
367
                'product/update',
368
                $context
369
            );
370
        }
371
    }
372
373
    /**
374
    * Delete the entity
375
    * @param ServerRequestInterface $request
376
    * @return ResponseInterface
377
    */
378
    public function delete(ServerRequestInterface $request): ResponseInterface
379
    {
380
        $id = (int) $request->getAttribute('id');
381
382
        /** @var Product|null $product */
383
        $product = $this->productRepository->find($id);
384
385
        if ($product === null) {
386
            $this->flash->setError($this->lang->tr('This record doesn\'t exist'));
387
388
            return new RedirectResponse(
389
                $this->routeHelper->generateUrl('product_list')
390
            );
391
        }
392
393
        try {
394
            $this->productRepository->delete($product);
395
396
            $this->flash->setSuccess($this->lang->tr('Data successfully deleted'));
397
398
            return new RedirectResponse(
399
                $this->routeHelper->generateUrl('product_list')
400
            );
401
        } catch (Exception $ex) {
402
            $this->logger->error('Error when delete the data {error}', ['error' => $ex->getMessage()]);
403
404
            $this->flash->setError($this->lang->tr('Data processing error'));
405
406
            return new RedirectResponse(
407
                $this->routeHelper->generateUrl('product_list')
408
            );
409
        }
410
    }
411
}
412