ProductAction::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 0
c 1
b 0
f 0
nc 1
nop 8
dl 0
loc 10
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
    * Create new instance
33
    * @param Lang $lang
34
    * @param Pagination $pagination
35
    * @param Template $template
36
    * @param Flash $flash
37
    * @param RouteHelper $routeHelper
38
    * @param LoggerInterface $logger
39
    * @param ProductCategoryRepository $productCategoryRepository
40
    * @param ProductRepository $productRepository
41
    */
42
    public function __construct(
43
        protected Lang $lang,
44
        protected Pagination $pagination,
45
        protected Template $template,
46
        protected Flash $flash,
47
        protected RouteHelper $routeHelper,
48
        protected LoggerInterface $logger,
49
        protected ProductCategoryRepository $productCategoryRepository,
50
        protected ProductRepository $productRepository
51
    ) {
52
    }
53
54
    /**
55
    * List all entities
56
    * @param ServerRequestInterface $request
57
    * @return ResponseInterface
58
    */
59
    public function index(ServerRequestInterface $request): ResponseInterface
60
    {
61
        $context = [];
62
        $param = new RequestData($request);
63
64
        $filters = [];
65
        $filtersParam = [
66
            'category',
67
        ];
68
69
        foreach ($filtersParam as $p) {
70
            $value = $param->get($p);
71
            if (strlen((string) $value) > 0) {
72
                $filters[$p] = $value;
73
            }
74
        }
75
76
        $totalItems = $this->productRepository->query()
77
                                              ->filter($filters)
78
                                               ->count('id');
79
80
        $currentPage = (int) $param->get('page', 1);
81
82
        $this->pagination->setTotalItems($totalItems)
83
                        ->setCurrentPage($currentPage);
84
85
        $limit = $this->pagination->getItemsPerPage();
86
        $offset = $this->pagination->getOffset();
87
88
        $results = $this->productRepository->query()
89
                                            ->with('category')
90
                                            ->filter($filters)
91
                                            ->offset($offset)
92
                                            ->limit($limit)
93
                                            ->orderBy('name', 'ASC')
94
                                            ->all();
95
96
        $categories = $this->productCategoryRepository->orderBy('name')
97
                                                      ->all();
98
99
        $context['categories'] = $categories;
100
101
        $context['filters'] = $filters;
102
        $context['list'] = $results;
103
        $context['pagination'] = $this->pagination->render();
104
105
106
        return new TemplateResponse(
107
            $this->template,
108
            'product/list',
109
            $context
110
        );
111
    }
112
113
    /**
114
    * List entity detail
115
    * @param ServerRequestInterface $request
116
    * @return ResponseInterface
117
    */
118
    public function detail(ServerRequestInterface $request): ResponseInterface
119
    {
120
        $context = [];
121
        $id = (int) $request->getAttribute('id');
122
123
        /** @var Product|null $product */
124
        $product = $this->productRepository->find($id);
125
126
        if ($product === null) {
127
            $this->flash->setError($this->lang->tr('This record doesn\'t exist'));
128
129
            return new RedirectResponse(
130
                $this->routeHelper->generateUrl('product_list')
131
            );
132
        }
133
        $context['product'] = $product;
134
135
        return new TemplateResponse(
136
            $this->template,
137
            'product/detail',
138
            $context
139
        );
140
    }
141
142
    /**
143
    * Create new entity
144
    * @param ServerRequestInterface $request
145
    * @return ResponseInterface
146
    */
147
    public function create(ServerRequestInterface $request): ResponseInterface
148
    {
149
        $context = [];
150
        $param = new RequestData($request);
151
152
        $formParam = new ProductParam($param->posts());
153
        $context['param'] = $formParam;
154
155
        $categories = $this->productCategoryRepository->orderBy('name')
156
                                                      ->all();
157
158
        $context['categories'] = $categories;
159
160
        if ($request->getMethod() === 'GET') {
161
            return new TemplateResponse(
162
                $this->template,
163
                'product/create',
164
                $context
165
            );
166
        }
167
168
        $validator = new ProductValidator($formParam, $this->lang);
169
        if ($validator->validate() === false) {
170
            $context['errors'] = $validator->getErrors();
171
172
            return new TemplateResponse(
173
                $this->template,
174
                'product/create',
175
                $context
176
            );
177
        }
178
179
        $entityExist = $this->productRepository->findBy([
180
                                               'name' => $formParam->getName(),
181
                                           ]);
182
183
        if ($entityExist !== null) {
184
            $this->flash->setError($this->lang->tr('This record already exist'));
185
186
            return new TemplateResponse(
187
                $this->template,
188
                'product/create',
189
                $context
190
            );
191
        }
192
193
        /** @var Product $product */
194
        $product = $this->productRepository->create([
195
           'name' => $formParam->getName(),
196
        'description' => $formParam->getDescription(),
197
        'price' => $formParam->getPrice(),
198
        'quantity' => $formParam->getQuantity(),
199
        'product_category_id' => $formParam->getCategory(),
200
        ]);
201
202
        try {
203
            $this->productRepository->save($product);
204
205
            $this->flash->setSuccess($this->lang->tr('Data successfully created'));
206
207
            return new RedirectResponse(
208
                $this->routeHelper->generateUrl('product_list')
209
            );
210
        } catch (Exception $ex) {
211
            $this->logger->error('Error when saved the data {error}', ['error' => $ex->getMessage()]);
212
213
            $this->flash->setError($this->lang->tr('Data processing error'));
214
215
            return new TemplateResponse(
216
                $this->template,
217
                'product/create',
218
                $context
219
            );
220
        }
221
    }
222
223
    /**
224
    * Update existing entity
225
    * @param ServerRequestInterface $request
226
    * @return ResponseInterface
227
    */
228
    public function update(ServerRequestInterface $request): ResponseInterface
229
    {
230
        $context = [];
231
        $param = new RequestData($request);
232
233
        $id = (int) $request->getAttribute('id');
234
235
        /** @var Product|null $product */
236
        $product = $this->productRepository->find($id);
237
238
        if ($product === null) {
239
            $this->flash->setError($this->lang->tr('This record doesn\'t exist'));
240
241
            return new RedirectResponse(
242
                $this->routeHelper->generateUrl('product_list')
243
            );
244
        }
245
        $context['product'] = $product;
246
        $context['param'] = (new ProductParam())->fromEntity($product);
247
248
        $categories = $this->productCategoryRepository->orderBy('name')
249
                                                      ->all();
250
251
        $context['categories'] = $categories;
252
253
        if ($request->getMethod() === 'GET') {
254
            return new TemplateResponse(
255
                $this->template,
256
                'product/update',
257
                $context
258
            );
259
        }
260
        $formParam = new ProductParam($param->posts());
261
        $context['param'] = $formParam;
262
263
        $validator = new ProductValidator($formParam, $this->lang);
264
        if ($validator->validate() === false) {
265
            $context['errors'] = $validator->getErrors();
266
267
            return new TemplateResponse(
268
                $this->template,
269
                'product/update',
270
                $context
271
            );
272
        }
273
274
        $entityExist = $this->productRepository->findBy([
275
                                               'name' => $formParam->getName(),
276
                                           ]);
277
278
        if ($entityExist !== null && $entityExist->id !== $id) {
279
            $this->flash->setError($this->lang->tr('This record already exist'));
280
281
            return new TemplateResponse(
282
                $this->template,
283
                'product/update',
284
                $context
285
            );
286
        }
287
288
        $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...
289
        $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...
290
        $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...
291
        $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...
292
        $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...
293
294
        try {
295
            $this->productRepository->save($product);
296
297
            $this->flash->setSuccess($this->lang->tr('Data successfully updated'));
298
299
            return new RedirectResponse(
300
                $this->routeHelper->generateUrl('product_detail', ['id' => $id])
301
            );
302
        } catch (Exception $ex) {
303
            $this->logger->error('Error when saved the data {error}', ['error' => $ex->getMessage()]);
304
305
            $this->flash->setError($this->lang->tr('Data processing error'));
306
307
            return new TemplateResponse(
308
                $this->template,
309
                'product/update',
310
                $context
311
            );
312
        }
313
    }
314
315
    /**
316
    * Delete the entity
317
    * @param ServerRequestInterface $request
318
    * @return ResponseInterface
319
    */
320
    public function delete(ServerRequestInterface $request): ResponseInterface
321
    {
322
        $id = (int) $request->getAttribute('id');
323
324
        /** @var Product|null $product */
325
        $product = $this->productRepository->find($id);
326
327
        if ($product === null) {
328
            $this->flash->setError($this->lang->tr('This record doesn\'t exist'));
329
330
            return new RedirectResponse(
331
                $this->routeHelper->generateUrl('product_list')
332
            );
333
        }
334
335
        try {
336
            $this->productRepository->delete($product);
337
338
            $this->flash->setSuccess($this->lang->tr('Data successfully deleted'));
339
340
            return new RedirectResponse(
341
                $this->routeHelper->generateUrl('product_list')
342
            );
343
        } catch (Exception $ex) {
344
            $this->logger->error('Error when delete the data {error}', ['error' => $ex->getMessage()]);
345
346
            $this->flash->setError($this->lang->tr('Data processing error'));
347
348
            return new RedirectResponse(
349
                $this->routeHelper->generateUrl('product_list')
350
            );
351
        }
352
    }
353
}
354