Passed
Push — 1.0 ( c0c1b4...dd1df7 )
by Morven
02:19
created

ShoppingCart::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 0
dl 0
loc 8
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace SilverCommerce\ShoppingCart\Control;
4
5
use SilverStripe\i18n\i18n;
6
use SilverStripe\Forms\Form;
7
use SilverStripe\View\SSViewer;
8
use SilverStripe\Forms\FieldList;
9
use SilverStripe\Forms\TextField;
10
use SilverStripe\Control\Director;
11
use SilverStripe\Forms\FormAction;
12
use SilverStripe\Control\Controller;
13
use SilverStripe\ORM\ValidationResult;
14
use SilverStripe\SiteConfig\SiteConfig;
15
use SilverStripe\Core\Injector\Injector;
16
use SilverStripe\Subsites\Model\Subsite;
0 ignored issues
show
Bug introduced by
The type SilverStripe\Subsites\Model\Subsite was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
17
use SilverStripe\ORM\ValidationException;
18
use SilverCommerce\Checkout\Control\Checkout;
0 ignored issues
show
Bug introduced by
The type SilverCommerce\Checkout\Control\Checkout was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
19
use SilverCommerce\Postage\Forms\PostageForm;
20
use SilverCommerce\OrdersAdmin\Model\Estimate;
21
use SilverStripe\CMS\Controllers\ContentController;
0 ignored issues
show
Bug introduced by
The type SilverStripe\CMS\Controllers\ContentController was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
22
use SilverCommerce\ShoppingCart\ShoppingCartFactory;
23
24
/**
25
 * Holder for items in the shopping cart and interacting with them, as
26
 * well as rendering these items into an interface that allows editing
27
 * of items,
28
 *
29
 * @author ilateral (http://www.ilateral.co.uk)
30
 * @package shoppingcart
31
 */
32
class ShoppingCart extends Controller
33
{
34
35
    /**
36
     * URL Used to access this controller
37
     *
38
     * @var string
39
     * @config
40
     */
41
    private static $url_segment = 'shoppingcart';
42
43
    /**
44
     * Setup default templates for this controller
45
     *
46
     * @var array
47
     */
48
    protected $templates = [
49
        "index" => [ShoppingCart::class, "Page"],
50
        "usediscount" => [ShoppingCart::class . "_usediscount", ShoppingCart::class, "Page"]
51
    ];
52
    
53
    /**
54
     * Overwrite the default title for this controller which is taken
55
     * from the translation files. This is used for Title and MetaTitle
56
     * variables in templates.
57
     *
58
     * @var string
59
     * @config
60
     */
61
    private static $title;
62
63
    /**
64
     * Class Name of object we use as an assotiated estimate.
65
     * This defaults to Estimate
66
     *
67
     * @var string
68
     * @config
69
     */
70
    private static $checkout_class = Checkout::class;
71
72
    /**
73
     * Show the discount form on the shopping cart
74
     *
75
     * @var boolean
76
     * @config
77
     */
78
    private static $show_discount_form = false;
79
80
    /**
81
     * Redirect the user to the cart when an item is added?
82
     * 
83
     * @var boolean
84
     */
85
    private static $redirect_on_add = false;
0 ignored issues
show
introduced by
The private property $redirect_on_add is not used, and could be removed.
Loading history...
86
87
    /**
88
     * The associated dataRecord
89
     *
90
     * @var ShoppingCartModel
0 ignored issues
show
Bug introduced by
The type SilverCommerce\ShoppingC...ntrol\ShoppingCartModel was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
91
     */
92
    protected $dataRecord;
93
94
    /**
95
     * These methods are mapped to sub URLs of this
96
     * controller.
97
     *
98
     * @var array
99
     */
100
    private static $allowed_actions = [
0 ignored issues
show
introduced by
The private property $allowed_actions is not used, and could be removed.
Loading history...
101
        "remove",
102
        "emptycart",
103
        "usediscount",
104
        "setdeliverytype",
105
        "checkout",
106
        "CartForm",
107
        "PostageForm",
108
        "DiscountForm"
109
    ];
110
111
    /**
112
     * Overwrite default init to support subsites (if installed)
113
     * 
114
     * @return void 
115
     */
116
    protected function init()
117
    {
118
        parent::init();
119
120
        // Setup current controller on init (as Security::getMember()
121
        // is not available on construction)
122
        $dataRecord = ShoppingCartFactory::create()->getCurrent();
123
        $this->setDataRecord($dataRecord);
124
        $this->setFailover($this->dataRecord);
125
126
        # Check for subsites and add support
127
        if (class_exists(Subsite::class)) {
128
            $subsite = Subsite::currentSubsite();
129
130
            if ($subsite && $subsite->Theme) {
131
                SSViewer::add_themes([$subsite->Theme]);
132
            }
133
134
            if ($subsite && i18n::getData()->validate($subsite->Language)) {
135
                i18n::set_locale($subsite->Language);
136
            }
137
        }
138
    }
139
    
140
    public function getTitle()
141
    {
142
        if ($this->config()->title) {
143
            return $this->config()->title;
144
        } else {
145
            _t("SilverCommerce\ShoppingCart.CartName", "Shopping Cart");
146
        }
147
    }
148
149
    public function getMetaTitle()
150
    {
151
        return $this->getTitle();
152
    }
153
154
    public function getShowDiscountForm()
155
    {
156
        return $this->config()->show_discount_form;
157
    }
158
159
    public function getDataRecord()
160
    {
161
        return $this->dataRecord;
162
    }
163
164
    public function setDataRecord($record)
165
    {
166
        $this->dataRecord = $record;
167
        return $this;
168
    }
169
170
    /**
171
     * Get the link to this controller
172
     *
173
     * @param string $action The action you want to add to the link
174
     * @return string
175
     */
176
    public function Link($action = null)
177
    {
178
        return Controller::join_links(
179
            $this->config()->url_segment,
180
            $action
181
        );
182
    }
183
184
    /**
185
     * Get an absolute link to this controller
186
     *
187
     * @param string $action The action you want to add to the link
188
     * @return string
189
     */
190
    public function AbsoluteLink($action = null)
191
    {
192
        return Director::absoluteURL($this->Link($action));
193
    }
194
195
    /**
196
     * Get a relative (to the root url of the site) link to this
197
     * controller
198
     *
199
     * @param string $action The action you want to add to the link
200
     * @return string
201
     */
202
    public function RelativeLink($action = null)
203
    {
204
        return Controller::join_links(
205
            Director::baseURL(),
206
            $this->Link($action)
207
        );
208
    }
209
210
    /**
211
     * If content controller exists, return it's menu function
212
     * @param int $level Menu level to return.
213
     * @return ArrayList
0 ignored issues
show
Bug introduced by
The type SilverCommerce\ShoppingCart\Control\ArrayList was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
214
     */
215
    public function getMenu($level = 1)
216
    {
217
        if (class_exists(ContentController::class)) {
218
            $controller = ContentController::singleton();
219
            return $controller->getMenu($level);
220
        }
221
    }
222
223
    public function Menu($level)
0 ignored issues
show
Unused Code introduced by
The parameter $level 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

223
    public function Menu(/** @scrutinizer ignore-unused */ $level)

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...
224
    {
225
        return $this->getMenu();
226
    }
227
228
    /**
229
     * Default acton for the shopping cart
230
     */
231
    public function index()
232
    {
233
        $this->extend("onBeforeIndex");
234
235
        return $this->render();
236
    }
237
238
    /**
239
     * Remove a product from ShoppingCart Via its ID. This action
240
     * expects an ID to be sent through the URL that matches a specific
241
     * key added to an item in the cart
242
     *
243
     * @return Redirect
0 ignored issues
show
Bug introduced by
The type SilverCommerce\ShoppingCart\Control\Redirect was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
244
     */
245
    public function remove()
246
    {
247
        $key = $this->request->param('ID');
248
        $item = null;
249
        $title = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $title is dead and can be removed.
Loading history...
250
251
        if (isset($key)) {
252
            $item = $this
253
                ->Items()
0 ignored issues
show
Bug introduced by
The method Items() does not exist on SilverCommerce\ShoppingCart\Control\ShoppingCart. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

253
                ->/** @scrutinizer ignore-call */ Items()
Loading history...
254
                ->find("Key", $key);
255
        }
256
257
        if (isset($item)) {
258
            $title = $item->Title;
259
            ShoppingCartFactory::create()->removeItem($item);
260
261
            $form = $this->CartForm();
262
            $form->sessionMessage(_t(
263
                "ShoppingCart.RemovedItem",
264
                "Removed '{title}' from your cart",
265
                ["title" => $title]
266
            ));
267
        }
268
269
        return $this->redirectBack();
270
    }
271
    
272
    /**
273
     * Action that will clear shopping cart and associated items
274
     *
275
     */
276
    public function emptycart()
277
    {
278
        ShoppingCartFactory::create()->delete();
279
        
280
        $form = $this->CartForm();
281
        $form->sessionMessage(_t(
282
            "ShoppingCart.EmptiedCart",
283
            "Shopping cart emptied"
284
        ));
285
286
        return $this->redirectBack();
287
    }
288
    
289
    
290
    /**
291
     * Action used to add a discount to the users session via a URL.
292
     * This is preferable to using the dicount form as disount code
293
     * forms seem to provide a less than perfect user experience
294
     *
295
     */
296
    public function usediscount()
297
    {   
298
        $code_to_search = $this->request->param("ID");
299
        $code = false;
300
        $curr = $this->getDiscount();
0 ignored issues
show
Bug introduced by
The method getDiscount() does not exist on SilverCommerce\ShoppingCart\Control\ShoppingCart. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

300
        /** @scrutinizer ignore-call */ 
301
        $curr = $this->getDiscount();
Loading history...
301
        
302
        if (!$code_to_search) {
303
            return $this->httpError(404, "Page not found");
304
        }
305
        
306
        // First check if the discount is already added (so we don't
307
        // query the DB if we don't have to).
308
        if (!$curr || ($curr && $curr->Code != $code_to_search)) {
309
            $code = Discount::get()
0 ignored issues
show
Bug introduced by
The type SilverCommerce\ShoppingCart\Control\Discount was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
310
                ->filter("Code", $code_to_search)
311
                ->exclude("Expires:LessThan", date("Y-m-d"))
312
                ->first();
313
            
314
            if ($code) {
315
                $this->setDiscount($code);
0 ignored issues
show
Bug introduced by
The method setDiscount() does not exist on SilverCommerce\ShoppingCart\Control\ShoppingCart. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

315
                $this->/** @scrutinizer ignore-call */ 
316
                       setDiscount($code);
Loading history...
316
                $this->save();
0 ignored issues
show
Bug introduced by
The method save() does not exist on SilverCommerce\ShoppingCart\Control\ShoppingCart. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

316
                $this->/** @scrutinizer ignore-call */ 
317
                       save();
Loading history...
317
            }
318
        } elseif ($curr && $code->Code == $code_to_search) {
0 ignored issues
show
Bug introduced by
The property Code does not exist on false.
Loading history...
319
            $code = $this->getDiscount();
320
        }
321
322
        $this->extend("onBeforeUseDiscount");
323
324
        return $this
325
            ->customise([
326
                "Discount" => $code
327
            ])->render();
328
    }
329
330
    /**
331
     * Setup the checkout and redirect to it
332
     *
333
     * @return Redirect
334
     */
335
    public function checkout()
336
    {
337
        if (!class_exists($this->config()->checkout_class)) {
338
            return $this->httpError(404);
339
        }
340
341
        $checkout = Injector::inst()
342
            ->get($this->config()->checkout_class);
343
        $checkout->setEstimate($this->dataRecord);
344
345
        $this->extend("onBeforeCheckout");
346
347
        $this->redirect($checkout->Link());
348
    }
349
    
350
    /**
351
     * Shortcut to checkout config, to allow us to access it via
352
     * templates
353
     *
354
     * @return boolean
355
     */
356
    public function ShowTax()
357
    {
358
        $config = SiteConfig::current_site_config();
359
        return $config->ShowPriceAndTax;
360
    }
361
362
    /**
363
     * Form responsible for listing items in the shopping cart and
364
     * allowing management (such as addition, removal, etc)
365
     *
366
     * @return Form
367
     */
368
    public function CartForm()
369
    {   
370
        $form = Form::create(
371
            $this,
372
            "CartForm",
373
            FieldList::create(),
374
            FieldList::create(
375
                FormAction::create(
376
                    'doUpdate',
377
                    _t('ShoppingCart.UpdateCart', 'Update Cart')
378
                )->addExtraClass('btn btn-info')
379
            )
380
        )->setTemplate("SilverCommerce\ShoppingCart\Forms\Includes\ShoppingCartForm");
381
        
382
        $this->extend("updateCartForm", $form);
383
        
384
        return $form;
385
    }
386
    
387
    /**
388
     * Form that allows you to add a discount code which then gets added
389
     * to the cart's list of discounts.
390
     *
391
     * @return Form
392
     */
393
    public function DiscountForm()
394
    {
395
        $form = Form::create(
396
            $this,
397
            "DiscountForm",
398
            FieldList::create(
399
                TextField::create(
400
                    "DiscountCode",
401
                    _t("ShoppingCart.DiscountCode", "Discount Code")
402
                )->setAttribute(
403
                    "placeholder",
404
                    _t("ShoppingCart.EnterDiscountCode", "Enter a discount code")
405
                )
406
            ),
407
            FieldList::create(
408
                FormAction::create(
409
                    'doAddDiscount',
410
                    _t('ShoppingCart.Add', 'Add')
411
                )->addExtraClass('btn btn-info')
412
            )
413
        );
414
        
415
        $this->extend("updateDiscountForm", $form);
416
        
417
        return $form;
418
    }
419
    
420
    /**
421
     * Form responsible for estimating shipping based on location and
422
     * postal code
423
     *
424
     * @return Form
425
     */
426
    public function PostageForm()
427
    {
428
        if ($this->isDeliverable()) {
0 ignored issues
show
Bug introduced by
The method isDeliverable() does not exist on SilverCommerce\ShoppingCart\Control\ShoppingCart. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

428
        if ($this->/** @scrutinizer ignore-call */ isDeliverable()) {
Loading history...
429
            $form = PostageForm::create(
430
                $this,
431
                "PostageForm",
432
                $this->dataRecord,
433
                $this->dataRecord->SubTotal,
434
                $this->dataRecord->TotalWeight,
435
                $this->dataRecord->TotalItems
436
            );
437
438
            $form->setLegend(_t(
439
                "SilverCommerce\ShoppingCart.EstimatePostage",
440
                "Estimate Postage"
441
            ));
442
443
            // Extension call
444
            $this->extend("updatePostageForm", $form);
445
446
            return $form;
447
        }
448
    }
449
450
    /**
451
     * Action that will update cart
452
     *
453
     * @param type $data
454
     * @param type $form
0 ignored issues
show
Bug introduced by
The type SilverCommerce\ShoppingCart\Control\type was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
455
     */
456
    public function doUpdate($data, $form)
457
    {
458
        try {
459
            foreach ($this->Items() as $item) {
460
                foreach ($data as $key => $value) {
461
                    $sliced_key = explode("_", $key);
462
                    if ($sliced_key[0] == "Quantity") {
463
                        if (isset($item) && ($item->Key == $sliced_key[1])) {
464
                            if ($value > 0) {
465
                                ShoppingCartFactory::create()->updateItem(
466
                                    $item,
467
                                    $value
468
                                );
469
                            } else {
470
                                $item->delete();
471
                            }
472
473
                            $form->sessionMessage(
474
                                _t("ShoppingCart.UpdatedShoppingCart", "Shopping cart updated"),
475
                                ValidationResult::TYPE_GOOD
476
                            );
477
                        }
478
                    }
479
                }
480
            }
481
        } catch (ValidationException $e) {
482
            $form->sessionMessage(
483
                $e->getMessage()
484
            );
485
        } catch (Exception $e) {
0 ignored issues
show
Bug introduced by
The type SilverCommerce\ShoppingCart\Control\Exception was not found. Did you mean Exception? If so, make sure to prefix the type with \.
Loading history...
486
            $form->sessionMessage(
487
                $e->getMessage()
488
            );
489
        }
490
        
491
        return $this->redirectBack();
492
    }
493
    
494
    /**
495
     * Action that will find a discount based on the code
496
     *
497
     * @param type $data
498
     * @param type $form
499
     */
500
    public function doAddDiscount($data, $form)
0 ignored issues
show
Unused Code introduced by
The parameter $form 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

500
    public function doAddDiscount($data, /** @scrutinizer ignore-unused */ $form)

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...
501
    {
502
        $code_to_search = $data['DiscountCode'];
503
        
504
        // First check if the discount is already added (so we don't
505
        // query the DB if we don't have to).
506
        if ($this->getDiscount()->Code != $code_to_search) {
507
            $code = Discount::get()
508
                ->filter("Code", $code_to_search)
509
                ->exclude("Expires:LessThan", date("Y-m-d"))
510
                ->first();
511
            
512
            if ($code) {
513
                $this->setDiscount($code);
514
                $this->save();
515
            }
516
        }
517
        
518
        return $this->redirectBack();
519
    }
520
}
521