Completed
Push — master ( 284884...b70f30 )
by Kamil
20:25
created

OrderController::afterPurchaseAction()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 22
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
c 2
b 1
f 0
dl 0
loc 22
rs 9.2
cc 3
eloc 15
nc 2
nop 1
1
<?php
2
3
/*
4
 * This file is part of the Sylius package.
5
 *
6
 * (c) Paweł Jędrzejewski
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Sylius\Bundle\WebBundle\Controller\Frontend\Account;
13
14
use Doctrine\ORM\EntityManager;
15
use FOS\RestBundle\Controller\FOSRestController;
16
use Payum\Core\Registry\RegistryInterface;
17
use Payum\Core\Security\GenericTokenFactoryInterface;
18
use Payum\Core\Security\HttpRequestVerifierInterface;
19
use Sylius\Bundle\PayumBundle\Request\GetStatus;
20
use Sylius\Component\Core\Model\CustomerInterface;
21
use Sylius\Component\Core\Model\OrderInterface;
22
use Sylius\Component\Core\Model\PaymentInterface;
23
use Sylius\Component\Core\Repository\OrderRepositoryInterface;
24
use Symfony\Component\Form\FormInterface;
25
use Symfony\Component\HttpFoundation\Request;
26
use Symfony\Component\HttpFoundation\Response;
27
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
28
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
29
30
/**
31
 * Account order controller.
32
 *
33
 * @author Julien Janvier <[email protected]>
34
 */
35
class OrderController extends FOSRestController
36
{
37
    /**
38
     * List orders of the current customer.
39
     *
40
     * @return Response
41
     */
42
    public function indexAction()
43
    {
44
        $orders = $this->getOrderRepository()->findBy(['customer' => $this->getCustomer()], ['updatedAt' => 'desc']);
45
46
        $view = $this
47
            ->view()
48
            ->setTemplate('SyliusWebBundle:Frontend/Account:Order/index.html.twig')
49
            ->setData([
50
                'orders' => $orders,
51
            ])
52
        ;
53
54
        return $this->handleView($view);
55
    }
56
57
    /**
58
     * Get single order of the current customer.
59
     *
60
     * @param string $number
61
     *
62
     * @return Response
63
     *
64
     * @throws NotFoundHttpException
65
     * @throws AccessDeniedException
66
     */
67
    public function showAction($number)
68
    {
69
        $order = $this->findOrderOr404($number);
70
        $this->checkAccessToOrder($order);
71
72
        $view = $this
73
            ->view()
74
            ->setTemplate('SyliusWebBundle:Frontend/Account:Order/show.html.twig')
75
            ->setData([
76
                'order' => $order,
77
            ])
78
        ;
79
80
        return $this->handleView($view);
81
    }
82
83
    /**
84
     * Renders an invoice as PDF.
85
     *
86
     * @param Request $request
87
     * @param string  $number
88
     *
89
     * @return Response
90
     *
91
     * @throws NotFoundHttpException
92
     * @throws AccessDeniedException
93
     */
94
    public function renderInvoiceAction(Request $request, $number)
95
    {
96
        $order = $this->findOrderOr404($number);
97
        $this->checkAccessToOrder($order);
98
99
        if (!$order->isInvoiceAvailable()) {
100
            throw $this->createNotFoundException('The invoice can not yet be generated.');
101
        }
102
103
        $html = $this->renderView('SyliusWebBundle:Frontend/Account:Order/invoice.html.twig', [
104
            'order' => $order,
105
        ]);
106
107
        $generator = $this
108
            ->get('knp_snappy.pdf')
109
            ->getInternalGenerator();
110
111
        $generator->setOptions([
112
            'footer-left' => '[title]',
113
            'footer-right' => '[page]/[topage]',
114
            'footer-line' => true,
115
            'footer-font-name' => '"Helvetica Neue",​Helvetica,​Arial,​sans-serif',
116
            'footer-font-size' => 10,
117
            'viewport-size' => '1200x1024',
118
            'margin-top' => 10,
119
            'margin-right' => 5,
120
            'margin-bottom' => 10,
121
            'margin-left' => 5,
122
        ]);
123
124
        return new Response(
125
            $generator->getOutputFromHtml($html),
126
            200,
127
            [
128
                'Content-Type' => 'application/pdf',
129
                'Content-Disposition' => 'attachment; filename="'.$order->getNumber().'.pdf"',
130
            ]
131
        );
132
    }
133
134
    /**
135
     * @param string $number
136
     *
137
     * @return Response
138
     */
139
    public function showPaymentsAction($number)
140
    {
141
        $order = $this->findOrderOr404($number);
142
        $this->checkAccessToOrder($order);
143
144
        if ($order->getLastPayment(PaymentInterface::STATE_COMPLETED)) {
145
            return $this->redirectToRoute('sylius_checkout_thank_you', ['id' => $order->getId()]);
146
        }
147
148
        $this->get('sylius.order_processing.payment_processor')->processOrderPayments($order);
149
        $this->getOrderManager()->flush();
150
151
        return $this->render('SyliusWebBundle:Frontend/Account/Order:showPayments.html.twig', ['order' => $order]);
152
    }
153
154
    /**
155
     * @param Request $request
156
     *
157
     * @return Response
158
     */
159
    public function afterPurchaseAction(Request $request)
160
    {
161
        $token = $this->getHttpRequestVerifier()->verify($request);
162
        $this->getHttpRequestVerifier()->invalidate($token);
163
164
        $status = new GetStatus($token);
165
        $this->getPayum()->getGateway($token->getGatewayName())->execute($status);
166
        $payment = $status->getFirstModel();
167
        $order = $payment->getOrder();
168
        $this->checkAccessToOrder($order);
169
170
        $orderStateResolver = $this->get('sylius.order_processing.state_resolver');
171
        $orderStateResolver->resolvePaymentState($order);
172
        $orderStateResolver->resolveShippingState($order);
173
174
        $this->getOrderManager()->flush();
175
        if ($status->isCanceled() || $status->isFailed()) {
176
            return $this->redirectToRoute('sylius_order_payment_index', ['number' => $order->getNumber()]);
177
        }
178
179
        return $this->redirectToRoute('sylius_checkout_thank_you');
180
    }
181
182
    /**
183
     * @param mixed $paymentId
184
     *
185
     * @return Response
186
     */
187
    public function purchaseAction($paymentId)
188
    {
189
        $paymentRepository = $this->get('sylius.repository.payment');
190
        $payment = $paymentRepository->find($paymentId);
191
192
        $captureToken = $this->getTokenFactory()->createCaptureToken(
193
            $payment->getMethod()->getGateway(),
194
            $payment,
195
            'sylius_order_after_purchase'
196
        );
197
198
        return $this->redirect($captureToken->getTargetUrl());
199
    }
200
201
    /**
202
     * @return OrderRepositoryInterface
203
     */
204
    protected function getOrderRepository()
205
    {
206
        return $this->get('sylius.repository.order');
207
    }
208
209
    /**
210
     * @param string $number
211
     *
212
     * @return OrderInterface
213
     *
214
     * @throws NotFoundHttpException
215
     */
216
    protected function findOrderOr404($number)
217
    {
218
        /* @var $order OrderInterface */
219
        if (null === $order = $this->getOrderRepository()->findOneBy(['number' => $number])) {
220
            throw $this->createNotFoundException('The order does not exist.');
221
        }
222
223
        return $order;
224
    }
225
226
    /**
227
     * @param OrderInterface $order
228
     *
229
     * @throws AccessDeniedException
230
     */
231
    protected function checkAccessToOrder(OrderInterface $order)
232
    {
233
        $customerGuestId = $this->get('session')->get('sylius_customer_guest_id');
234
        $customerGuest = null;
235
236
        if (null !== $customerGuestId) {
237
            $customerGuest = $this->get('sylius.repository.customer')->find($customerGuestId);
238
        }
239
240
        $loggedInCustomer = $this->getCustomer();
241
        $expectedCustomer = $order->getCustomer();
242
243
        if ($expectedCustomer !== $customerGuest && $expectedCustomer !== $loggedInCustomer) {
244
            throw $this->createAccessDeniedException();
245
        }
246
    }
247
248
    /**
249
     * @return null|CustomerInterface
250
     */
251
    protected function getCustomer()
252
    {
253
        return $this->get('sylius.context.customer')->getCustomer();
254
    }
255
256
    /**
257
     * @return RegistryInterface
258
     */
259
    protected function getPayum()
260
    {
261
        return $this->get('payum');
262
    }
263
264
    /**
265
     * @return GenericTokenFactoryInterface
266
     */
267
    protected function getTokenFactory()
268
    {
269
        return $this->get('payum.security.token_factory');
270
    }
271
272
    /**
273
     * @return HttpRequestVerifierInterface
274
     */
275
    protected function getHttpRequestVerifier()
276
    {
277
        return $this->get('payum.security.http_request_verifier');
278
    }
279
280
    /**
281
     * @param OrderInterface $order
282
     *
283
     * @return FormInterface
284
     */
285
    protected function createCheckoutPaymentForm(OrderInterface $order)
286
    {
287
        return $this->createForm('sylius_checkout_payment', $order);
288
    }
289
290
    /**
291
     * @return EntityManager
292
     */
293
    protected function getOrderManager()
294
    {
295
        return $this->get('sylius.manager.order');
296
    }
297
}
298