Completed
Pull Request — experimental/sf (#3456)
by Kiyotaka
87:43 queued 81:34
created

MypageController::favorite()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 30

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 2.0009

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 2
dl 0
loc 30
rs 9.44
c 0
b 0
f 0
ccs 15
cts 16
cp 0.9375
crap 2.0009
1
<?php
2
3
/*
4
 * This file is part of EC-CUBE
5
 *
6
 * Copyright(c) LOCKON CO.,LTD. All Rights Reserved.
7
 *
8
 * http://www.lockon.co.jp/
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Eccube\Controller\Mypage;
15
16
use Eccube\Controller\AbstractController;
17
use Eccube\Entity\BaseInfo;
18
use Eccube\Entity\Customer;
19
use Eccube\Entity\CustomerFavoriteProduct;
20
use Eccube\Event\EccubeEvents;
21
use Eccube\Event\EventArgs;
22
use Eccube\Exception\CartException;
23
use Eccube\Form\Type\Front\CustomerLoginType;
24
use Eccube\Repository\BaseInfoRepository;
25
use Eccube\Repository\CustomerFavoriteProductRepository;
26
use Eccube\Repository\OrderRepository;
27
use Eccube\Repository\ProductRepository;
28
use Eccube\Service\CartService;
29
use Eccube\Service\PurchaseFlow\PurchaseContext;
30
use Eccube\Service\PurchaseFlow\PurchaseFlow;
31
use Knp\Component\Pager\Paginator;
32
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
33
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
34
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
35
use Symfony\Component\HttpFoundation\Request;
36
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
37
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
38
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
39
40
class MypageController extends AbstractController
41
{
42
    /**
43
     * @var ProductRepository
44
     */
45
    protected $productRepository;
46
47
    /**
48
     * @var CustomerFavoriteProductRepository
49
     */
50
    protected $customerFavoriteProductRepository;
51
52
    /**
53
     * @var BaseInfo
54
     */
55
    protected $BaseInfo;
56
57
    /**
58
     * @var CartService
59
     */
60
    protected $cartService;
61
62
    /**
63
     * @var OrderRepository
64
     */
65
    protected $orderRepository;
66
67
    /**
68
     * @var PurchaseFlow
69
     */
70
    protected $purchaseFlow;
71
72
    /**
73
     * MypageController constructor.
74
     *
75
     * @param OrderRepository $orderRepository
76
     * @param CustomerFavoriteProductRepository $customerFavoriteProductRepository
77
     * @param CartService $cartService
78
     * @param BaseInfoRepository $baseInfoRepository
79
     * @param PurchaseFlow $purchaseFlow
80
     */
81 9 View Code Duplication
    public function __construct(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
82
        OrderRepository $orderRepository,
83
        CustomerFavoriteProductRepository $customerFavoriteProductRepository,
84
        CartService $cartService,
85
        BaseInfoRepository $baseInfoRepository,
86
        PurchaseFlow $purchaseFlow
87
    ) {
88 9
        $this->orderRepository = $orderRepository;
89 9
        $this->customerFavoriteProductRepository = $customerFavoriteProductRepository;
90 9
        $this->BaseInfo = $baseInfoRepository->get();
91 9
        $this->cartService = $cartService;
92 9
        $this->purchaseFlow = $purchaseFlow;
93
    }
94
95
    /**
96
     * ログイン画面.
97
     *
98
     * @Route("/mypage/login", name="mypage_login")
99
     * @Template("Mypage/login.twig")
100
     */
101 2
    public function login(Request $request, AuthenticationUtils $utils)
102
    {
103 2
        if ($this->isGranted('IS_AUTHENTICATED_FULLY')) {
104 1
            log_info('認証済のためログイン処理をスキップ');
105
106 1
            return $this->redirectToRoute('mypage');
107
        }
108
109
        /* @var $form \Symfony\Component\Form\FormInterface */
110 1
        $builder = $this->formFactory
111 1
            ->createNamedBuilder('', CustomerLoginType::class);
112
113 1
        $builder->get('login_memory')->setData((bool) $request->getSession()->get('_security.login_memory'));
114
115 1
        if ($this->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
116
            $Customer = $this->getUser();
117
            if ($Customer instanceof Customer) {
118
                $builder->get('login_email')
119
                    ->setData($Customer->getEmail());
120
            }
121
        }
122
123 1
        $event = new EventArgs(
124
            [
125 1
                'builder' => $builder,
126
            ],
127 1
            $request
128
        );
129 1
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_MYPAGE_MYPAGE_LOGIN_INITIALIZE, $event);
130
131 1
        $form = $builder->getForm();
132
133
        return [
134 1
            'error' => $utils->getLastAuthenticationError(),
135 1
            'form' => $form->createView(),
136
        ];
137
    }
138
139
    /**
140
     * マイページ.
141
     *
142
     * @Route("/mypage/", name="mypage")
143
     * @Template("Mypage/index.twig")
144
     */
145 1
    public function index(Request $request, Paginator $paginator)
146
    {
147 1
        $Customer = $this->getUser();
148
149
        // 購入処理中/決済処理中ステータスの受注を非表示にする.
150 1
        $this->entityManager
151 1
            ->getFilters()
152 1
            ->enable('incomplete_order_status_hidden');
153
154
        // paginator
155 1
        $qb = $this->orderRepository->getQueryBuilderByCustomer($Customer);
0 ignored issues
show
Documentation introduced by
$Customer is of type null|object, but the function expects a object<Eccube\Entity\Customer>.

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...
156
157 1
        $event = new EventArgs(
158
            [
159 1
                'qb' => $qb,
160 1
                'Customer' => $Customer,
161
            ],
162 1
            $request
163
        );
164 1
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_MYPAGE_MYPAGE_INDEX_SEARCH, $event);
165
166 1
        $pagination = $paginator->paginate(
167 1
            $qb,
168 1
            $request->get('pageno', 1),
169 1
            $this->eccubeConfig['eccube_search_pmax']
170
        );
171
172
        return [
173 1
            'pagination' => $pagination,
174
        ];
175
    }
176
177
    /**
178
     * 購入履歴詳細を表示する.
179
     *
180
     * @Route("/mypage/history/{order_no}", name="mypage_history")
181
     * @Template("Mypage/history.twig")
182
     */
183 2
    public function history(Request $request, $order_no)
184
    {
185 2
        $this->entityManager->getFilters()
186 2
            ->enable('incomplete_order_status_hidden');
187 2
        $Order = $this->orderRepository->findOneBy(
188
            [
189 2
                'order_no' => $order_no,
190 2
                'Customer' => $this->getUser(),
191
            ]
192
        );
193
194 2
        $event = new EventArgs(
195
            [
196 2
                'Order' => $Order,
197
            ],
198 2
            $request
199
        );
200 2
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_MYPAGE_MYPAGE_HISTORY_INITIALIZE, $event);
201
202 2
        $Order = $event->getArgument('Order');
203
204 2
        if (!$Order) {
205 2
            throw new NotFoundHttpException();
206
        }
207
208
        return [
209
            'Order' => $Order,
210
        ];
211
    }
212
213
    /**
214
     * 再購入を行う.
215
     *
216
     * @Route("/mypage/order/{order_no}", name="mypage_order")
217
     * @Method("PUT")
218
     */
219 1
    public function order(Request $request, $order_no)
220
    {
221 1
        $this->isTokenValid();
222
223 1
        log_info('再注文開始', [$order_no]);
224
225 1
        $Customer = $this->getUser();
226
227
        /* @var $Order \Eccube\Entity\Order */
228 1
        $Order = $this->orderRepository->findOneBy(
229
            [
230 1
                'order_no' => $order_no,
231 1
                'Customer' => $Customer,
232
            ]
233
        );
234
235 1
        $event = new EventArgs(
236
            [
237 1
                'Order' => $Order,
238 1
                'Customer' => $Customer,
239
            ],
240 1
            $request
241
        );
242 1
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_MYPAGE_MYPAGE_ORDER_INITIALIZE, $event);
243
244 1
        if (!$Order) {
245
            log_info('対象の注文が見つかりません', [$order_no]);
246
            throw new NotFoundHttpException();
247
        }
248
249
        // エラーメッセージの配列
250 1
        $errorMessages = [];
251
252 1
        foreach ($Order->getOrderItems() as $OrderItem) {
253
            try {
254 1
                if ($OrderItem->getProduct() &&
255 1
                    $OrderItem->getProductClass()
256
                ) {
257 1
                    $this->cartService->addProduct($OrderItem->getProductClass(), $OrderItem->getQuantity());
258
259
                    // 明細の正規化
260 1
                    $Carts = $this->cartService->getCarts();
261 1 View Code Duplication
                    foreach ($Carts as $Cart) {
262 1
                        $result = $this->purchaseFlow->validate($Cart, new PurchaseContext($Cart, $this->getUser()));
263
                        // 復旧不可のエラーが発生した場合は追加した明細を削除.
264 1
                        if ($result->hasError()) {
265
                            $this->cartService->removeProduct($OrderItem->getProductClass());
266
                            foreach ($result->getErrors() as $error) {
267
                                $errorMessages[] = $error->getMessage();
268
                            }
269
                        }
270 1
                        foreach ($result->getWarning() as $warning) {
271 1
                            $errorMessages[] = $warning->getMessage();
272
                        }
273
                    }
274
275 1
                    $this->cartService->save();
276
                } else {
277 1
                    log_info(trans('cart.product.delete'), [$order_no]);
278 1
                    $this->addRequestError('cart.product.delete');
279
                }
280
            } catch (CartException $e) {
281
                log_info($e->getMessage(), [$order_no]);
282 1
                $this->addRequestError($e->getMessage());
283
            }
284
        }
285
286 1
        foreach ($errorMessages as $errorMessage) {
287
            $this->addRequestError($errorMessage);
288
        }
289
290 1
        $event = new EventArgs(
291
            [
292 1
                'Order' => $Order,
293 1
                'Customer' => $Customer,
294
            ],
295 1
            $request
296
        );
297 1
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_MYPAGE_MYPAGE_ORDER_COMPLETE, $event);
298
299 1
        if ($event->getResponse() !== null) {
300
            return $event->getResponse();
301
        }
302
303 1
        log_info('再注文完了', [$order_no]);
304
305 1
        return $this->redirect($this->generateUrl('cart'));
306
    }
307
308
    /**
309
     * お気に入り商品を表示する.
310
     *
311
     * @Route("/mypage/favorite", name="mypage_favorite")
312
     * @Template("Mypage/favorite.twig")
313
     */
314 2
    public function favorite(Request $request, Paginator $paginator)
315
    {
316 2
        if (!$this->BaseInfo->isOptionFavoriteProduct()) {
317
            throw new NotFoundHttpException();
318
        }
319 2
        $Customer = $this->getUser();
320
321
        // paginator
322 2
        $qb = $this->customerFavoriteProductRepository->getQueryBuilderByCustomer($Customer);
0 ignored issues
show
Documentation introduced by
$Customer is of type null|object, but the function expects a object<Eccube\Entity\Customer>.

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...
323
324 2
        $event = new EventArgs(
325
            [
326 2
                'qb' => $qb,
327 2
                'Customer' => $Customer,
328
            ],
329 2
            $request
330
        );
331 2
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_MYPAGE_MYPAGE_FAVORITE_SEARCH, $event);
332
333 2
        $pagination = $paginator->paginate(
334 2
            $qb,
335 2
            $request->get('pageno', 1),
336 2
            $this->eccubeConfig['eccube_search_pmax'],
337 2
            ['wrap-queries' => true]
338
        );
339
340
        return [
341 2
            'pagination' => $pagination,
342
        ];
343
    }
344
345
    /**
346
     * お気に入り商品を削除する.
347
     *
348
     * @Method("DELETE")
349
     * @Route("/mypage/favorite/{id}/delete", name="mypage_favorite_delete", requirements={"id" = "\d+"})
350
     */
351 1
    public function delete(Request $request, CustomerFavoriteProduct $CustomerFavoriteProduct)
352
    {
353 1
        $this->isTokenValid();
354
355 1
        $Customer = $this->getUser();
356
357 1
        log_info('お気に入り商品削除開始', [$Customer->getId(), $CustomerFavoriteProduct->getId()]);
358
359 1
        if ($Customer->getId() !== $CustomerFavoriteProduct->getCustomer()
360 1
                ->getId()) {
361
            throw new BadRequestHttpException();
362
        }
363
364 1
        $this->customerFavoriteProductRepository->delete($CustomerFavoriteProduct);
365
366 1
        $event = new EventArgs(
367
            [
368 1
                'Customer' => $Customer,
369 1
                'CustomerFavoriteProduct' => $CustomerFavoriteProduct,
370 1
            ], $request
371
        );
372 1
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_MYPAGE_MYPAGE_DELETE_COMPLETE, $event);
373
374 1
        log_info('お気に入り商品削除完了', [$Customer->getId(), $CustomerFavoriteProduct->getId()]);
375
376 1
        return $this->redirect($this->generateUrl('mypage_favorite'));
377
    }
378
}
379