Failed Conditions
Pull Request — experimental/3.1 (#2486)
by
unknown
68:04 queued 25:47
created

ProductController   C

Complexity

Total Complexity 37

Size/Duplication

Total Lines 426
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 19

Test Coverage

Coverage 80%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 426
ccs 148
cts 185
cp 0.8
rs 5.9125
c 1
b 0
f 0
wmc 37
lcom 1
cbo 19

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
D index() 0 171 13
D detail() 0 161 18
B getPageTitle() 0 10 5
1
<?php
2
/*
3
 * This file is part of EC-CUBE
4
 *
5
 * Copyright(c) 2000-2015 LOCKON CO.,LTD. All Rights Reserved.
6
 *
7
 * http://www.lockon.co.jp/
8
 *
9
 * This program is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU General Public License
11
 * as published by the Free Software Foundation; either version 2
12
 * of the License, or (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program; if not, write to the Free Software
21
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
 */
23
24
25
namespace Eccube\Controller;
26
27
use Doctrine\ORM\EntityManager;
28
use Eccube\Annotation\Component;
29
use Eccube\Annotation\Inject;
30
use Eccube\Application;
31
use Eccube\Entity\BaseInfo;
32
use Eccube\Common\Constant;
33
use Eccube\Entity\ProductClass;
34
use Eccube\Event\EccubeEvents;
35
use Eccube\Event\EventArgs;
36
use Eccube\Exception\CartException;
37
use Eccube\Form\Type\AddCartType;
38
use Eccube\Form\Type\Master\ProductListMaxType;
39
use Eccube\Form\Type\Master\ProductListOrderByType;
40
use Eccube\Form\Type\SearchProductType;
41
use Eccube\Repository\BaseInfoRepository;
42
use Eccube\Repository\CustomerFavoriteProductRepository;
43
use Eccube\Repository\ProductRepository;
44
use Eccube\Service\CartService;
45
use Eccube\Service\PurchaseFlow\PurchaseFlow;
46
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
47
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
48
use Symfony\Component\EventDispatcher\EventDispatcher;
49
use Symfony\Component\Form\FormFactory;
50
use Symfony\Component\HttpFoundation\Request;
51
use Symfony\Component\HttpFoundation\Session\Session;
52
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
53
54
/**
55
 * @Component
56
 * @Route(service=ProductController::class)
57
 */
58
class ProductController
59
{
60
    /**
61
     * @Inject("eccube.purchase.flow.cart")
62
     * @var PurchaseFlow
63
     */
64
    protected $purchaseFlow;
65
66
    /**
67
     * @Inject("session")
68
     * @var Session
69
     */
70
    protected $session;
71
72
    /**
73
     * @Inject(CustomerFavoriteProductRepository::class)
74
     * @var CustomerFavoriteProductRepository
75
     */
76
    protected $customerFavoriteProductRepository;
77
78
    /**
79
     * @Inject(CartService::class)
80
     * @var CartService
81
     */
82
    protected $cartService;
83
84
    /**
85
     * @Inject(ProductRepository::class)
86
     * @var ProductRepository
87
     */
88
    protected $productRepository;
89
90
    /**
91
     * @Inject("eccube.event.dispatcher")
92
     * @var EventDispatcher
93
     */
94
    protected $eventDispatcher;
95
96
    /**
97
     * @Inject("form.factory")
98
     * @var FormFactory
99
     */
100
    protected $formFactory;
101
102
    /**
103
     * @Inject("orm.em")
104
     * @var EntityManager
105
     */
106
    protected $entityManager;
107
108
    /**
109
     * @Inject(BaseInfo::class)
110
     * @var BaseInfo
111
     */
112
    protected $BaseInfo;
113
114
    private $title;
115
116
    public function __construct()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
117
    {
118
        $this->title = '';
119
    }
120
121
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$request" missing
Loading history...
122
     * 商品一覧画面.
123
     *
124
     * @Route("/products/list", name="product_list")
125
     * @Template("Product/list.twig")
126
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
127 3
    public function index(Application $app, Request $request)
128
    {
129
        // Doctrine SQLFilter
130 3
        if ($this->BaseInfo->getNostockHidden() === Constant::ENABLED) {
131
            $this->entityManager->getFilters()->enable('nostock_hidden');
132
        }
133
134
        // handleRequestは空のqueryの場合は無視するため
135 3
        if ($request->getMethod() === 'GET') {
136 3
            $request->query->set('pageno', $request->query->get('pageno', ''));
137
        }
138
139
        // searchForm
140
        /* @var $builder \Symfony\Component\Form\FormBuilderInterface */
141 3
        $builder = $this->formFactory->createNamedBuilder('', SearchProductType::class);
142 3
        $builder->setAttribute('freeze', true);
143 3
        $builder->setAttribute('freeze_display_text', false);
144 3
        if ($request->getMethod() === 'GET') {
145 3
            $builder->setMethod('GET');
146
        }
147
148 3
        $event = new EventArgs(
149
            array(
150 3
                'builder' => $builder,
151
            ),
152 3
            $request
153
        );
154 3
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_INDEX_INITIALIZE, $event);
155
156
        /* @var $searchForm \Symfony\Component\Form\FormInterface */
157 3
        $searchForm = $builder->getForm();
158
159 3
        $searchForm->handleRequest($request);
160
161
        // paginator
162 3
        $searchData = $searchForm->getData();
163 3
        $qb = $this->productRepository->getQueryBuilderBySearchData($searchData);
164
165 3
        $event = new EventArgs(
166
            array(
167 3
                'searchData' => $searchData,
168 3
                'qb' => $qb,
169
            ),
170 3
            $request
171
        );
172 3
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_INDEX_SEARCH, $event);
173 3
        $searchData = $event->getArgument('searchData');
174
175 3
        $pagination = $app['paginator']()->paginate(
176 3
            $qb,
177 3
            !empty($searchData['pageno']) ? $searchData['pageno'] : 1,
178 3
            $searchData['disp_number']->getId()
179
        );
180
181
        // addCart form
182 3
        $forms = array();
183 3
        foreach ($pagination as $Product) {
184
            /* @var $builder \Symfony\Component\Form\FormBuilderInterface */
185 3
            $builder = $this->formFactory->createNamedBuilder(
186 3
                '',
187 3
                AddCartType::class,
188 3
                null,
189
                array(
190 3
                    'product' => $Product,
191
                    'allow_extra_fields' => true,
192
                )
193
            );
194 3
            $addCartForm = $builder->getForm();
195
196 3
            if ($request->getMethod() === 'POST' && (string)$Product->getId() === $request->get('product_id')) {
0 ignored issues
show
Coding Style introduced by
As per coding-style, a cast statement should be followed by a single space.
Loading history...
197
                $addCartForm->handleRequest($request);
198
199
                if ($addCartForm->isValid()) {
200
                    $addCartData = $addCartForm->getData();
201
202
                    try {
203
                        // TODO カート追加処理の変更
204
                        $this->cartService->addProduct(
0 ignored issues
show
Bug introduced by
The method save cannot be called on $this->cartService->addP...ddCartData['quantity']) (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
205
                            $addCartData['product_class_id'],
206
                            $addCartData['quantity']
207
                        )->save();
208
                    } catch (CartException $e) {
209
                        $app->addRequestError($e->getMessage());
210
                    }
211
212
                    $event = new EventArgs(
213
                        array(
214
                            'form' => $addCartForm,
215
                            'Product' => $Product,
216
                        ),
217
                        $request
218
                    );
219
                    $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_INDEX_COMPLETE, $event);
220
221
                    if ($event->getResponse() !== null) {
222
                        return $event->getResponse();
223
                    }
224
225
                    return $app->redirect($app->url('cart'));
226
                }
227
            }
228
229 3
            $forms[$Product->getId()] = $addCartForm->createView();
230
        }
231
232
        // 表示件数
233 3
        $builder = $this->formFactory->createNamedBuilder(
234 3
            'disp_number',
235 3
            ProductListMaxType::class,
236 3
            null,
237
            array(
238 3
                'required' => false,
239
                'label' => '表示件数',
240
                'allow_extra_fields' => true,
241
            )
242
        );
243 3
        if ($request->getMethod() === 'GET') {
244 3
            $builder->setMethod('GET');
245
        }
246
247 3
        $event = new EventArgs(
248
            array(
249 3
                'builder' => $builder,
250
            ),
251 3
            $request
252
        );
253 3
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_INDEX_DISP, $event);
254
255 3
        $dispNumberForm = $builder->getForm();
256
257 3
        $dispNumberForm->handleRequest($request);
258
259
        // ソート順
260 3
        $builder = $this->formFactory->createNamedBuilder(
261 3
            'orderby',
262 3
            ProductListOrderByType::class,
263 3
            null,
264
            array(
265 3
                'required' => false,
266
                'label' => '表示順',
267
                'allow_extra_fields' => true,
268
            )
269
        );
270 3
        if ($request->getMethod() === 'GET') {
271 3
            $builder->setMethod('GET');
272
        }
273
274 3
        $event = new EventArgs(
275
            array(
276 3
                'builder' => $builder,
277
            ),
278 3
            $request
279
        );
280 3
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_INDEX_ORDER, $event);
281
282 3
        $orderByForm = $builder->getForm();
283
284 3
        $orderByForm->handleRequest($request);
285
286 3
        $Category = $searchForm->get('category_id')->getData();
287
288
        return [
289 3
            'subtitle' => $this->getPageTitle($searchData),
290 3
            'pagination' => $pagination,
291 3
            'search_form' => $searchForm->createView(),
292 3
            'disp_number_form' => $dispNumberForm->createView(),
293 3
            'order_by_form' => $orderByForm->createView(),
294 3
            'forms' => $forms,
295 3
            'Category' => $Category,
296
        ];
297
    }
298
299
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$request" missing
Loading history...
introduced by
Doc comment for parameter "$id" missing
Loading history...
300
     * 商品詳細画面.
301
     *
302
     * @Route("/products/detail/{id}", name="product_detail", requirements={"id" = "\d+"})
303
     * @Template("Product/detail.twig")
304
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
305 17
    public function detail(Application $app, Request $request, $id)
306
    {
307 17
        if ($this->BaseInfo->getNostockHidden() === Constant::ENABLED) {
308
            $this->entityManager->getFilters()->enable('nostock_hidden');
309
        }
310
311
        /* @var $Product \Eccube\Entity\Product */
312 17
        $Product = $this->productRepository->get($id);
0 ignored issues
show
Deprecated Code introduced by
The method Eccube\Repository\ProductRepository::get() has been deprecated with message: Use ProductRepository::find()

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
313 17
        if (!$request->getSession()->has('_security_admin') && $Product->getStatus()->getId() !== 1) {
314
            throw new NotFoundHttpException();
315
        }
316 17
        if (count($Product->getProductClasses()) < 1) {
317
            throw new NotFoundHttpException();
318
        }
319
320
        /* @var $builder \Symfony\Component\Form\FormBuilderInterface */
321 17
        $builder = $this->formFactory->createNamedBuilder(
322 17
            '',
323 17
            AddCartType::class,
324 17
            null,
325
            array(
326 17
                'product' => $Product,
327
                'id_add_product_id' => false,
328
            )
329
        );
330
331 17
        $event = new EventArgs(
332
            array(
333 17
                'builder' => $builder,
334 17
                'Product' => $Product,
335
            ),
336 17
            $request
337
        );
338 17
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_DETAIL_INITIALIZE, $event);
339
340
        /* @var $form \Symfony\Component\Form\FormInterface */
341 17
        $form = $builder->getForm();
342
343 17
        if ($request->getMethod() === 'POST') {
344 16
            $form->handleRequest($request);
345
346 16
            if ($form->isValid()) {
347
                /** @var \Eccube\Entity\CartItem $addCartData */
348 15
                $addCartData = $form->getData();
349 15
                $mode = $form['mode']->getData();
350 15
                if ($mode === 'add_favorite') {
351 2
                    if ($app->isGranted('ROLE_USER')) {
352 2
                        $Customer = $app->user();
353 2
                        $this->customerFavoriteProductRepository->addFavorite($Customer, $Product);
354 2
                        $this->session->getFlashBag()->set('product_detail.just_added_favorite', $Product->getId());
355
356 2
                        $event = new EventArgs(
357
                            array(
358 2
                                'form' => $form,
359 2
                                'Product' => $Product,
360
                            ),
361 2
                            $request
362
                        );
363 2
                        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_DETAIL_FAVORITE, $event);
364
365 2
                        if ($event->getResponse() !== null) {
366
                            return $event->getResponse();
367
                        }
368
369 2
                        return $app->redirect($app->url('product_detail', array('id' => $Product->getId())));
370
                    } else {
371
                        // 非会員の場合、ログイン画面を表示
372
                        //  ログイン後の画面遷移先を設定
373
                        $app->setLoginTargetPath($app->url('product_detail', array('id' => $Product->getId())));
374
                        $this->session->getFlashBag()->set('eccube.add.favorite', true);
0 ignored issues
show
Documentation introduced by
true is of type boolean, but the function expects a string|array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
375
376
                        return $app->redirect($app->url('mypage_login'));
377
                    }
378 13
                } elseif ($mode === 'add_cart') {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
379
380 13
                    $ProductClass = $addCartData->getProductClass();
381 13
                    $product_class_id = $ProductClass->getId();
382 13
                    $quantity = $addCartData->getQuantity();
383
384 13
                    log_info(
385 13
                        'カート追加処理開始',
386
                        array(
387 13
                            'product_id' => $Product->getId(),
388 13
                            'product_class_id' => $product_class_id,
389 13
                            'quantity' => $quantity,
390
                        )
391
                    );
392
393
                    // カートを取得
394 13
                    $Cart = $this->cartService->getCart();
395
396
                    // 明細の正規化
397 13
                    $flow = $this->purchaseFlow;
398 13
                    $flow->addItem($addCartData, $app['eccube.purchase.context']($Cart));
399 13
                    $result = $flow->calculate($Cart, $app['eccube.purchase.context']());
400
401
                    // 復旧不可のエラーが発生した場合は追加した明細を削除.
402 13
                    if ($result->hasError()) {
403
                        $Cart->removeCartItemByCartNo($addCartData->getCartNo());
404
                        foreach ($result->getErrors() as $error) {
405
                            $app->addRequestError($error->getMessage());
406
                        }
407
                    }
408
409 13
                    foreach ($result->getWarning() as $warning) {
410
                        $app->addRequestError($warning->getMessage());
411
                    }
412
413 13
                    $this->cartService->save();
414
415 13
                    log_info(
416 13
                        'カート追加処理完了',
417
                        array(
418 13
                            'product_id' => $Product->getId(),
419 13
                            'product_class_id' => $product_class_id,
420 13
                            'quantity' => $quantity,
421
                        )
422
                    );
423
424 13
                    $event = new EventArgs(
425
                        array(
426 13
                            'form' => $form,
427 13
                            'Product' => $Product,
428
                        ),
429 13
                        $request
430
                    );
431 13
                    $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_DETAIL_COMPLETE, $event);
432
433 13
                    if ($event->getResponse() !== null) {
434
                        return $event->getResponse();
435
                    }
436
437 14
                    return $app->redirect($app->url('cart'));
438
                }
439
            }
440
        } else {
441 3
            $addFavorite = $this->session->getFlashBag()->get('eccube.add.favorite');
442 3
            if (!empty($addFavorite)) {
443
                // お気に入り登録時にログインされていない場合、ログイン後にお気に入り追加処理を行う
444
                if ($app->isGranted('ROLE_USER')) {
445
                    $Customer = $app->user();
446
                    $this->customerFavoriteProductRepository->addFavorite($Customer, $Product);
447
                    $this->session->getFlashBag()->set('product_detail.just_added_favorite', $Product->getId());
448
                }
449
            }
450
        }
451
452 4
        $is_favorite = false;
453 4
        if ($app->isGranted('ROLE_USER')) {
454 2
            $Customer = $app->user();
455 2
            $is_favorite = $this->customerFavoriteProductRepository->isFavorite($Customer, $Product);
456
        }
457
458
        return [
459 4
            'title' => $this->title,
460 4
            'subtitle' => $Product->getName(),
461 4
            'form' => $form->createView(),
462 4
            'Product' => $Product,
463 4
            'is_favorite' => $is_favorite,
464
        ];
465
    }
466
467
    /**
468
     * ページタイトルの設定
469
     *
470
     * @param  null|array $searchData
471
     * @return str
472
     */
473 3
    private function getPageTitle($searchData)
474
    {
475 3
        if (isset($searchData['name']) && !empty($searchData['name'])) {
476
            return '検索結果';
477 3
        } elseif (isset($searchData['category_id']) && $searchData['category_id']) {
478 1
            return $searchData['category_id']->getName();
479
        } else {
480 2
            return '全商品';
481
        }
482
    }
483
}
484