Passed
Push — master ( a08ce3...37d7f4 )
by Nic
03:09
created

PageControllerExtension::getOptionsQuery()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 6
c 1
b 0
f 0
nc 3
nop 1
dl 0
loc 12
rs 10
1
<?php
2
3
namespace Dynamic\Foxy\Discounts\Extension;
4
5
use Dynamic\Foxy\Discounts\Model\DiscountTier;
6
use Dynamic\Foxy\Form\AddToCartForm;
7
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...
8
use SilverStripe\Control\HTTPRequest;
9
use SilverStripe\Core\Extension;
10
use SilverStripe\Forms\HiddenField;
11
use SilverStripe\View\Requirements;
12
13
/**
14
 * Class PageControllerExtension
15
 * @package Dynamic\Foxy\Discounts\Extension
16
 */
17
class PageControllerExtension extends Extension
18
{
19
    /**
20
     * @var array
21
     */
22
    private static $allowed_actions = [
0 ignored issues
show
introduced by
The private property $allowed_actions is not used, and could be removed.
Loading history...
23
        'fetchprice',
24
    ];
25
26
    /**
27
     * @var array
28
     */
29
    private static $exempt_fields = [
0 ignored issues
show
introduced by
The private property $exempt_fields is not used, and could be removed.
Loading history...
30
        'price',
31
        'x:visibleQuantity',
32
        'h:product_id',
33
        'isAjax',
34
    ];
35
36
    /**
37
     * @param $form
38
     */
39
    public function updateAddToCartForm(&$form)
40
    {
41
        $class = $this->owner->data()->ClassName;
42
        if ($class::singleton()->hasMethod('getActiveDiscount')) {
43
            if ($discount = $this->owner->data()->getActiveDiscount()) {
44
                Requirements::javascript('dynamic/silverstripe-foxy-discounts: client/dist/javascript/discount.js');
45
                $code = $this->owner->data()->Code;
46
                $fields = $form->Fields();
47
                $fields->push(
48
                    HiddenField::create(AddToCartForm::getGeneratedValue(
49
                        $code,
50
                        $discount->getDiscountType(),
51
                        $this->getDiscountFieldValue()
52
                    ))->setValue($this->getDiscountFieldValue())
53
                        ->addExtraClass('product-discount')
54
                );
55
            }
56
        }
57
    }
58
59
    /**
60
     * @return string
61
     */
62
    public function getDiscountFieldValue()
63
    {
64
        if ($discount = $this->owner->data()->getActiveDiscount()) {
65
            $tiers = $discount->DiscountTiers();
66
            $bulkString = '';
67
            foreach ($tiers as $tier) {
68
                if ($discount->Type == 'Percent') {
69
                    $bulkString .= "|{$tier->Quantity}-{$tier->Percentage}";
70
                    $method = 'allunits';
71
                } elseif ($discount->Type == 'Amount') {
72
                    $bulkString .= "|{$tier->Quantity}-{$tier->Amount}";
73
                    $method = 'allunits';
74
                }
75
            }
76
77
            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 67. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
78
        }
79
80
        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...
81
    }
82
83
    public function fetchprice(HTTPRequest $request)
84
    {
85
        if (!$id = $request->getVar('h:product_id')) {
86
            return;
87
        }
88
89
        if (!$product = Product::get()->byID(explode('||', $id)[0])) {
90
            return;
91
        }
92
93
        $quantity = (int)$request->getVar('quantity');
94
95
        $cost = $product->Price * $quantity;
96
97
        $optionsQuery = $this->getOptionsQuery($request->getVars());
98
99
        $options = $product->Options()->filter($optionsQuery);
100
101
        foreach ($options as $option) {
102
            switch ($option->PriceModifierAction) {
103
                case 'Add':
104
                    $cost += ($option->PriceModifier * $quantity);
105
                    break;
106
                case 'Subtract':
107
                    $cost -= ($option->PriceModifier * $quantity);
108
                    break;
109
                case 'Set':
110
                    $cost = ($option->PriceModifier * $quantity);
111
                    break;
112
            }
113
        }
114
115
        $discount = $this->getDiscount($quantity);
116
117
        if ($discount instanceof DiscountTier && $discount->exists()) {
118
            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

118
            if ($discount->/** @scrutinizer ignore-call */ Discount()->Type == 'Percent') {
Loading history...
119
                $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...
120
            } elseif ($discount->Discount()->Type == 'Amount') {
121
                $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...
122
            }
123
124
            if (isset($discountAmount)) {
125
                $cost = $cost - $discountAmount;
126
            }
127
        }
128
129
        return $cost;
130
    }
131
132
    /**
133
     * @param $quantity
134
     * @return mixed
135
     */
136
    protected function getDiscount($quantity)
137
    {
138
        $best = $this->owner->data()->getActiveDiscount();
139
140
        $tier = $best->DiscountTiers()->filter('Quantity:LessThanOrEqual', $quantity)->sort('Quantity DESC')->first();
141
142
        return $tier;
143
    }
144
145
    /**
146
     * @param $vars
147
     * @return array
148
     */
149
    protected function getOptionsQuery($vars)
150
    {
151
        $exempt = $this->owner->config()->get('exempt_fields');
152
        $filter = ['PriceModifierAction:not' => null];
153
154
        foreach ($vars as $key => $val) {
155
            if (!in_array($key, $exempt)) {
156
                $filter['OptionModifierKey'][] = explode('||', $val)[0];
157
            }
158
        }
159
160
        return $filter;
161
    }
162
}
163