Passed
Push — master ( 3a5fda...57ad9e )
by Nic
04:24
created

PageControllerExtension   A

Complexity

Total Complexity 32

Size/Duplication

Total Lines 174
Duplicated Lines 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 86
c 3
b 0
f 0
dl 0
loc 174
rs 9.84
wmc 32

6 Methods

Rating   Name   Duplication   Size   Complexity  
A getDiscountFieldValue() 0 20 5
A updateAddToCartForm() 0 16 3
C fetchprice() 0 61 17
A getOptionsQuery() 0 12 3
A getIsDiscountable() 0 5 3
A getDiscount() 0 10 1
1
<?php
2
3
namespace Dynamic\Foxy\Discounts\Extension;
4
5
use Dynamic\Foxy\Discounts\DiscountHelper;
6
use Dynamic\Foxy\Discounts\Model\Discount;
7
use Dynamic\Foxy\Discounts\Model\DiscountTier;
8
use Dynamic\Foxy\Form\AddToCartForm;
9
use Dynamic\Products\Page\Product;
0 ignored issues
show
Bug introduced by
The type Dynamic\Products\Page\Product 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...
10
use SilverStripe\Control\HTTPRequest;
11
use SilverStripe\Core\Extension;
12
use SilverStripe\Dev\Debug;
13
use SilverStripe\Forms\HiddenField;
14
use SilverStripe\View\Requirements;
15
16
/**
17
 * Class PageControllerExtension
18
 * @package Dynamic\Foxy\Discounts\Extension
19
 */
20
class PageControllerExtension extends Extension
21
{
22
    /**
23
     * @var array
24
     */
25
    private static $allowed_actions = [
0 ignored issues
show
introduced by
The private property $allowed_actions is not used, and could be removed.
Loading history...
26
        'fetchprice',
27
    ];
28
29
    /**
30
     * @var array
31
     */
32
    private static $exempt_fields = [
0 ignored issues
show
introduced by
The private property $exempt_fields is not used, and could be removed.
Loading history...
33
        'price',
34
        'quantity',
35
        'h:product_id',
36
        'isAjax',
37
    ];
38
39
    /**
40
     * @param $form
41
     */
42
    public function updateAddToCartForm(&$form)
43
    {
44
        $page = $this->owner->data();
45
        if ($this->getIsDiscountable($page)) {
46
            /** @var DiscountHelper $discount */
47
            if ($discount = $page->getBestDiscount()) {
48
                Requirements::javascript('dynamic/silverstripe-foxy-discounts: client/dist/javascript/discount.js');
49
                $code = $page->Code;
50
                $fields = $form->Fields();
51
                $fields->push(
52
                    HiddenField::create(AddToCartForm::getGeneratedValue(
53
                        $code,
54
                        $discount->getDiscount()->getDiscountType(),
55
                        $this->getDiscountFieldValue()
56
                    ))->setValue($this->getDiscountFieldValue())
57
                        ->addExtraClass('product-discount')
58
                );
59
            }
60
        }
61
    }
62
63
    /**
64
     * @return string
65
     */
66
    public function getDiscountFieldValue()
67
    {
68
        /** @var Discount $discount */
69
        if ($discount = $this->owner->data()->getBestDiscount()->getDiscount()) {
70
            $tiers = $discount->DiscountTiers();
0 ignored issues
show
Bug introduced by
The method DiscountTiers() does not exist on Dynamic\Foxy\Discounts\Model\Discount. 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

70
            /** @scrutinizer ignore-call */ 
71
            $tiers = $discount->DiscountTiers();
Loading history...
71
            $bulkString = '';
72
            foreach ($tiers as $tier) {
73
                if ($discount->Type == 'Percent') {
0 ignored issues
show
Bug Best Practice introduced by
The property Type does not exist on Dynamic\Foxy\Discounts\Model\Discount. Since you implemented __get, consider adding a @property annotation.
Loading history...
74
                    $bulkString .= "|{$tier->Quantity}-{$tier->Percentage}";
75
                    $method = 'allunits';
76
                } elseif ($discount->Type == 'Amount') {
77
                    $bulkString .= "|{$tier->Quantity}-{$tier->Amount}";
78
                    $method = 'allunits';
79
                }
80
            }
81
82
            return "{$discount->Title}{{$method}{$bulkString}}";
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $method seems to be defined by a foreach iteration on line 72. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
83
        }
84
85
        return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type string.
Loading history...
86
    }
87
88
    public function fetchprice(HTTPRequest $request)
89
    {
90
        if (!$id = $request->getVar('h:product_id')) {
91
            return;
92
        }
93
94
        if (!$product = Product::get()->byID(explode('||', $id)[0])) {
95
            return;
96
        }
97
98
        if (!$this->getIsDiscountable($product)) {
99
            return;
100
        }
101
102
        $totalPrice = Discount::config()->get('calculate_total');
103
        $quantity = (int)$request->getVar('quantity');
104
        $cost = ($totalPrice) ? $product->Price * $quantity : $product->Price;
105
        $optionsQuery = $this->getOptionsQuery($request->getVars());
106
        $options = $product->Options()->filter($optionsQuery);
107
108
        foreach ($options as $option) {
109
            switch ($option->PriceModifierAction) {
110
                case 'Add':
111
                    if ($totalPrice) {
112
                        $cost += ($option->PriceModifier * $quantity);
113
                    } else {
114
                        $cost += $option->PriceModifier;
115
                    }
116
                    break;
117
                case 'Subtract':
118
                    if ($totalPrice) {
119
                        $cost -= ($option->PriceModifier * $quantity);
120
                    } else {
121
                        $cost -= $option->ProceModifier;
122
                    }
123
                    break;
124
                case 'Set':
125
                    if ($totalPrice) {
126
                        $cost = ($option->PriceModifier * $quantity);
127
                    } else {
128
                        $cost = $option->PriceModifier;
129
                    }
130
                    break;
131
            }
132
        }
133
134
        $discount = $this->getDiscount($quantity);
135
136
        if ($discount instanceof DiscountTier && $discount->exists()) {
137
            if ($discount->Discount()->Type == 'Percent') {
0 ignored issues
show
Bug introduced by
The method Discount() does not exist on Dynamic\Foxy\Discounts\Model\DiscountTier. 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

137
            if ($discount->/** @scrutinizer ignore-call */ Discount()->Type == 'Percent') {
Loading history...
138
                $discountAmount = $cost * ($discount->Percentage / 100);
0 ignored issues
show
Bug Best Practice introduced by
The property Percentage does not exist on Dynamic\Foxy\Discounts\Model\DiscountTier. Since you implemented __get, consider adding a @property annotation.
Loading history...
139
            } elseif ($discount->Discount()->Type == 'Amount') {
140
                $discountAmount = $discount->Amount;
0 ignored issues
show
Bug Best Practice introduced by
The property Amount does not exist on Dynamic\Foxy\Discounts\Model\DiscountTier. Since you implemented __get, consider adding a @property annotation.
Loading history...
141
            }
142
143
            if (isset($discountAmount)) {
144
                $cost = $cost - $discountAmount;
145
            }
146
        }
147
148
        return $cost;
149
    }
150
151
    /**
152
     * @param $quantity
153
     * @return mixed
154
     */
155
    protected function getDiscount($quantity)
156
    {
157
        /** @var DiscountHelper $best */
158
        $best = $this->owner->data()->getBestDiscount();
159
160
        $best->setDiscountTier($quantity);
161
162
        $tier = $best->getDiscountTier();
163
164
        return $tier;
165
    }
166
167
    /**
168
     * @param $vars
169
     * @return array
170
     */
171
    protected function getOptionsQuery($vars)
172
    {
173
        $exempt = $this->owner->config()->get('exempt_fields');
174
        $filter['PriceModifierAction:not'] = null;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$filter was never initialized. Although not strictly required by PHP, it is generally a good practice to add $filter = array(); before regardless.
Loading history...
175
176
        foreach ($vars as $key => $val) {
177
            if (!in_array($key, $exempt)) {
178
                $filter['OptionModifierKey'][] = explode('||', $val)[0];
179
            }
180
        }
181
182
        return $filter;
183
    }
184
185
    /**
186
     * @param $product
187
     * @return bool
188
     */
189
    public function getIsDiscountable($product)
190
    {
191
        return $product->hasMethod('getHasDiscount')
192
            && $product->hasMethod('getBestDiscount')
193
            && $product->getHasDiscount();
194
    }
195
}
196