Passed
Push — master ( a90b5c...399722 )
by Matthijs
07:00
created

CheckoutController   C

Complexity

Total Complexity 55

Size/Duplication

Total Lines 300
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 170
dl 0
loc 300
rs 6
c 0
b 0
f 0
wmc 55

6 Methods

Rating   Name   Duplication   Size   Complexity  
A postCheckoutLogin() 0 27 4
B checkout() 0 48 8
A getEditAddress() 0 28 6
D postComplete() 0 63 16
B postCheckoutRegister() 0 78 11
B postEditAddress() 0 44 10

How to fix   Complexity   

Complex Class

Complex classes like CheckoutController often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use CheckoutController, and based on these observations, apply Extract Interface, too.

1
<?php namespace App\Http\Controllers\Frontend;
2
3
use App\Http\Controllers\Controller;
4
use Illuminate\Http\Request;
5
use Hideyo\Ecommerce\Framework\Services\SendingMethod\SendingMethodFacade as SendingMethodService;
6
use Hideyo\Ecommerce\Framework\Services\PaymentMethod\PaymentMethodFacade as PaymentMethodService;
7
use Hideyo\Ecommerce\Framework\Services\Client\ClientFacade as ClientService;
8
use Hideyo\Ecommerce\Framework\Services\Order\OrderFacade as OrderService;
9
use Hideyo\Ecommerce\Framework\Services\Order\Events\OrderChangeStatus;
10
use Cart;
11
use Validator;
12
use Notification;
13
use BrowserDetect;
14
use Mail;
15
use Event;
16
17
class CheckoutController extends Controller
18
{
19
    public function checkout()
20
    {
21
        $sendingMethodsList = SendingMethodService::selectAllActiveByShopId(config()->get('app.shop_id'));
22
23
        if (!Cart::getContent()->count()) {
24
            return redirect()->to('cart');
25
        }
26
27
        $paymentMethodsList = Cart::getConditionsByType('sending_method')->first()->getAttributes()['data']['related_payment_methods_list'];
28
     
29
        if(!Cart::getConditionsByType('sending_method')->count()) {
30
            Notification::error('Selecteer een verzendwijze');
31
            return redirect()->to('cart');
32
        }
33
34
        if(!Cart::getConditionsByType('payment_method')->count()) {
35
            Notification::error('Selecteer een betaalwijze');
36
            return redirect()->to('cart');
37
        }
38
39
        if (auth('web')->guest()) {
40
            $noAccountUser = session()->get('noAccountUser');
41
            if ($noAccountUser) {
42
                if (!isset($noAccountUser['delivery'])) {
43
                    $noAccountUser['delivery'] = $noAccountUser;
44
                    session()->put('noAccountUser', $noAccountUser);
45
                }
46
  
47
                return view('frontend.checkout.no-account')->with(array( 
48
                    'noAccountUser' =>  $noAccountUser, 
49
                    'sendingMethodsList' => $sendingMethodsList, 
50
                    'paymentMethodsList' => $paymentMethodsList));
51
            }
52
              
53
             return view('frontend.checkout.login')->with(array(  'sendingMethodsList' => $sendingMethodsList, 'paymentMethodsList' => $paymentMethodsList));
54
        }
55
56
        $user = auth('web')->user();
57
58
        if (!$user->clientDeliveryAddress()->count()) {
0 ignored issues
show
Bug introduced by
The method clientDeliveryAddress() does not exist on Illuminate\Contracts\Auth\Authenticatable. It seems like you code against a sub-type of Illuminate\Contracts\Auth\Authenticatable such as Illuminate\Foundation\Auth\User. ( Ignorable by Annotation )

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

58
        if (!$user->/** @scrutinizer ignore-call */ clientDeliveryAddress()->count()) {
Loading history...
59
            ClientService::setBillOrDeliveryAddress(config()->get('app.shop_id'), $user->id, $user->clientBillAddress->id, 'delivery');
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
Bug introduced by
Accessing clientBillAddress on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
60
            return redirect()->to('cart/checkout');
61
        }
62
63
        return view('frontend.checkout.index')->with(array(
64
            'user' =>  $user, 
65
            'sendingMethodsList' => $sendingMethodsList, 
66
            'paymentMethodsList' => $paymentMethodsList));
67
    }
68
69
    public function postCheckoutLogin(Request $request)
70
    {
71
        $validateLogin = ClientService::validateLogin($request->all());
72
73
        if ($validateLogin->fails()) {
74
            foreach ($validateLogin->errors()->all() as $error) {
75
                Notification::error($error);
76
            }
77
78
            return redirect()->to('cart/checkout')
79
            ->withErrors(true, 'login')->withInput();
0 ignored issues
show
Bug introduced by
true of type true is incompatible with the type Illuminate\Contracts\Sup...geProvider|string|array expected by parameter $provider of Illuminate\Http\RedirectResponse::withErrors(). ( Ignorable by Annotation )

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

79
            ->withErrors(/** @scrutinizer ignore-type */ true, 'login')->withInput();
Loading history...
80
        }
81
82
        $userdata = array(
83
            'email' => $request->get('email'),
84
            'password' => $request->get('password'),
85
            'confirmed' => 1,
86
            'active' => 1,
87
            'shop_id' => config()->get('app.shop_id')
88
        );
89
90
        if (auth('web')->attempt($userdata)) {
91
            return redirect()->to('cart/checkout');
92
        }
93
94
        Notification::error(trans('message.error.data-is-incorrect'));
0 ignored issues
show
Bug introduced by
It seems like trans('message.error.data-is-incorrect') can also be of type array; however, parameter $message of Krucas\Notification\Facades\Notification::error() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

94
        Notification::error(/** @scrutinizer ignore-type */ trans('message.error.data-is-incorrect'));
Loading history...
95
        return redirect()->to('cart/checkout')->withErrors(true, 'login')->withInput(); 
96
    }
97
98
    public function postCheckoutRegister(Request $request)
99
    {
100
        if (!Cart::getContent()->count()) {  
101
            return redirect()->to('cart/checkout');
102
        }
103
104
        $noAccount = true;
105
        if ($userdata['password']) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $userdata seems to be never defined.
Loading history...
106
            $noAccount = false;
107
        } 
108
109
        $validateRegister = ClientService::validateRegister($request->all(), $noAccount);
0 ignored issues
show
Unused Code introduced by
The call to Hideyo\Ecommerce\Framewo...ice::validateRegister() has too many arguments starting with $noAccount. ( Ignorable by Annotation )

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

109
        /** @scrutinizer ignore-call */ 
110
        $validateRegister = ClientService::validateRegister($request->all(), $noAccount);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
110
111
        if($validateRegister->fails()) {
112
            foreach ($validator->errors()->all() as $error) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $validator seems to be never defined.
Loading history...
113
                Notification::error($error);
114
            }
115
116
            return redirect()->to('cart/checkout')
117
            ->withErrors(true, 'register')->withInput();;
0 ignored issues
show
Bug introduced by
true of type true is incompatible with the type Illuminate\Contracts\Sup...geProvider|string|array expected by parameter $provider of Illuminate\Http\RedirectResponse::withErrors(). ( Ignorable by Annotation )

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

117
            ->withErrors(/** @scrutinizer ignore-type */ true, 'register')->withInput();;
Loading history...
118
        }
119
120
        if ($request->get('password')) {
121
            $registerAttempt = ClientService::validateRegister($request->all(), config()->get('app.shop_id'));
122
123
            if ($registerAttempt) {
0 ignored issues
show
introduced by
$registerAttempt is of type Illuminate\Validation\Validator, thus it always evaluated to true.
Loading history...
124
                $register = ClientService::register($request->all(), config()->get('app.shop_id'), true);
125
            } else {
126
                $client = ClientService::findByEmail($request->get('email'), config()->get('app.shop_id'));
127
128
                if ($client->account_created) {
129
                    Notification::error('Je hebt al een account. Login aan de linkerkant of vraag een nieuw wachtwoord aan.');
130
                    return redirect()->to('cart/checkout')->withInput()->withErrors('Dit emailadres is al in gebruik. Je kan links inloggen.', 'register');
131
                }
132
                
133
                $register = ClientService::createAccount($request->all(), config()->get('app.shop_id'));
134
            }
135
136
            if ($register) {
137
                $data = $register;
138
                $data['shop'] = app('shop');
139
        
140
                Mail::send('frontend.email.register-mail', array('password' => $userdata['password'], 'user' => $data->toArray(), 'billAddress' => $data->clientBillAddress->toArray()), function ($message) use ($data) {
141
            
142
                    $message->to($data['email'])->from($data['shop']->email, $data['shop']->title)->subject('Je bent geregistreerd.');
143
                });
144
145
                $userdata = array(
146
                    'email' => $request->get('email'),
147
                    'password' => $request->get('password'),
148
                    'confirmed' => 1,
149
                    'active' => 1
150
                );
151
152
                auth('web')->attempt($userdata);
153
154
                return redirect()->to('cart/checkout')->withErrors('Je bent geregistreerd. Er is een bevestigingsmail gestuurd.', 'login');
155
            }
156
            
157
            Notification::error('Je hebt al een account');
158
            return redirect()->to('cart/checkout')->withErrors(true, 'register')->withInput();    
159
        }
160
        
161
        unset($userdata['password']);
162
        $registerAttempt = ClientService::validateRegisterNoAccount($userdata, config()->get('app.shop_id'));
163
164
        if ($registerAttempt) {
165
            $register = ClientService::register($userdata, config()->get('app.shop_id'));   
166
            $userdata['client_id'] = $register->id;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$userdata was never initialized. Although not strictly required by PHP, it is generally a good practice to add $userdata = array(); before regardless.
Loading history...
167
        } else {
168
            $client = ClientService::findByEmail($userdata['email'], config()->get('app.shop_id'));
169
            if ($client) {
170
                $userdata['client_id'] = $client->id;
171
            }
172
        }
173
174
        session()->put('noAccountUser', $userdata);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $userdata does not seem to be defined for all execution paths leading up to this point.
Loading history...
175
        return redirect()->to('cart/checkout');   
176
    }
177
178
    public function postComplete(Request $request)
179
    {
180
        $noAccountUser = session()->get('noAccountUser');
181
        if (auth('web')->guest() and !$noAccountUser) {
182
            return view('frontend.checkout.login');
183
        }
184
185
        if (!Cart::getContent()->count()) {        
186
            return redirect()->to('cart/checkout');
187
        }
188
189
        $data = array(
190
            'products' => Cart::getContent()->toArray(),
191
            'price_with_tax' => Cart::getTotalWithTax(false),
192
            'price_without_tax' => Cart::getTotalWithoutTax(false),
193
            'comments' => $request->get('comments'),
194
            'browser_detect' => serialize(BrowserDetect::toArray())
195
        );
196
197
        if (auth('web')->check()) {
198
            $data['user_id'] = auth('web')->user()->id;
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
199
        }
200
201
        if ($noAccountUser){
202
            $data['user_id'] = $noAccountUser['client_id'];
203
        }     
204
205
        if(Cart::getConditionsByType('sending_method')->count()) {
206
            $data['sending_method'] = Cart::getConditionsByType('sending_method');
207
        }
208
209
        if(Cart::getConditionsByType('sending_method_country_price')->count()) {
210
            $data['sending_method_country_price'] = Cart::getConditionsByType('sending_method_country_price');
211
        }
212
213
        if(Cart::getConditionsByType('payment_method')->count()) {
214
            $data['payment_method'] = Cart::getConditionsByType('payment_method');
215
        }
216
217
        $orderInsertAttempt = OrderService::createOrderFrontend($data, config()->get('app.shop_id'), $noAccountUser);
218
219
        if ($orderInsertAttempt AND $orderInsertAttempt->count()) {
220
            if ($orderInsertAttempt->OrderPaymentMethod and $orderInsertAttempt->OrderPaymentMethod->paymentMethod->order_confirmed_order_status_id) {
221
                $orderStatus = OrderService::updateStatus($orderInsertAttempt->id, $orderInsertAttempt->OrderPaymentMethod->paymentMethod->order_confirmed_order_status_id);
222
                if ($orderInsertAttempt->OrderPaymentMethod->paymentMethod->order_confirmed_order_status_id) {
223
                    Event::fire(new OrderChangeStatus($orderStatus));
224
                }
225
            }
226
227
            session()->put('orderData', $orderInsertAttempt);
228
229
            if ($orderInsertAttempt->OrderPaymentMethod and $orderInsertAttempt->OrderPaymentMethod->paymentMethod->payment_external) {
230
                return redirect()->to('cart/payment');
231
            }
232
233
            app('cart')->clear();
234
            app('cart')->clearCartConditions();  
235
            session()->flush('noAccountUser');
236
            $body = "";
237
            return view('frontend.checkout.complete')->with(array('body' => $body));            
238
        }
239
240
        return redirect()->to('cart/checkout');
241
    }
242
243
    public function getEditAddress(Request $request, $type) {
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed. ( Ignorable by Annotation )

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

243
    public function getEditAddress(/** @scrutinizer ignore-unused */ Request $request, $type) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
244
245
        if (!Cart::getContent()->count()) {        
246
            return redirect()->to('cart/checkout');
247
        }              
248
249
        if (auth('web')->guest()) {
250
            $noAccountUser = session()->get('noAccountUser');
251
            if ($noAccountUser) {
252
                
253
                $address = $noAccountUser;
254
                if ($type == 'delivery') {
255
                    $address = $noAccountUser['delivery'];
256
                }
257
258
                return view('frontend.checkout.edit-address-no-account')->with(array('type' => $type, 'noAccountUser' =>  $noAccountUser, 'clientAddress' => $address));
259
            }
260
        }
261
262
        $user = auth('web')->user();
263
264
        if ($type == 'delivery') {
265
            $address = $user->clientDeliveryAddress->toArray();
0 ignored issues
show
Bug introduced by
Accessing clientDeliveryAddress on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
266
        } else {
267
            $address = $user->clientBillAddress->toArray();
0 ignored issues
show
Bug introduced by
Accessing clientBillAddress on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
268
        }
269
270
        return view('frontend.checkout.edit-address')->with(array('type' => $type, 'user' => $user, 'clientAddress' => $address));
271
    }
272
273
    public function postEditAddress(Request $request, $type)
274
    {
275
        if (!Cart::getContent()->count()) {        
276
            return redirect()->to('cart/checkout');
277
        } 
278
        
279
        $validate = ClientService::validateAddress($request->all());
280
281
        if ($validate->fails()) {
282
            foreach ($validate->errors()->all() as $error) {
283
                Notification::error($error);
284
            }
285
286
            return redirect()->to('cart/edit-address/'.$type)
287
            ->with(array('type' => $type))->withInput();
288
        }
289
290
        if (auth('web')->guest()) {
291
            $noAccountUser = session()->get('noAccountUser');
292
            if ($noAccountUser) {
293
                if ($type == 'bill') {
294
                    $noAccountUser = array_merge($noAccountUser, $request->all());
295
                } elseif ($type == 'delivery') {
296
                    $noAccountUser['delivery'] = array_merge($noAccountUser['delivery'], $request->all());
297
                }
298
299
                session()->put('noAccountUser', $noAccountUser);
300
            }
301
        } else {
302
            $user = auth('web')->user();
303
            $id = $user->clientBillAddress->id;
0 ignored issues
show
Bug introduced by
Accessing clientBillAddress on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
304
            if ($type == 'delivery') {
305
                $id = $user->clientDeliveryAddress->id;
0 ignored issues
show
Bug introduced by
Accessing clientDeliveryAddress on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
306
            }
307
308
            if ($user->clientDeliveryAddress->id == $user->clientBillAddress->id) {
309
                $clientAddress = ClientService::createAddress($request->all(), $user->id);
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
310
                ClientService::setBillOrDeliveryAddress(config()->get('app.shop_id'), $user->id, $clientAddress->id, $type);
311
            } else {
312
                $clientAddress = ClientService::editAddress($user->id, $id, $request->all());
0 ignored issues
show
Unused Code introduced by
The assignment to $clientAddress is dead and can be removed.
Loading history...
313
            }
314
        }
315
316
        return redirect()->to('cart/checkout');        
317
    }
318
}