Completed
Push — development ( 640c04...189908 )
by Torben
09:05 queued 03:50
created

PaymentController::injectPaymentService()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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