Failed Conditions
Push — dev/plugin-misc ( f22d99...066a4d )
by Kiyotaka
10:54 queued 03:43
created

MypageController::history()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 39

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
nc 4
nop 2
dl 0
loc 39
rs 8.9848
c 0
b 0
f 0
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\Product;
20
use Eccube\Entity\Order;
21
use Eccube\Event\EccubeEvents;
22
use Eccube\Event\EventArgs;
23
use Eccube\Exception\CartException;
24
use Eccube\Form\Type\Front\CustomerLoginType;
25
use Eccube\Repository\BaseInfoRepository;
26
use Eccube\Repository\CustomerFavoriteProductRepository;
27
use Eccube\Repository\OrderRepository;
28
use Eccube\Repository\ProductRepository;
29
use Eccube\Service\CartService;
30
use Eccube\Service\PurchaseFlow\PurchaseContext;
31
use Eccube\Service\PurchaseFlow\PurchaseFlow;
32
use Knp\Component\Pager\Paginator;
33
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
34
use Symfony\Component\HttpFoundation\Request;
35
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
36
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
37
use Symfony\Component\Routing\Annotation\Route;
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
    public function __construct(
82
        OrderRepository $orderRepository,
83
        CustomerFavoriteProductRepository $customerFavoriteProductRepository,
84
        CartService $cartService,
85
        BaseInfoRepository $baseInfoRepository,
86
        PurchaseFlow $purchaseFlow
87
    ) {
88
        $this->orderRepository = $orderRepository;
89
        $this->customerFavoriteProductRepository = $customerFavoriteProductRepository;
90
        $this->BaseInfo = $baseInfoRepository->get();
91
        $this->cartService = $cartService;
92
        $this->purchaseFlow = $purchaseFlow;
93
    }
94
95
    /**
96
     * ログイン画面.
97
     *
98
     * @Route("/mypage/login", name="mypage_login")
99
     * @Template("Mypage/login.twig")
100
     */
101
    public function login(Request $request, AuthenticationUtils $utils)
102
    {
103
        if ($this->isGranted('IS_AUTHENTICATED_FULLY')) {
104
            log_info('認証済のためログイン処理をスキップ');
105
106
            return $this->redirectToRoute('mypage');
107
        }
108
109
        /* @var $form \Symfony\Component\Form\FormInterface */
110
        $builder = $this->formFactory
111
            ->createNamedBuilder('', CustomerLoginType::class);
112
113
        $builder->get('login_memory')->setData((bool) $request->getSession()->get('_security.login_memory'));
114
115
        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
        $event = new EventArgs(
124
            [
125
                'builder' => $builder,
126
            ],
127
            $request
128
        );
129
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_MYPAGE_MYPAGE_LOGIN_INITIALIZE, $event);
130
131
        $form = $builder->getForm();
132
133
        return [
134
            'error' => $utils->getLastAuthenticationError(),
135
            'form' => $form->createView(),
136
        ];
137
    }
138
139
    /**
140
     * マイページ.
141
     *
142
     * @Route("/mypage/", name="mypage")
143
     * @Template("Mypage/index.twig")
144
     */
145
    public function index(Request $request, Paginator $paginator)
146
    {
147
        $Customer = $this->getUser();
148
149
        // 購入処理中/決済処理中ステータスの受注を非表示にする.
150
        $this->entityManager
151
            ->getFilters()
152
            ->enable('incomplete_order_status_hidden');
153
154
        // paginator
155
        $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
        $event = new EventArgs(
158
            [
159
                'qb' => $qb,
160
                'Customer' => $Customer,
161
            ],
162
            $request
163
        );
164
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_MYPAGE_MYPAGE_INDEX_SEARCH, $event);
165
166
        $pagination = $paginator->paginate(
167
            $qb,
168
            $request->get('pageno', 1),
169
            $this->eccubeConfig['eccube_search_pmax']
170
        );
171
172
        return [
173
            'pagination' => $pagination,
174
        ];
175
    }
176
177
    /**
178
     * 購入履歴詳細を表示する.
179
     *
180
     * @Route("/mypage/history/{order_no}", name="mypage_history")
181
     * @Template("Mypage/history.twig")
182
     */
183
    public function history(Request $request, $order_no)
184
    {
185
        $this->entityManager->getFilters()
186
            ->enable('incomplete_order_status_hidden');
187
        $Order = $this->orderRepository->findOneBy(
188
            [
189
                'order_no' => $order_no,
190
                'Customer' => $this->getUser(),
191
            ]
192
        );
193
194
        $event = new EventArgs(
195
            [
196
                'Order' => $Order,
197
            ],
198
            $request
199
        );
200
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_MYPAGE_MYPAGE_HISTORY_INITIALIZE, $event);
201
202
        /** @var Order $Order */
203
        $Order = $event->getArgument('Order');
204
205
        if (!$Order) {
206
            throw new NotFoundHttpException();
207
        }
208
209
        $stockOrder = true;
210
        foreach ($Order->getOrderItems() as $orderItem) {
211
            if ($orderItem->isProduct() && $orderItem->getQuantity() < 0) {
212
                $stockOrder = false;
213
                break;
214
            }
215
        }
216
217
        return [
218
            'Order' => $Order,
219
            'stockOrder' => $stockOrder,
220
        ];
221
    }
222
223
    /**
224
     * 再購入を行う.
225
     *
226
     * @Route("/mypage/order/{order_no}", name="mypage_order", methods={"PUT"})
227
     */
228
    public function order(Request $request, $order_no)
229
    {
230
        $this->isTokenValid();
231
232
        log_info('再注文開始', [$order_no]);
233
234
        $Customer = $this->getUser();
235
236
        /* @var $Order \Eccube\Entity\Order */
237
        $Order = $this->orderRepository->findOneBy(
238
            [
239
                'order_no' => $order_no,
240
                'Customer' => $Customer,
241
            ]
242
        );
243
244
        $event = new EventArgs(
245
            [
246
                'Order' => $Order,
247
                'Customer' => $Customer,
248
            ],
249
            $request
250
        );
251
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_MYPAGE_MYPAGE_ORDER_INITIALIZE, $event);
252
253
        if (!$Order) {
254
            log_info('対象の注文が見つかりません', [$order_no]);
255
            throw new NotFoundHttpException();
256
        }
257
258
        // エラーメッセージの配列
259
        $errorMessages = [];
260
261
        foreach ($Order->getOrderItems() as $OrderItem) {
262
            try {
263
                if ($OrderItem->getProduct() && $OrderItem->getProductClass()) {
264
                    $this->cartService->addProduct($OrderItem->getProductClass(), $OrderItem->getQuantity());
265
266
                    // 明細の正規化
267
                    $Carts = $this->cartService->getCarts();
268 View Code Duplication
                    foreach ($Carts as $Cart) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
269
                        $result = $this->purchaseFlow->validate($Cart, new PurchaseContext($Cart, $this->getUser()));
270
                        // 復旧不可のエラーが発生した場合は追加した明細を削除.
271
                        if ($result->hasError()) {
272
                            $this->cartService->removeProduct($OrderItem->getProductClass());
273
                            foreach ($result->getErrors() as $error) {
274
                                $errorMessages[] = $error->getMessage();
275
                            }
276
                        }
277
                        foreach ($result->getWarning() as $warning) {
278
                            $errorMessages[] = $warning->getMessage();
279
                        }
280
                    }
281
282
                    $this->cartService->save();
283
                }
284
            } catch (CartException $e) {
285
                log_info($e->getMessage(), [$order_no]);
286
                $this->addRequestError($e->getMessage());
287
            }
288
        }
289
290
        foreach ($errorMessages as $errorMessage) {
291
            $this->addRequestError($errorMessage);
292
        }
293
294
        $event = new EventArgs(
295
            [
296
                'Order' => $Order,
297
                'Customer' => $Customer,
298
            ],
299
            $request
300
        );
301
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_MYPAGE_MYPAGE_ORDER_COMPLETE, $event);
302
303
        if ($event->getResponse() !== null) {
304
            return $event->getResponse();
305
        }
306
307
        log_info('再注文完了', [$order_no]);
308
309
        return $this->redirect($this->generateUrl('cart'));
310
    }
311
312
    /**
313
     * お気に入り商品を表示する.
314
     *
315
     * @Route("/mypage/favorite", name="mypage_favorite")
316
     * @Template("Mypage/favorite.twig")
317
     */
318
    public function favorite(Request $request, Paginator $paginator)
319
    {
320
        if (!$this->BaseInfo->isOptionFavoriteProduct()) {
321
            throw new NotFoundHttpException();
322
        }
323
        $Customer = $this->getUser();
324
325
        // paginator
326
        $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...
327
328
        $event = new EventArgs(
329
            [
330
                'qb' => $qb,
331
                'Customer' => $Customer,
332
            ],
333
            $request
334
        );
335
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_MYPAGE_MYPAGE_FAVORITE_SEARCH, $event);
336
337
        $pagination = $paginator->paginate(
338
            $qb,
339
            $request->get('pageno', 1),
340
            $this->eccubeConfig['eccube_search_pmax'],
341
            ['wrap-queries' => true]
342
        );
343
344
        return [
345
            'pagination' => $pagination,
346
        ];
347
    }
348
349
    /**
350
     * お気に入り商品を削除する.
351
     *
352
     * @Route("/mypage/favorite/{id}/delete", name="mypage_favorite_delete", methods={"DELETE"}, requirements={"id" = "\d+"})
353
     */
354
    public function delete(Request $request, Product $Product)
355
    {
356
        $this->isTokenValid();
357
358
        $Customer = $this->getUser();
359
360
        log_info('お気に入り商品削除開始', [$Customer->getId(), $Product->getId()]);
361
362
        $CustomerFavoriteProduct = $this->customerFavoriteProductRepository->findOneBy(['Customer' => $Customer, 'Product' => $Product]);
363
364
        if ($CustomerFavoriteProduct) {
365
            $this->customerFavoriteProductRepository->delete($CustomerFavoriteProduct);
366
        } else {
367
            throw new BadRequestHttpException();
368
        }
369
370
        $event = new EventArgs(
371
            [
372
                'Customer' => $Customer,
373
                'CustomerFavoriteProduct' => $CustomerFavoriteProduct,
374
            ], $request
375
        );
376
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_MYPAGE_MYPAGE_DELETE_COMPLETE, $event);
377
378
        log_info('お気に入り商品削除完了', [$Customer->getId(), $CustomerFavoriteProduct->getId()]);
379
380
        return $this->redirect($this->generateUrl('mypage_favorite'));
381
    }
382
}
383