Completed
Push — payment ( 9605b6...5a9190 )
by Torben
54:44 queued 09:45
created

PaymentController::injectRegistrationService()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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