Completed
Push — master ( b4c2b2...50fde4 )
by Torben
86:18 queued 41:18
created

PaymentController::failureAction()   B

Complexity

Conditions 4
Paths 6

Size

Total Lines 35
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 0 Features 3
Metric Value
c 4
b 0
f 3
dl 0
loc 35
rs 8.5806
cc 4
eloc 18
nc 6
nop 2
1
<?php
2
namespace DERHANSEN\SfEventMgt\Controller;
3
4
/*
5
 * This file is part of the TYPO3 CMS project.
6
 *
7
 * It is free software; you can redistribute it and/or modify it under
8
 * the terms of the GNU General Public License, either version 2
9
 * of the License, or any later version.
10
 *
11
 * For the full copyright and license information, please read the
12
 * LICENSE.txt file that was distributed with this source code.
13
 *
14
 * The TYPO3 project - inspiring people to share!
15
 */
16
17
use DERHANSEN\SfEventMgt\Domain\Repository\RegistrationRepository;
18
use DERHANSEN\SfEventMgt\Payment\Exception\PaymentException;
19
use DERHANSEN\SfEventMgt\Service\RegistrationService;
20
use TYPO3\CMS\Extbase\Security\Cryptography\HashService;
21
use TYPO3\CMS\Core\Utility\GeneralUtility;
22
use TYPO3\CMS\Extbase\Mvc\RequestInterface;
23
use TYPO3\CMS\Extbase\Mvc\ResponseInterface;
24
use DERHANSEN\SfEventMgt\Service\PaymentService;
25
use TYPO3\CMS\Extbase\Security\Exception\InvalidHashException;
26
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
27
28
/**
29
 * PaymentController
30
 *
31
 * @author Torben Hansen <[email protected]>
32
 */
33
class PaymentController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController
34
{
35
36
    /**
37
     * PaymentService
38
     *
39
     * @var PaymentService
40
     */
41
    protected $paymentService;
42
43
    /**
44
     * Hash Service
45
     *
46
     * @var \TYPO3\CMS\Extbase\Security\Cryptography\HashService
47
     */
48
    protected $hashService;
49
50
    /**
51
     * Registration repository
52
     *
53
     * @var \DERHANSEN\SfEventMgt\Domain\Repository\RegistrationRepository
54
     */
55
    protected $registrationRepository = null;
56
57
    /**
58
     * Registration Service
59
     *
60
     * @var \DERHANSEN\SfEventMgt\Service\RegistrationService
61
     */
62
    protected $registrationService;
63
64
    /**
65
     * DI for paymentService
66
     *
67
     * @param PaymentService $paymentService
68
     */
69
    public function injectPaymentService(PaymentService $paymentService)
70
    {
71
        $this->paymentService = $paymentService;
72
    }
73
74
    /**
75
     * DI for hashService
76
     *
77
     * @param HashService $hashService
78
     */
79
    public function injectHashService(HashService $hashService)
80
    {
81
        $this->hashService = $hashService;
82
    }
83
84
    /**
85
     * DI for registrationRepository
86
     *
87
     * @param RegistrationRepository $registrationRepository
88
     */
89
    public function injectRegistrationRepository(RegistrationRepository $registrationRepository)
90
    {
91
        $this->registrationRepository = $registrationRepository;
92
    }
93
94
    /**
95
     * DI for registrationService
96
     *
97
     * @param RegistrationService $registrationService
98
     */
99
    public function injectRegistrationService(RegistrationService $registrationService)
100
    {
101
        $this->registrationService = $registrationService;
102
    }
103
104
    /**
105
     * Catches all PaymentExceptions and sets the Exception message to the response content
106
     *
107
     * @param RequestInterface $request
108
     * @param ResponseInterface $response
109
     * @throws \TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException
110
     */
111
    public function processRequest(RequestInterface $request, ResponseInterface $response)
112
    {
113
        try {
114
            parent::processRequest($request, $response);
115
        } catch (\DERHANSEN\SfEventMgt\Exception $e) {
116
            $response->setContent('<div class="payment-error">' . $e->getMessage() . '</div>');
117
        } catch (\TYPO3\CMS\Extbase\Security\Exception\InvalidHashException $e) {
0 ignored issues
show
Bug introduced by
The class TYPO3\CMS\Extbase\Securi...on\InvalidHashException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
118
            $response->setContent('<div class="payment-error">' . $e->getMessage() . '</div>');
119
        }
120
    }
121
122
    /**
123
     * Redirect to payment provider
124
     *
125
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Registration $registration
126
     * @param string $hmac
127
     */
128
    public function redirectAction($registration, $hmac)
129
    {
130
        $this->validateHmacForAction($registration, $hmac, $this->actionMethodName);
131
        $this->proceedWithAction($registration, $this->actionMethodName);
132
133
        $values = [
134
            'sfEventMgtSettings' => $this->settings,
135
            'successUrl' => $this->getPaymentUriForAction('success', $registration),
136
            'failureUrl' => $this->getPaymentUriForAction('failure', $registration),
137
            'cancelUrl' => $this->getPaymentUriForAction('cancel', $registration),
138
            'notifyUrl' => $this->getPaymentUriForAction('notify', $registration),
139
            'registration' => $registration,
140
            'html' => ''
141
        ];
142
143
        $paymentMethod = $registration->getPaymentmethod();
144
145
        /**
146
         * If true, the externally called BeforeRedirect method requested, that the registration should be updated
147
         */
148
        $updateRegistration = false;
149
150
        $this->signalSlotDispatcher->dispatch(
151
            __CLASS__,
152
            __FUNCTION__ . 'BeforeRedirect' . ucfirst($paymentMethod),
153
            [&$values, &$updateRegistration, $registration, $this]
154
        );
155
156
        if ($updateRegistration) {
157
            $this->registrationRepository->update($registration);
158
        }
159
160
        $this->view->assign('result', $values);
161
    }
162
163
    /**
164
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Registration $registration
165
     * @param string $hmac
166
     */
167
    public function successAction($registration, $hmac)
168
    {
169
        $this->validateHmacForAction($registration, $hmac, $this->actionMethodName);
170
        $this->proceedWithAction($registration, $this->actionMethodName);
171
172
        $values = ['html' => ''];
173
174
        $paymentMethod = $registration->getPaymentmethod();
175
176
        /**
177
         * If true, the externally called ProcessSuccess method requested, that the registration should be updated
178
         */
179
        $updateRegistration = false;
180
181
        $this->signalSlotDispatcher->dispatch(
182
            __CLASS__,
183
            __FUNCTION__ . 'ProcessSuccess' . ucfirst($paymentMethod),
184
            [&$values, &$updateRegistration, $registration, GeneralUtility::_GET(), $this]
185
        );
186
187
        if ($updateRegistration) {
188
            $this->registrationRepository->update($registration);
189
        }
190
191
        $this->view->assign('result', $values);
192
    }
193
194
    /**
195
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Registration $registration
196
     * @param string $hmac
197
     */
198
    public function failureAction($registration, $hmac)
199
    {
200
        $this->validateHmacForAction($registration, $hmac, $this->actionMethodName);
201
        $this->proceedWithAction($registration, $this->actionMethodName);
202
203
        $values = ['html' => ''];
204
205
        $paymentMethod = $registration->getPaymentmethod();
206
207
        /**
208
         * Update- and remove flags
209
         */
210
        $updateRegistration = false;
211
        $removeRegistration = false;
212
213
        $this->signalSlotDispatcher->dispatch(
214
            __CLASS__,
215
            __FUNCTION__ . 'ProcessFailure' . ucfirst($paymentMethod),
216
            [&$values, &$updateRegistration, &$removeRegistration, $registration, GeneralUtility::_GET(), $this]
217
        );
218
219
        if ($updateRegistration) {
220
            $this->registrationRepository->update($registration);
221
        }
222
223
        if ($removeRegistration) {
224
            // First cancel depending registrations
225
            if ($registration->getAmountOfRegistrations() > 1) {
226
                $this->registrationService->cancelDependingRegistrations($registration);
227
            }
228
            $this->registrationRepository->remove($registration);
229
        }
230
231
        $this->view->assign('result', $values);
232
    }
233
234
    /**
235
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Registration $registration
236
     * @param string $hmac
237
     */
238
    public function cancelAction($registration, $hmac)
239
    {
240
        $this->validateHmacForAction($registration, $hmac, $this->actionMethodName);
241
        $this->proceedWithAction($registration, $this->actionMethodName);
242
243
        $values = ['html' => ''];
244
245
        $paymentMethod = $registration->getPaymentmethod();
246
247
        /**
248
         * Update- and remove flags
249
         */
250
        $updateRegistration = false;
251
        $removeRegistration = false;
252
253
        $this->signalSlotDispatcher->dispatch(
254
            __CLASS__,
255
            __FUNCTION__ . 'ProcessCancel' . ucfirst($paymentMethod),
256
            [&$values, &$updateRegistration, &$removeRegistration, $registration, GeneralUtility::_GET(), $this]
257
        );
258
259
        if ($updateRegistration) {
260
            $this->registrationRepository->update($registration);
261
        }
262
263
        if ($removeRegistration) {
264
            // First cancel depending registrations
265
            if ($registration->getAmountOfRegistrations() > 1) {
266
                $this->registrationService->cancelDependingRegistrations($registration);
267
            }
268
            $this->registrationRepository->remove($registration);
269
        }
270
271
        $this->view->assign('result', $values);
272
    }
273
274
    /**
275
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Registration $registration
276
     * @param string $hmac
277
     */
278
    public function notifyAction($registration, $hmac)
279
    {
280
        $this->validateHmacForAction($registration, $hmac, $this->actionMethodName);
281
        $this->proceedWithAction($registration, $this->actionMethodName);
282
283
        $values = ['html' => ''];
284
285
        $paymentMethod = $registration->getPaymentmethod();
286
287
        /**
288
         * Initialize update-flag
289
         *
290
         * If true, the externally called ProcessNotify method requested, that the registration should be updated
291
         */
292
        $updateRegistration = false;
293
294
        $this->signalSlotDispatcher->dispatch(
295
            __CLASS__,
296
            __FUNCTION__ . 'ProcessNotify' . ucfirst($paymentMethod),
297
            [&$values, &$updateRegistration, $registration, GeneralUtility::_GET(), $this]
298
        );
299
300
        if ($updateRegistration) {
301
            $this->registrationRepository->update($registration);
302
        }
303
304
        $this->view->assign('result', $values);
305
    }
306
307
    /**
308
     * Checks if the given action can be called for the given registration / event and throws
309
     * an exception if action should not proceed
310
     *
311
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Registration $registration
312
     * @param string $actionName
313
     * @throws PaymentException
314
     * @return void
315
     */
316
    protected function proceedWithAction($registration, $actionName)
317
    {
318
        if ($registration->getEvent()->getEnablePayment() === false) {
319
            $message = LocalizationUtility::translate('payment.messages.paymentNotEnabled', 'sf_event_mgt');
320
            throw new PaymentException($message, 1899934881);
321
        }
322
323
        if ($this->paymentService->paymentActionEnabled($registration->getPaymentmethod(), $actionName) === false) {
324
            $message = LocalizationUtility::translate('payment.messages.actionNotEnabled', 'sf_event_mgt');
325
            throw new PaymentException($message, 1899934882);
326
        }
327
328
        if ($registration->getPaid()) {
329
            $message = LocalizationUtility::translate('payment.messages.paymentAlreadyProcessed', 'sf_event_mgt');
330
            throw new PaymentException($message, 1899934883);
331
        }
332
333
        if ($registration->getEvent()->getRestrictPaymentMethods()) {
334
            $selectedPaymentMethods = explode(',', $registration->getEvent()->getSelectedPaymentMethods());
335
            if (!in_array($registration->getPaymentmethod(), $selectedPaymentMethods)) {
336
                $message = LocalizationUtility::translate('payment.messages.paymentMethodNotAvailable', 'sf_event_mgt');
337
                throw new PaymentException($message, 1899934884);
338
            }
339
        }
340
    }
341
342
    /**
343
     * Checks the HMAC for the given action and registration
344
     *
345
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Registration $registration
346
     * @param string $hmac
347
     * @param string $action
348
     * @throws InvalidHashException
349
     */
350
    protected function validateHmacForAction($registration, $hmac, $action)
351
    {
352
        $result = $this->hashService->validateHmac($action . '-' . $registration->getUid(), $hmac);
353
        if (!$result) {
354
            $message = LocalizationUtility::translate('payment.messages.invalidHmac', 'sf_event_mgt');
355
            throw new InvalidHashException($message, 1899934890);
356
        }
357
    }
358
359
    /**
360
     * Returns the payment Uri for the given action and registration
361
     *
362
     * @param string $action
363
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Registration $registration
364
     * @return string
365
     * @throws \TYPO3\CMS\Extbase\Security\Exception\InvalidArgumentForHashGenerationException
366
     */
367
    protected function getPaymentUriForAction($action, $registration)
368
    {
369
        $this->uriBuilder
370
            ->setCreateAbsoluteUri(true)
371
            ->setUseCacheHash(false);
372
        return $this->uriBuilder->uriFor(
373
            $action,
374
            [
375
                'registration' => $registration,
376
                'hmac' => $this->hashService->generateHmac($action . 'Action-' . $registration->getUid())
377
            ],
378
            'Payment',
379
            'sfeventmgt',
380
            'Pipayment'
381
        );
382
    }
383
384
}
385