Passed
Push — master ( 72d8e5...32c749 )
by Antony
02:11
created

SilvershopJsonResponse   A

Complexity

Total Complexity 36

Size/Duplication

Total Lines 357
Duplicated Lines 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 157
c 3
b 0
f 0
dl 0
loc 357
rs 9.52
wmc 36

11 Methods

Rating   Name   Duplication   Size   Complexity  
A get() 0 13 2
A updateAddResponse() 0 17 2
A updateRemoveResponse() 0 17 2
A getCurrentShoppingCart() 0 21 5
A updateAddProductFormResponse() 0 19 3
B getCurrentShoppingCartItems() 0 51 7
A updateVariationFormResponse() 0 20 3
A updateSetQuantityResponse() 0 19 2
A updateClearResponse() 0 15 2
A getCurrentShoppingCartModifiers() 0 30 6
A updateRemoveAllResponse() 0 17 2
1
<?php
2
3
namespace AntonyThorpe\SilverShopJsonResponse;
4
5
use SilverShop\Cart\ShoppingCart;
6
use SilverShop\Page\Product;
7
use SilverShop\Extension\ProductImageExtension;
8
use SilverShop\Extension\ProductVariationsExtension;
9
use SilverShop\Forms\AddProductForm;
10
use SilverShop\Forms\VariationForm;
11
use SilverShop\Model\Buyable;
12
use SilverShop\Model\Variation\Variation;
13
use SilverStripe\Core\Extension;
14
use SilverStripe\Control\HTTPRequest;
15
use SilverStripe\Control\HTTPResponse;
16
17
/**
18
 * ShopJsonResponse
19
 *
20
 * Json Response for shopping cart of Silverstripe Shop
21
 * @package shop
22
 */
23
class SilvershopJsonResponse extends Extension
24
{
25
    /**
26
     * Allow get action to obtain a copy of the shopping cart
27
     */
28
    private static $allowed_actions = array(
0 ignored issues
show
introduced by
The private property $allowed_actions is not used, and could be removed.
Loading history...
29
        'get'
30
    );
31
32
    /**
33
     * get the shopping cart
34
     *
35
     * @param SS_HTTPRequest $request
0 ignored issues
show
Bug introduced by
The type AntonyThorpe\SilverShopJsonResponse\SS_HTTPRequest 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...
36
     * @return SS_HTTPResponse $response with JSON body
0 ignored issues
show
Bug introduced by
The type AntonyThorpe\SilverShopJ...esponse\SS_HTTPResponse 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...
37
     */
38
    public function get(HTTPRequest $request)
39
    {
40
        if (!$request->isAjax()) {
41
            return $this->owner->httpError(404, _t(ShoppingCart::class . 'GetCartAjaxOnly', 'Ajax request only Bo'));
42
        }
43
        $response = $this->owner->getResponse();
44
        $response->removeHeader('Content-Type');
45
        $response->addHeader('Content-Type', 'application/json; charset=utf-8');
46
47
        $data = $this->getCurrentShoppingCart();
48
49
        $this->owner->extend('updateGet', $data, $request, $response);
50
        return $response->setBody(json_encode($data));
51
    }
52
53
    /**
54
     * Add one of an item to a cart (Category Page)
55
     *
56
     * @see 'add' function of ShoppingCart_Controller ($this->owner)
57
     * @param SS_HTTPRequest $request
58
     * @param SS_HTTPResponse $response
59
     * @param Buyable $product [optional]
60
     * @param int $quantity [optional]
61
     */
62
    public function updateAddResponse(&$request, &$response, $product = null, $quantity = 1)
63
    {
64
        if ($request->isAjax()) {
65
            $response->removeHeader('Content-Type');
66
            $response->addHeader('Content-Type', 'application/json; charset=utf-8');
67
            $shoppingcart = ShoppingCart::curr();
68
            $shoppingcart->calculate(); // recalculate the shopping cart
69
70
            $data = $this->getCurrentShoppingCart();
71
            $data['message'] = [
72
                'content' => $this->owner->cart->getMessage(),
73
                'type' => $this->owner->cart->getMessageType()
74
            ];
75
            $this->owner->cart->clearMessage();
76
77
            $this->owner->extend('updateAddResponseShopJsonResponse', $data, $request, $response, $product, $quantity);
78
            $response->setBody(json_encode($data));
79
        }
80
    }
81
82
    /**
83
     * Remove one of an item from a cart (Cart Page)
84
     *
85
     * @see 'remove' function of ShoppingCart_Controller ($this->owner)
86
     * @param SS_HTTPRequest $request
87
     * @param SS_HTTPResponse $response
88
     * @param Buyable $product [optional]
89
     * @param int $quantity [optional]
90
     */
91
    public function updateRemoveResponse(&$request, &$response, $product = null, $quantity = 1)
92
    {
93
        if ($request->isAjax()) {
94
            $response->removeHeader('Content-Type');
95
            $response->addHeader('Content-Type', 'application/json; charset=utf-8');
96
            $shoppingcart = ShoppingCart::curr();
97
            $shoppingcart->calculate(); // recalculate the shopping cart
98
99
            $data = $this->getCurrentShoppingCart();
100
            $data['message'] = [
101
                'content' => $this->owner->cart->getMessage(),
102
                'type' => $this->owner->cart->getMessageType()
103
            ];
104
            $this->owner->cart->clearMessage();
105
106
            $this->owner->extend('updateRemoveResponseShopJsonResponse', $data, $request, $response, $product, $quantity);
107
            $response->setBody(json_encode($data));
108
        }
109
    }
110
111
    /**
112
     * Remove all of an item from a cart (Cart Page)
113
     * Quantity is NIL
114
     *
115
     * @see 'removeall' function of ShoppingCart_Controller ($this->owner)
116
     * @param SS_HTTPRequest $request
117
     * @param SS_HTTPResponse $response
118
     * @param Buyable $product [optional]
119
     */
120
    public function updateRemoveAllResponse(&$request, &$response, $product = null)
121
    {
122
        if ($request->isAjax()) {
123
            $response->removeHeader('Content-Type');
124
            $response->addHeader('Content-Type', 'application/json; charset=utf-8');
125
            $shoppingcart = ShoppingCart::curr();
126
            $shoppingcart->calculate(); // recalculate the shopping cart
127
128
            $data = $this->getCurrentShoppingCart();
129
            $data['message'] = [
130
                'content' => $this->owner->cart->getMessage(),
131
                'type' => $this->owner->cart->getMessageType()
132
            ];
133
            $this->owner->cart->clearMessage();
134
135
            $this->owner->extend('updateRemoveAllResponseShopJsonResponse', $data, $request, $response, $product);
136
            $response->setBody(json_encode($data));
137
        }
138
    }
139
140
    /**
141
     * Update the quantity of an item in a cart (Cart Page)
142
     *
143
     * @see 'setquantity' function of ShoppingCart_Controller ($this->owner)
144
     * @param SS_HTTPRequest $request
145
     * @param SS_HTTPResponse $response
146
     * @param Buyable $product [optional]
147
     * @param int $quantity [optional]
148
     */
149
    public function updateSetQuantityResponse(&$request, &$response, $product = null, $quantity = 1)
150
    {
151
        if ($request->isAjax()) {
152
            $response->removeHeader('Content-Type');
153
            $response->addHeader('Content-Type', 'application/json; charset=utf-8');
154
            $shoppingcart = ShoppingCart::curr();
155
            $shoppingcart->calculate(); // recalculate the shopping cart
156
157
            $currentquantity = (int) $product->Item()->Quantity; // quantity of the order item left now in the cart
0 ignored issues
show
Unused Code introduced by
The assignment to $currentquantity is dead and can be removed.
Loading history...
Bug introduced by
The method Item() does not exist on null. ( Ignorable by Annotation )

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

157
            $currentquantity = (int) $product->/** @scrutinizer ignore-call */ Item()->Quantity; // quantity of the order item left now in the cart

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
158
159
            $data = $this->getCurrentShoppingCart();
160
            $data['message'] = [
161
                'content' => $this->owner->cart->getMessage(),
162
                'type' => $this->owner->cart->getMessageType()
163
            ];
164
            $this->owner->cart->clearMessage();
165
166
            $this->owner->extend('updateSetQuantityResponseShopJsonResponse', $data, $request, $response, $product, $quantity);
167
            $response->setBody(json_encode($data));
168
        }
169
    }
170
171
    /**
172
     * Clear all items from the cart (Cart Page)
173
     *
174
     * @see 'clear' function of ShoppingCart_Controller ($this->owner)
175
     * @param SS_HTTPRequest $request
176
     * @param SS_HTTPResponse $response
177
     */
178
    public function updateClearResponse(&$request, &$response)
179
    {
180
        if ($request->isAjax()) {
181
            $response->removeHeader('Content-Type');
182
            $response->addHeader('Content-Type', 'application/json; charset=utf-8');
183
184
            $data = $this->getCurrentShoppingCart();
185
            $data['message'] = [
186
                'content' => $this->owner->cart->getMessage(),
187
                'type' => $this->owner->cart->getMessageType()
188
            ];
189
            $this->owner->cart->clearMessage();
190
191
            $this->owner->extend('updateClearResponseShopJsonResponse', $data, $request, $response);
192
            $response->setBody(json_encode($data));
193
        }
194
    }
195
196
    /**
197
     * Update the variations of a product (Cart Page)
198
     *
199
     * @see 'addtocart' function of VariationForm ($this->owner)
200
     * @param SS_HTTPRequest $request
201
     * @param SS_HTTPResponse $response
202
     * @param Buyable $variation [optional]
203
     * @param int $quantity [optional]
204
     * @param VariationForm $form [optional]
205
     */
206
    public function updateVariationFormResponse(&$request, &$response, $variation = null, $quantity = 1, $form = null)
207
    {
208
        if ($request->isAjax()) {
209
            $response->removeHeader('Content-Type');
210
            $response->addHeader('Content-Type', 'application/json; charset=utf-8');
211
            $shoppingcart = ShoppingCart::curr();
212
            $shoppingcart->calculate(); // recalculate the shopping cart
213
214
            $data = $this->getCurrentShoppingCart();
215
            if ($form) {
216
                $data['message'] = [
217
                    'content' => $form->getMessage(),
218
                    'type' => $form->getMessageType()
219
                ];
220
                $form->clearMessage();
221
            }
222
223
224
            $this->owner->extend('updateVariationFormResponseShopJsonResponse', $data, $request, $response, $variation, $quantity, $form);
225
            $response->setBody(json_encode($data));
226
        }
227
    }
228
229
    /**
230
     * Add one of an item to a cart (Product Page)
231
     *
232
     * @see the addtocart function within AddProductForm class
233
     * @param SS_HTTPRequest $request
234
     * @param SS_HTTPResponse $response
235
     * @param Buyable $buyable [optional]
236
     * @param int $quantity [optional]
237
     * @param AddProductForm $form [optional]
238
     */
239
    public function updateAddProductFormResponse(&$request, &$response, $buyable, $quantity, $form)
240
    {
241
        if ($request->isAjax()) {
242
            $response->removeHeader('Content-Type');
243
            $response->addHeader('Content-Type', 'application/json; charset=utf-8');
244
            $shoppingcart = ShoppingCart::curr();
245
            $shoppingcart->calculate(); // recalculate the shopping cart
246
247
            $data = $this->getCurrentShoppingCart();
248
            if ($form) {
0 ignored issues
show
introduced by
$form is of type SilverShop\Forms\AddProductForm, thus it always evaluated to true.
Loading history...
249
                $data['message'] = [
250
                    'content' => $form->getMessage(),
251
                    'type' => $form->getMessageType()
252
                ];
253
                $form->clearMessage();
254
            }
255
256
            $this->owner->extend('updateAddProductFormResponseShopJsonResponse', $data, $request, $response, $buyable, $quantity, $form);
257
            $response->setBody(json_encode($data));
258
        }
259
    }
260
261
    /**
262
     * Provide a copy of the current order in the required format
263
     * Note the id is the cart's id
264
     * @return array of product id, subTotal, grandTotal, and items & modifiers
265
     */
266
    public function getCurrentShoppingCart()
267
    {
268
        $result = [];
269
270
        if ($shoppingcart = ShoppingCart::curr()) {
271
            $result['id'] = (string) $shoppingcart->getReference();
272
273
            if ($items = $this->getCurrentShoppingCartItems()) {
274
                $result['items'] = $items;
275
            }
276
277
            if ($modifiers = $this->getCurrentShoppingCartModifiers()) {
278
                $result['modifiers'] = $modifiers;
279
            }
280
281
            if ($shoppingcart->SubTotal()) {
282
                $result['subTotal'] = $shoppingcart->SubTotal();
283
                $result['grandTotal'] = $shoppingcart->GrandTotal();
284
            }
285
        }
286
        return $result;
287
    }
288
289
    /**
290
     * Provide a copy of the current order's items, including image details and variations
291
     * @return array
292
     */
293
    protected function getCurrentShoppingCartItems()
294
    {
295
        $result = [];
296
        $shoppingcart = ShoppingCart::curr();
297
298
        if ($shoppingcart->Items()->exists()) {
299
            foreach ($shoppingcart->Items()->getIterator() as $item) {
300
                // Definitions
301
                $data = [];
302
                $product = $item->Product();
303
304
                $data["id"] = (string) $item->ProductID;
305
                $data["internalItemID"] = $product->InternalItemID;
306
                $data["title"] = $product->getTitle();
307
                $data["quantity"] = (int) $item->Quantity;
308
                $data["unitPrice"] = $product->getPrice();
309
                $data["href"] = $item->Link();
310
                $data['categories'] = $product->getCategories()->column('Title');
311
                $data["addLink"] = $item->addLink();
312
                $data["removeLink"] = $item->removeLink();
313
                $data["removeallLink"] = $item->removeallLink();
314
                $data["setquantityLink"] = $item->setquantityLink();
315
316
                // Image
317
                if ($item->Image()) {
318
                    $image = $item->Image()->ScaleWidth((int) ProductImageExtension::config()->cart_image_width);
319
                    $data["image"] = array(
320
                        'alt' => $image->getTitle(),
321
                        'src' => $image->getAbsoluteURL(),
322
                        'width' => $image->getWidth(),
323
                        'height' => $image->getHeight(),
324
                    );
325
                }
326
327
                // Variations
328
                if (Variation::get()->filter('ProductID', $item->ID)->first()) {
329
                    $variations = $product->Variations();
330
                    if ($variations->exists()) {
331
                        $data['variations'] = [];
332
                        foreach ($variations as $variation) {
333
                            $data['variations'][] = array(
334
                                'id' => (string) $variation->ID,
335
                                'title' => $variation->getTitle(),
336
                            );
337
                        }
338
                    }
339
                }
340
                $result[] = $data;
341
            }
342
        }
343
        return $result;
344
    }
345
346
    /**
347
     * Provide a copy of the current order's modifiers
348
     * @return array of modifiers (note: this excludes subtotal and grandtotal)
349
     */
350
    protected function getCurrentShoppingCartModifiers()
351
    {
352
        $result = [];
353
        $shoppingcart = ShoppingCart::curr();
354
355
        if ($shoppingcart->Modifiers()->exists()) {
356
            $modifiers = $shoppingcart->Modifiers();
357
            foreach ($modifiers->sort('Sort')->getIterator() as $modifier) {
358
                if ($modifier->ShowInTable()) {
359
                    $data = array(
360
                        'id' => (string) $modifier->ID,
361
                        'tableTitle' => $modifier->getTableTitle(),
362
                        'tableValue' => (float) $modifier->TableValue(),
363
                    );
364
365
                    if (method_exists($modifier, 'Link')) {
366
                        // add if there is a link
367
                        $data["href"] = $modifier->Link();
368
                    }
369
370
                    if (method_exists($modifier, 'removeLink')) {
371
                        // add if there is a canRemove method
372
                        $data["removeLink"] = $modifier->removeLink();
373
                    }
374
375
                    $result[] = $data;
376
                }
377
            }
378
        }
379
        return $result;
380
    }
381
}
382