CartFlow   A
last analyzed

Complexity

Total Complexity 21

Size/Duplication

Total Lines 245
Duplicated Lines 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
eloc 85
c 2
b 1
f 0
dl 0
loc 245
rs 10
wmc 21

9 Methods

Rating   Name   Duplication   Size   Complexity  
A setAllowAnonymous() 0 4 1
A emptyCart() 0 5 1
B handleSubmit() 0 68 10
A setPayum() 0 4 1
A setCartMode() 0 4 1
A handleDone() 0 15 3
A __construct() 0 11 1
A setTokenStorage() 0 4 1
A loadStepsConfig() 0 19 2
1
<?php
2
3
namespace GGGGino\SkuskuCartBundle\Form;
4
5
use Craue\FormFlowBundle\Form\FormFlowInterface;
6
use GGGGino\SkuskuCartBundle\Entity\CartForm;
7
use GGGGino\SkuskuCartBundle\Event\PostPaymentCartEvent;
8
use GGGGino\SkuskuCartBundle\Event\PostSubmitCartEvent;
9
use GGGGino\SkuskuCartBundle\Event\PrePersistOrderEvent;
10
use GGGGino\SkuskuCartBundle\Event\PreSubmitCartEvent;
11
use GGGGino\SkuskuCartBundle\Model\SkuskuCart;
12
use GGGGino\SkuskuCartBundle\Model\SkuskuPayment;
13
use GGGGino\SkuskuCartBundle\Service\CartManager;
14
use GGGGino\SkuskuCartBundle\Service\OrderManager;
15
use Payum\Core\GatewayInterface;
16
use Payum\Core\Payum;
17
use Symfony\Component\Form\FormInterface;
18
use Symfony\Component\HttpFoundation\RedirectResponse;
19
use Symfony\Component\HttpFoundation\RequestStack;
20
use Symfony\Component\HttpFoundation\Response;
21
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
22
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
23
24
class CartFlow extends CartFlowBase
25
{
26
    const PRE_SUBMIT = 'skusku_cart.pre_submit';
27
28
    const POST_SUBMIT = 'skusku_cart.post_submit';
29
30
    const POST_PAYMENT = 'skusku_cart.post_payment';
31
32
    const PRE_PERSIST_ORDER = 'skusku_cart.pre_persist_order';
33
34
    const TRANSITION_RESET_CART = 'emptycart';
35
36
    const TOKEN_NOT_FOUND = 'skusku_cart.token_not_found';
37
38
    /**
39
     * @var CartManager
40
     */
41
    protected $cartManager;
42
43
    /**
44
     * @var RequestStack
45
     */
46
    protected $requestStack;
47
48
    /**
49
     * @var Payum
50
     */
51
    protected $payum;
52
53
    /**
54
     * @var OrderManager
55
     */
56
    protected $orderManager;
57
58
    /**
59
     * @var TokenStorage
60
     */
61
    protected $tokenStorage;
62
63
    /**
64
     * @var bool
65
     */
66
    protected $allowAnonymous;
67
68
    /**
69
     * @var string
70
     */
71
    protected $cartMode;    
72
73
    /**
74
     * CartFlowBase constructor.
75
     * @param array $configSteps
76
     * @param CartManager $cartManager
77
     * @param OrderManager $orderManager
78
     * @param RequestStack $requestStack
79
     */
80
    public function __construct(
81
        array $configSteps,
82
        CartManager $cartManager,
83
        OrderManager $orderManager,
84
        RequestStack $requestStack)
85
    {
86
        parent::__construct($configSteps);
87
88
        $this->cartManager = $cartManager;
89
        $this->requestStack = $requestStack;
90
        $this->orderManager = $orderManager;
91
    }
92
93
    /**
94
     * @inheritdoc
95
     */
96
    protected function loadStepsConfig()
97
    {
98
        $this->configSteps['payment']['skip'] = function($estimatedCurrentStepNumber, FormFlowInterface $flow) {
99
            /** @var CartForm $data */
100
            $data = $flow->getFormData();
101
102
            $paymentMethod = $data->getPaymentMethod();
103
104
            // se non è settato vuol dire che non ci sono ancora arrivato
105
            if( !$paymentMethod )
0 ignored issues
show
introduced by
$paymentMethod is of type string, thus it always evaluated to true.
Loading history...
106
                return false;
107
108
            /** @var GatewayInterface $gateway */
109
            $gateway = $this->payum->getGateway($paymentMethod);
0 ignored issues
show
Unused Code introduced by
The assignment to $gateway is dead and can be removed.
Loading history...
110
111
            return true;
112
        };
113
114
        return $this->configSteps;
115
    }
116
117
    /**
118
     * @param $form
119
     * @param CartForm $formData
120
     * @return Response|null
121
     *
122
     * @throws \Payum\Core\Reply\ReplyInterface
123
     * @throws null
124
     */
125
    public function handleSubmit(&$form, $formData)
126
    {
127
        if ($this->isValid($form)) {
128
            $this->saveCurrentStepData($form);
129
130
131
            if( !$this->allowAnonymous )
132
                throw new AccessDeniedException("Anonymous users cannot buy");
133
134
            // @todo done this because craue form flow doesn't permit to add a custom action
135
            if( $this->requestStack->getCurrentRequest()->request->get('flow_cart_transition') == self::TRANSITION_RESET_CART ) {
136
                $this->emptyCart($formData);
137
                $this->reset();
138
                $form = $this->createForm();
139
                return null;
140
            }
141
142
143
            if ($this->nextStep() && $this->cartMode != 'single_page') {
144
                // form for the next step
145
                $form = $this->createForm();
146
            } else {
147
                // flow finished
148
                /** @var SkuskuCart $finalCart */
149
                $finalCart = $formData->getCart();                
150
151
                if ($this->hasListeners(self::PRE_SUBMIT)) {
152
                    $event = new PreSubmitCartEvent($this, $finalCart);
153
                    $this->eventDispatcher->dispatch(self::PRE_SUBMIT, $event);
154
                }
155
156
                $this->cartManager->persistCart($finalCart);
157
158
                $storage = $this->payum->getStorage('GGGGino\SkuskuCartBundle\Model\SkuskuPayment');
159
160
                $payment = new SkuskuPayment();
161
                $payment->setNumber(uniqid());
162
                $payment->setCurrencyCode($finalCart->getCurrency()->getIsoCode());
163
                $payment->setTotalAmount($finalCart->getTotalPrice()); // 1.23 EUR
164
                $payment->setDescription($finalCart->getTotalQuantity());
165
                $payment->setClientId($finalCart->getCustomer());
0 ignored issues
show
Bug introduced by
$finalCart->getCustomer() of type GGGGino\SkuskuCartBundle...SkuskuCustomerInterface is incompatible with the type string expected by parameter $clientId of Payum\Core\Model\Payment::setClientId(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

165
                $payment->setClientId(/** @scrutinizer ignore-type */ $finalCart->getCustomer());
Loading history...
166
                $payment->setClientEmail($finalCart->getCustomer()->getEmail());
167
168
                $storage->update($payment);
169
170
                $captureToken = $this->payum->getTokenFactory()->createCaptureToken(
171
                    $formData->getPaymentMethod(),
172
                    $payment,
173
                    'done' // the route to redirect after capture
174
                );
175
176
                $finalCart->setPayment($payment);
177
178
                $requestFields = $this->requestStack->getCurrentRequest()->request->get('choosePayment');
179
                if(isset($requestFields['additionalFields']) && count($requestFields['additionalFields']) > 0 ) {
180
                    $finalCart->setAdditionalFields(json_encode($requestFields['additionalFields']));
0 ignored issues
show
Bug introduced by
json_encode($requestFields['additionalFields']) of type string is incompatible with the type array|null expected by parameter $additionalFields of GGGGino\SkuskuCartBundle...::setAdditionalFields(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

180
                    $finalCart->setAdditionalFields(/** @scrutinizer ignore-type */ json_encode($requestFields['additionalFields']));
Loading history...
181
                }                
182
183
                $this->cartManager->flushCart($finalCart);
184
185
                $this->reset(); // remove step data from the session
186
187
                if ($this->hasListeners(self::POST_SUBMIT)) {
188
                    $event = new PostSubmitCartEvent($this, $finalCart);
189
                    $this->eventDispatcher->dispatch(self::POST_SUBMIT, $event);
190
                }
191
192
                return new RedirectResponse($captureToken->getTargetUrl());
193
            }
194
        }
195
    }
196
197
    /**
198
     * Excecute all the listener tagged with "skusku_cart.post_payment"
199
     * Save the cart as order
200
     *
201
     * @param $payment
202
     * @return FormInterface
203
     */
204
    public function handleDone(SkuskuPayment $payment, $status)
205
    {
206
        if ($this->hasListeners(self::POST_PAYMENT)) {
207
            $event = new PostPaymentCartEvent($this, $payment, $status);
208
            $this->eventDispatcher->dispatch(self::POST_PAYMENT, $event);
209
        }
210
211
        $order = $this->orderManager->buildOrderFromCart($payment->getCart());
212
213
        if ($this->hasListeners(self::PRE_PERSIST_ORDER)) {
214
            $event = new PrePersistOrderEvent($this, $order);
215
            $this->eventDispatcher->dispatch(self::PRE_PERSIST_ORDER, $event);
216
        }
217
218
        $this->orderManager->saveOrder($order);
219
220
        // you have order and payment status
221
        // so you can do whatever you want for example you can just print status and payment details.
222
    }
223
224
    protected function emptyCart(CartForm $formData)
225
    {
226
        $this->cartManager->emptyCart($formData);
227
        $this->cartManager->persistCart($formData->getCart());
228
        $this->cartManager->flushCart($formData->getCart());
229
    }
230
231
    /**
232
     * @param mixed $payum
233
     * @return CartFlow
234
     */
235
    public function setPayum($payum)
236
    {
237
        $this->payum = $payum;
238
        return $this;
239
    }
240
241
    /**
242
     * @param TokenStorage $tokenStorage
243
     * @return CartFlow
244
     */
245
    public function setTokenStorage($tokenStorage)
246
    {
247
        $this->tokenStorage = $tokenStorage;
248
        return $this;
249
    }
250
251
    /**
252
     * @param boolean $allowAnonymous
253
     * @return CartFlow
254
     */
255
    public function setAllowAnonymous($allowAnonymous)
256
    {
257
        $this->allowAnonymous = $allowAnonymous;
258
        return $this;
259
    }
260
261
    /**
262
     * @param boolean $cartMode
263
     * @return CartFlow
264
     */
265
    public function setCartMode($cartMode)
266
    {
267
        $this->cartMode = $cartMode;
0 ignored issues
show
Documentation Bug introduced by
The property $cartMode was declared of type string, but $cartMode is of type boolean. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
268
        return $this;
269
    }    
270
}