Passed
Push — master ( da5c3a...138f6a )
by Torben
132:09 queued 128:49
created

PaymentController::proceedWithAction()   A

Complexity

Conditions 6
Paths 6

Size

Total Lines 22
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 6

Importance

Changes 0
Metric Value
cc 6
eloc 14
nc 6
nop 2
dl 0
loc 22
ccs 11
cts 11
cp 1
crap 6
rs 9.2222
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of the Extension "sf_event_mgt" for TYPO3 CMS.
5
 *
6
 * For the full copyright and license information, please read the
7
 * LICENSE.txt file that was distributed with this source code.
8
 */
9
10
namespace DERHANSEN\SfEventMgt\Controller;
11
12
use DERHANSEN\SfEventMgt\Event\ProcessPaymentCancelEvent;
13
use DERHANSEN\SfEventMgt\Event\ProcessPaymentFailureEvent;
14
use DERHANSEN\SfEventMgt\Event\ProcessPaymentInitializeEvent;
15
use DERHANSEN\SfEventMgt\Event\ProcessPaymentNotifyEvent;
16
use DERHANSEN\SfEventMgt\Event\ProcessPaymentSuccessEvent;
17
use DERHANSEN\SfEventMgt\Payment\Exception\PaymentException;
18
use TYPO3\CMS\Core\Utility\GeneralUtility;
19
use TYPO3\CMS\Extbase\Mvc\RequestInterface;
20
use TYPO3\CMS\Extbase\Mvc\ResponseInterface;
21
use TYPO3\CMS\Extbase\Security\Exception\InvalidHashException;
22
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
23
24
/**
25
 * PaymentController
26
 */
27
class PaymentController extends AbstractController
28
{
29
    /**
30
     * Catches all PaymentExceptions and sets the Exception message to the response content
31
     *
32
     * @param RequestInterface $request
33
     * @param ResponseInterface $response
34
     * @throws \TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException
35
     */
36
    public function processRequest(RequestInterface $request, ResponseInterface $response)
37
    {
38
        try {
39
            parent::processRequest($request, $response);
40
        } catch (\DERHANSEN\SfEventMgt\Exception $e) {
41
            $response->setContent('<div class="payment-error">' . $e->getMessage() . '</div>');
42
        } catch (\TYPO3\CMS\Extbase\Security\Exception\InvalidHashException $e) {
43
            $response->setContent('<div class="payment-error">' . $e->getMessage() . '</div>');
44
        }
45
    }
46
47
    /**
48
     * Redirect to payment provider
49
     *
50
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Registration $registration
51
     * @param string $hmac
52
     */
53
    public function redirectAction($registration, $hmac)
54
    {
55
        $this->validateHmacForAction($registration, $hmac, $this->actionMethodName);
56
        $this->proceedWithAction($registration, $this->actionMethodName);
57
58
        $variables = [
59
            'sfEventMgtSettings' => $this->settings,
60
            'successUrl' => $this->getPaymentUriForAction('success', $registration),
61
            'failureUrl' => $this->getPaymentUriForAction('failure', $registration),
62
            'cancelUrl' => $this->getPaymentUriForAction('cancel', $registration),
63
            'notifyUrl' => $this->getPaymentUriForAction('notify', $registration),
64
            'registration' => $registration,
65
            'html' => ''
66
        ];
67
68
        $paymentMethod = $registration->getPaymentmethod();
69
70
        /**
71
         * If true, the externally called BeforeRedirect method requested, that the registration should be updated
72
         */
73
        $updateRegistration = false;
74
75
        $processPaymentInitializeEvent = new ProcessPaymentInitializeEvent(
76
            $variables,
77
            $paymentMethod,
78
            $updateRegistration,
79 10
            $registration,
80
            $this
81 10
        );
82 10
        $this->eventDispatcher->dispatch($processPaymentInitializeEvent);
83
        $variables = $processPaymentInitializeEvent->getVariables();
84
        $updateRegistration = $processPaymentInitializeEvent->getUpdateRegistration();
85
86
        if ($updateRegistration) {
87
            $this->registrationRepository->update($registration);
88
        }
89
90
        $this->view->assign('result', $variables);
91
    }
92
93
    /**
94
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Registration $registration
95
     * @param string $hmac
96
     */
97
    public function successAction($registration, $hmac)
98
    {
99
        $this->validateHmacForAction($registration, $hmac, $this->actionMethodName);
100
        $this->proceedWithAction($registration, $this->actionMethodName);
101
102
        $variables = ['html' => ''];
103
104
        $paymentMethod = $registration->getPaymentmethod();
105
106
        /**
107
         * If true, the externally called ProcessSuccess method requested, that the registration should be updated
108
         */
109
        $updateRegistration = false;
110
111
        $getVariables = is_array(GeneralUtility::_GET()) ? GeneralUtility::_GET() : [];
112
        $processPaymentSuccessEvent = new ProcessPaymentSuccessEvent(
113
            $variables,
114
            $paymentMethod,
115
            $updateRegistration,
116
            $registration,
117
            $getVariables,
118
            $this
119
        );
120
        $this->eventDispatcher->dispatch($processPaymentSuccessEvent);
121
        $variables = $processPaymentSuccessEvent->getVariables();
122
        $updateRegistration = $processPaymentSuccessEvent->getUpdateRegistration();
123
124
        if ($updateRegistration) {
125
            $this->registrationRepository->update($registration);
126
        }
127
128 2
        $this->view->assign('result', $variables);
129
    }
130 2
131 2
    /**
132
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Registration $registration
133
     * @param string $hmac
134 2
     */
135 2
    public function failureAction($registration, $hmac)
136 2
    {
137 2
        $this->validateHmacForAction($registration, $hmac, $this->actionMethodName);
138 2
        $this->proceedWithAction($registration, $this->actionMethodName);
139 2
140
        $variables = ['html' => ''];
141 2
142
        $paymentMethod = $registration->getPaymentmethod();
143 2
144
        /**
145
         * Update- and remove flags
146
         */
147
        $updateRegistration = false;
148 2
        $removeRegistration = false;
149
150 2
        $getVariables = is_array(GeneralUtility::_GET()) ? GeneralUtility::_GET() : [];
151 2
        $processPaymentFailureEvent = new ProcessPaymentFailureEvent(
152 2
            $variables,
153 2
            $paymentMethod,
154 2
            $updateRegistration,
155
            $removeRegistration,
156 2
            $registration,
157
            $getVariables,
158
            $this
159
        );
160 2
        $this->eventDispatcher->dispatch($processPaymentFailureEvent);
161 2
        $variables = $processPaymentFailureEvent->getVariables();
162
        $updateRegistration = $processPaymentFailureEvent->getUpdateRegistration();
163
        $removeRegistration = $processPaymentFailureEvent->getRemoveRegistration();
164
165
        if ($updateRegistration) {
166
            $this->registrationRepository->update($registration);
167 2
        }
168
169 2
        if ($removeRegistration) {
170 2
            // First cancel depending registrations
171
            if ($registration->getAmountOfRegistrations() > 1) {
172 2
                $this->registrationService->cancelDependingRegistrations($registration);
173
            }
174 2
            $this->registrationRepository->remove($registration);
175
        }
176
177
        $this->view->assign('result', $variables);
178
    }
179 2
180
    /**
181 2
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Registration $registration
182 2
     * @param string $hmac
183 2
     */
184 2
    public function cancelAction($registration, $hmac)
185 2
    {
186
        $this->validateHmacForAction($registration, $hmac, $this->actionMethodName);
187 2
        $this->proceedWithAction($registration, $this->actionMethodName);
188
189
        $variables = ['html' => ''];
190
191 2
        $paymentMethod = $registration->getPaymentmethod();
192 2
193
        /**
194
         * Update- and remove flags
195
         */
196
        $updateRegistration = false;
197
        $removeRegistration = false;
198 2
199
        $getVariables = is_array(GeneralUtility::_GET()) ? GeneralUtility::_GET() : [];
200 2
        $processPaymentCancelEvent = new ProcessPaymentCancelEvent(
201 2
            $variables,
202
            $paymentMethod,
203 2
            $updateRegistration,
204
            $removeRegistration,
205 2
            $registration,
206
            $getVariables,
207
            $this
208
        );
209
        $this->eventDispatcher->dispatch($processPaymentCancelEvent);
210 2
        $variables = $processPaymentCancelEvent->getVariables();
211 2
        $updateRegistration = $processPaymentCancelEvent->getUpdateRegistration();
212
        $removeRegistration = $processPaymentCancelEvent->getRemoveRegistration();
213 2
214 2
        if ($updateRegistration) {
215 2
            $this->registrationRepository->update($registration);
216 2
        }
217 2
218
        if ($removeRegistration) {
219 2
            // First cancel depending registrations
220
            if ($registration->getAmountOfRegistrations() > 1) {
221
                $this->registrationService->cancelDependingRegistrations($registration);
222
            }
223 2
            $this->registrationRepository->remove($registration);
224
        }
225
226
        $this->view->assign('result', $variables);
227
    }
228
229
    /**
230
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Registration $registration
231 2
     * @param string $hmac
232 2
     */
233
    public function notifyAction($registration, $hmac)
234
    {
235
        $this->validateHmacForAction($registration, $hmac, $this->actionMethodName);
236
        $this->proceedWithAction($registration, $this->actionMethodName);
237
238 2
        $variables = ['html' => ''];
239
240 2
        $paymentMethod = $registration->getPaymentmethod();
241 2
242
        /**
243 2
         * Initialize update-flag
244
         *
245 2
         * If true, the externally called ProcessNotify method requested, that the registration should be updated
246
         */
247
        $updateRegistration = false;
248
249
        $getVariables = is_array(GeneralUtility::_GET()) ? GeneralUtility::_GET() : [];
250 2
        $processPaymentNotifyEvent = new ProcessPaymentNotifyEvent(
251 2
            $variables,
252
            $paymentMethod,
253 2
            $updateRegistration,
254 2
            $registration,
255 2
            $getVariables,
256 2
            $this
257 2
        );
258
        $this->eventDispatcher->dispatch($processPaymentNotifyEvent);
259 2
        $variables = $processPaymentNotifyEvent->getVariables();
260
        $updateRegistration = $processPaymentNotifyEvent->getUpdateRegistration();
261
262
        if ($updateRegistration) {
263 2
            $this->registrationRepository->update($registration);
264
        }
265
266
        $this->view->assign('result', $variables);
267
    }
268
269
    /**
270
     * Checks if the given action can be called for the given registration / event and throws
271 2
     * an exception if action should not proceed
272 2
     *
273
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Registration $registration
274
     * @param string $actionName
275
     * @throws PaymentException
276
     */
277
    protected function proceedWithAction($registration, $actionName)
278 2
    {
279
        if ($registration->getEvent()->getEnablePayment() === false) {
280 2
            $message = LocalizationUtility::translate('payment.messages.paymentNotEnabled', 'SfEventMgt');
281 2
            throw new PaymentException($message, 1899934881);
282
        }
283 2
284
        if ($this->paymentService->paymentActionEnabled($registration->getPaymentmethod(), $actionName) === false) {
285 2
            $message = LocalizationUtility::translate('payment.messages.actionNotEnabled', 'SfEventMgt');
286
            throw new PaymentException($message, 1899934882);
287
        }
288
289
        if ($registration->getPaid()) {
290
            $message = LocalizationUtility::translate('payment.messages.paymentAlreadyProcessed', 'SfEventMgt');
291
            throw new PaymentException($message, 1899934883);
292 2
        }
293
294 2
        if ($registration->getEvent()->getRestrictPaymentMethods()) {
295 2
            $selectedPaymentMethods = explode(',', $registration->getEvent()->getSelectedPaymentMethods());
296 2
            if (!in_array($registration->getPaymentmethod(), $selectedPaymentMethods)) {
297 2
                $message = LocalizationUtility::translate('payment.messages.paymentMethodNotAvailable', 'SfEventMgt');
298 2
                throw new PaymentException($message, 1899934884);
299
            }
300 2
        }
301
    }
302
303
    /**
304 2
     * Checks the HMAC for the given action and registration
305 2
     *
306
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Registration $registration
307
     * @param string $hmac
308
     * @param string $action
309
     * @throws InvalidHashException
310
     */
311
    protected function validateHmacForAction($registration, $hmac, $action)
312
    {
313
        $result = $this->hashService->validateHmac($action . '-' . $registration->getUid(), $hmac);
314
        if (!$result) {
315
            $message = LocalizationUtility::translate('payment.messages.invalidHmac', 'SfEventMgt');
316
            throw new InvalidHashException($message, 1899934890);
317
        }
318
    }
319
320
    /**
321
     * Returns the payment Uri for the given action and registration
322
     *
323
     * @param string $action
324
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Registration $registration
325
     * @throws \TYPO3\CMS\Extbase\Security\Exception\InvalidArgumentForHashGenerationException
326
     * @return string
327
     */
328
    protected function getPaymentUriForAction($action, $registration)
329
    {
330
        $this->uriBuilder
331
            ->setCreateAbsoluteUri(true);
332
333
        return $this->uriBuilder->uriFor(
334
            $action,
335
            [
336
                'registration' => $registration,
337
                'hmac' => $this->hashService->generateHmac($action . 'Action-' . $registration->getUid())
338
            ],
339
            'Payment',
340
            'sfeventmgt',
341
            'Pipayment'
342
        );
343
    }
344
}
345