Completed
Push — payment ( 7231cf...1f89f9 )
by Torben
41:55
created

PaymentController::proceedWithAction()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 25
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 25
rs 8.5806
cc 4
eloc 10
nc 4
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 TYPO3\CMS\Extbase\Security\Cryptography\HashService;
20
use TYPO3\CMS\Core\Utility\GeneralUtility;
21
use TYPO3\CMS\Extbase\Mvc\RequestInterface;
22
use TYPO3\CMS\Extbase\Mvc\ResponseInterface;
23
use DERHANSEN\SfEventMgt\Service\PaymentService;
24
use TYPO3\CMS\Extbase\Security\Exception\InvalidHashException;
25
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
26
27
/**
28
 * PaymentController
29
 *
30
 * @author Torben Hansen <[email protected]>
31
 */
32
class PaymentController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController
33
{
34
35
    /**
36
     * PaymentService
37
     *
38
     * @var PaymentService
39
     */
40
    protected $paymentService;
41
42
    /**
43
     * Hash Service
44
     *
45
     * @var \TYPO3\CMS\Extbase\Security\Cryptography\HashService
46
     */
47
    protected $hashService;
48
49
    /**
50
     * Registration repository
51
     *
52
     * @var \DERHANSEN\SfEventMgt\Domain\Repository\RegistrationRepository
53
     */
54
    protected $registrationRepository = null;
55
56
    /**
57
     * DI for paymentService
58
     *
59
     * @param PaymentService $paymentService
60
     */
61
    public function injectPaymentService(PaymentService $paymentService)
62
    {
63
        $this->paymentService = $paymentService;
64
    }
65
66
    /**
67
     * DI for hashService
68
     *
69
     * @param HashService $hashService
70
     */
71
    public function injectHashService(HashService $hashService)
72
    {
73
        $this->hashService = $hashService;
74
    }
75
76
    /**
77
     * DI for registrationRepository
78
     *
79
     * @param RegistrationRepository $registrationRepository
80
     */
81
    public function injectRegistrationRepository(RegistrationRepository $registrationRepository)
82
    {
83
        $this->registrationRepository = $registrationRepository;
84
    }
85
86
    /**
87
     * Catches all PaymentExceptions and sets the Exception message to the response content
88
     *
89
     * @param RequestInterface $request
90
     * @param ResponseInterface $response
91
     * @throws \TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException
92
     */
93
    public function processRequest(RequestInterface $request, ResponseInterface $response)
94
    {
95
        try {
96
            parent::processRequest($request, $response);
97
        } catch (\DERHANSEN\SfEventMgt\Exception $e) {
98
            $response->setContent('<div class="payment-error">' . $e->getMessage() . '</div>');
99
        } 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...
100
            $response->setContent('<div class="payment-error">' . $e->getMessage() . '</div>');
101
        }
102
    }
103
104
    /**
105
     * Redirect to payment provider
106
     *
107
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Registration $registration
108
     * @param string $hmac
109
     */
110
    public function redirectAction($registration, $hmac)
111
    {
112
        $this->validateHmacForAction($registration, $hmac, $this->actionMethodName);
113
        $this->proceedWithAction($registration, $this->actionMethodName);
114
115
        $values = [
116
            'sfEventMgtSettings' => $this->settings,
117
            'successUrl' => $this->getPaymentUriForAction('success', $registration),
118
            'failureUrl' => $this->getPaymentUriForAction('failure', $registration),
119
            'cancelUrl' => $this->getPaymentUriForAction('cancel', $registration),
120
            'notifyUrl' => $this->getPaymentUriForAction('notify', $registration),
121
            'registration' => $registration,
122
            'html' => ''
123
        ];
124
125
        $paymentMethod = $registration->getPaymentmethod();
126
127
        /**
128
         * If true, the externally called BeforeRedirect method was successful and the registration can be updated
129
         */
130
        $updateRegistration = false;
131
        $this->signalSlotDispatcher->dispatch(
132
            __CLASS__,
133
            __FUNCTION__ . 'BeforeRedirect' . ucfirst($paymentMethod),
134
            [&$values, &$updateRegistration, $registration, $this]
135
        );
136
137
        if ($updateRegistration) {
138
            $this->registrationRepository->update($registration);
139
        }
140
141
        $this->view->assign('result', $values);
142
    }
143
144
    /**
145
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Registration $registration
146
     * @param string $hmac
147
     */
148
    public function successAction($registration, $hmac)
149
    {
150
        $this->validateHmacForAction($registration, $hmac, $this->actionMethodName);
151
        $this->proceedWithAction($registration, $this->actionMethodName);
152
153
        $values = ['html' => ''];
154
155
        $paymentMethod = $registration->getPaymentmethod();
156
157
        /**
158
         * If true, the externally called ProcessSuccess method was successful and the registration can be updated
159
         */
160
        $updateRegistration = false;
161
        $this->signalSlotDispatcher->dispatch(
162
            __CLASS__,
163
            __FUNCTION__ . 'ProcessSuccess' . ucfirst($paymentMethod),
164
            [&$values, &$updateRegistration, $registration, GeneralUtility::_GET(), $this]
165
        );
166
167
        if ($updateRegistration) {
168
            $this->registrationRepository->update($registration);
169
        }
170
171
        $this->view->assign('result', $values);
172
    }
173
174
    /**
175
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Registration $registration
176
     * @param string $hmac
177
     */
178
    public function failureAction($registration, $hmac)
179
    {
180
        $this->validateHmacForAction($registration, $hmac, $this->actionMethodName);
181
        $this->proceedWithAction($registration, $this->actionMethodName);
182
183
        $values = ['html' => ''];
184
185
        $paymentMethod = $registration->getPaymentmethod();
186
187
        /**
188
         * If true, the externally called ProcessSuccess method was successful and the registration can be updated
189
         */
190
        $updateRegistration = false;
191
        $this->signalSlotDispatcher->dispatch(
192
            __CLASS__,
193
            __FUNCTION__ . 'ProcessFailure' . ucfirst($paymentMethod),
194
            [&$values, &$updateRegistration, $registration, GeneralUtility::_GET(), $this]
195
        );
196
197
        if ($updateRegistration) {
198
            $this->registrationRepository->update($registration);
199
        }
200
201
        $this->view->assign('result', $values);
202
    }
203
204
    /**
205
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Registration $registration
206
     * @param string $hmac
207
     */
208
    public function cancelAction($registration, $hmac)
209
    {
210
        $this->validateHmacForAction($registration, $hmac, $this->actionMethodName);
211
        $this->proceedWithAction($registration, $this->actionMethodName);
212
213
        $values = ['html' => ''];
214
215
        $paymentMethod = $registration->getPaymentmethod();
216
217
        /**
218
         * If true, the externally called ProcessSuccess method was successful and the registration can be updated
219
         */
220
        $updateRegistration = false;
221
        $this->signalSlotDispatcher->dispatch(
222
            __CLASS__,
223
            __FUNCTION__ . 'ProcessCancel' . ucfirst($paymentMethod),
224
            [&$values, &$updateRegistration, $registration, GeneralUtility::_GET(), $this]
225
        );
226
227
        if ($updateRegistration) {
228
            $this->registrationRepository->update($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 notifyAction($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
         * If true, the externally called ProcessSuccess method was successful and the registration can be updated
249
         */
250
        $updateRegistration = false;
251
        $this->signalSlotDispatcher->dispatch(
252
            __CLASS__,
253
            __FUNCTION__ . 'ProcessNotify' . ucfirst($paymentMethod),
254
            [&$values, &$updateRegistration, $registration, GeneralUtility::_GET(), $this]
255
        );
256
257
        if ($updateRegistration) {
258
            $this->registrationRepository->update($registration);
259
        }
260
261
        $this->view->assign('result', $values);
262
    }
263
264
    /**
265
     * Checks if the given action can be called for the given registration / event and throws
266
     * an exception if action should not proceed
267
     *
268
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Registration $registration
269
     * @param string $actionName
270
     * @throws PaymentException
271
     * @return void
272
     */
273
    protected function proceedWithAction($registration, $actionName)
274
    {
275
        if ($registration->getEvent()->getEnablePayment() === false) {
276
            $message = LocalizationUtility::translate('payment.messages.paymentNotEnabled', 'sf_event_mgt');
277
            throw new PaymentException($message, 1899934881);
278
        }
279
280
        if ($this->paymentService->paymentActionEnabled($registration->getPaymentmethod(), $actionName) === false) {
281
            $message = LocalizationUtility::translate('payment.messages.actionNotEnabled', 'sf_event_mgt');
282
            throw new PaymentException($message, 1899934882);
283
        }
284
285
        if ($registration->getPaid()) {
286
            $message = LocalizationUtility::translate('payment.messages.paymentAlreadyProcessed', 'sf_event_mgt');
287
            throw new PaymentException($message, 1899934883);
288
        }
289
290
        // @todo - Should do the following:
291
        // 1. Check, if payment is enabled for Event (OK)
292
        // 2. Check, if payment method is enabled for Event
293
        // 3. Check, if action is configured for payment method (OK)
294
        // 4. Check, if "paid" is false for registration (OK)
295
        // If a condition does not match, throw a PaymentException
296
        // @todo - move to service
297
    }
298
299
    /**
300
     * Checks the HMAC for the given action and registration
301
     *
302
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Registration $registration
303
     * @param string $hmac
304
     * @param string $action
305
     * @throws InvalidHashException
306
     */
307
    protected function validateHmacForAction($registration, $hmac, $action)
308
    {
309
        $result = $this->hashService->validateHmac($action . '-' . $registration->getUid(), $hmac);
310
        if (!$result) {
311
            $message = LocalizationUtility::translate('payment.messages.invalidHmac', 'sf_event_mgt');
312
            throw new InvalidHashException($message, 1899934890);
313
        }
314
    }
315
316
    /**
317
     * Returns the payment Uri for the given action and registration
318
     *
319
     * @param string $action
320
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Registration $registration
321
     * @return string
322
     * @throws \TYPO3\CMS\Extbase\Security\Exception\InvalidArgumentForHashGenerationException
323
     */
324
    protected function getPaymentUriForAction($action, $registration)
325
    {
326
        $this->uriBuilder
327
            ->setCreateAbsoluteUri(true)
328
            ->setUseCacheHash(false);
329
        return $this->uriBuilder->uriFor(
330
            $action,
331
            [
332
                'registration' => $registration,
333
                'hmac' => $this->hashService->generateHmac($action . 'Action-' . $registration->getUid())
334
            ],
335
            'Payment',
336
            'sfeventmgt',
337
            'Pipayment'
338
        );
339
    }
340
341
}
342