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

ProductAction::create()   B

Complexity

Conditions 5
Paths 7

Size

Total Lines 72
Code Lines 45

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 45
c 1
b 0
f 0
nc 7
nop 1
dl 0
loc 72
rs 8.8888

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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