Issues (42)

src/Extension/PageControllerExtension.php (7 issues)

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
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\Forms\Form;
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
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
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
     * @var DiscountHelper|null
41
     */
42
    private $discount_helper = null;
43
44
    /**
45
     * @return $this
46
     */
47
    protected function setDiscountHelper()
48
    {
49
        if ($this->getIsDiscountable($this->owner->data())) {
50
            $this->discount_helper = $this->owner->data()->getBestDiscount();
51
        }
52
53
        return $this;
54
    }
55
56
    /**
57
     * @return DiscountHelper|null
58
     */
59
    protected function getDiscountHelper()
60
    {
61
        if (!$this->discount_helper) {
62
            $this->setDiscountHelper();
63
        }
64
65
        return $this->discount_helper;
66
    }
67
68
    /**
69
     * @param $form
70
     */
71
    public function updateAddToCartForm(&$form)
72
    {
73
        $page = $this->owner->data();
74
        /** @var DiscountHelper $discount */
75
        if ($discount = $this->getDiscountHelper()) {
76
            Requirements::javascript('dynamic/silverstripe-foxy-discounts: client/dist/javascript/discount.js');
77
            $code = $page->Code;
78
            if ($form instanceof Form && ($fields = $form->Fields())) {
79
                $fields->push(
80
                    HiddenField::create(AddToCartForm::getGeneratedValue(
81
                        $code,
82
                        $discount->getFoxyDiscountType(),
83
                        $discount->getDiscountFieldValue()
84
                    ))->setValue($this->getDiscountFieldValue())
85
                        ->addExtraClass('product-discount')
86
                );
87
88
                if ($endTime = $discount->getDiscountTier()->Discount()->EndTime) {
89
                    $fields->push(
90
                        HiddenField::create(AddToCartForm::getGeneratedValue(
91
                            $code,
92
                            'expires',
93
                            strtotime($endTime)
94
                        ))
95
                            ->setValue(strtotime($endTime))
96
                    );
97
                }
98
            }
99
        }
100
    }
101
102
    /**
103
     * @return string
104
     */
105
    public function getDiscountFieldValue()
106
    {
107
        /** @var Discount $discount */
108
        if ($discount = $this->getDiscountHelper()) {
0 ignored issues
show
The assignment to $discount is dead and can be removed.
Loading history...
109
            return $this->getDiscountHelper()->getDiscountFieldValue();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getDiscoun...getDiscountFieldValue() could also return false which is incompatible with the documented return type string. Did you maybe forget to handle an error condition?

If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled.

Loading history...
110
        }
111
112
        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...
113
    }
114
115
    public function fetchprice(HTTPRequest $request)
116
    {
117
        if (!$id = $request->getVar('h:product_id')) {
118
            return;
119
        }
120
121
        if (!$product = Product::get()->byID(explode('||', $id)[0])) {
122
            return;
123
        }
124
125
        if (!$this->getIsDiscountable($product)) {
126
            return;
127
        }
128
129
        $totalPrice = Discount::config()->get('calculate_total');
130
        $quantity = (int)$request->getVar('quantity');
131
        $cost = ($totalPrice) ? $product->Price * $quantity : $product->Price;
132
        $optionsQuery = $this->getOptionsQuery($request->getVars());
133
        $options = $product->Options()->filter($optionsQuery);
134
135
        foreach ($options as $option) {
136
            switch ($option->PriceModifierAction) {
137
                case 'Add':
138
                    if ($totalPrice) {
139
                        $cost += ($option->PriceModifier * $quantity);
140
                    } else {
141
                        $cost += $option->PriceModifier;
142
                    }
143
                    break;
144
                case 'Subtract':
145
                    if ($totalPrice) {
146
                        $cost -= ($option->PriceModifier * $quantity);
147
                    } else {
148
                        $cost -= $option->ProceModifier;
149
                    }
150
                    break;
151
                case 'Set':
152
                    if ($totalPrice) {
153
                        $cost = ($option->PriceModifier * $quantity);
154
                    } else {
155
                        $cost = $option->PriceModifier;
156
                    }
157
                    break;
158
            }
159
        }
160
        return $this->getDiscountHelper() instanceof DiscountHelper
161
            ? $cost - $this->getDiscountHelper()->getDiscountedPrice()->getValue()
162
            : $cost;
163
    }
164
165
    /**
166
     * @param $vars
167
     * @return array
168
     */
169
    protected function getOptionsQuery($vars)
170
    {
171
        $exempt = $this->owner->config()->get('exempt_fields');
172
        $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...
173
174
        foreach ($vars as $key => $val) {
175
            if (!in_array($key, $exempt)) {
176
                $filter['OptionModifierKey'][] = explode('||', $val)[0];
177
            }
178
        }
179
180
        return $filter;
181
    }
182
183
    /**
184
     * @param $product
185
     * @return bool
186
     */
187
    public function getIsDiscountable($product)
188
    {
189
        return $product->hasMethod('getHasDiscount')
190
            && $product->hasMethod('getBestDiscount')
191
            && $product->getHasDiscount();
192
    }
193
}
194