Completed
Push — master ( ce7cf2...c39b43 )
by Antony
07:40
created

SilvershopJsonResponse::get()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 8
nc 2
nop 1
dl 0
loc 13
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace AntonyThorpe\SilverShopJsonResponse;
4
5
use SilverStripe\Core\Extension;
6
use SilverStripe\Control\HTTPRequest;
7
use SilverShop\Cart\ShoppingCart;
8
use SilverShop\Page\Product;
9
use SilverShop\Extension\ProductImageExtension;
10
use SilverShop\Extension\ProductVariationsExtension;
11
use SilverShop\Model\Variation\Variation;
12
13
/**
14
 * ShopJsonResponse
15
 *
16
 * Json Response for shopping cart of Silverstripe Shop
17
 * @package shop
18
 */
19
class SilvershopJsonResponse extends Extension
20
{
21
    /**
22
     * Allow get action to obtain a copy of the shopping cart
23
     */
24
    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...
25
        'get'
26
    );
27
28
    /**
29
     * get the shopping cart
30
     *
31
     * @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...
32
     * @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...
33
     */
34
    public function get(HTTPRequest $request)
35
    {
36
        if (!$request->isAjax()) {
37
            return $this->owner->httpError(404, _t(ShoppingCart::class . 'GetCartAjaxOnly', 'Ajax request only Bo'));
38
        }
39
        $response = $this->owner->getResponse();
40
        $response->removeHeader('Content-Type');
41
        $response->addHeader('Content-Type', 'application/json; charset=utf-8');
42
43
        $data = $this->getCurrentShoppingCart();
44
45
        $this->owner->extend('updateGet', $data, $request, $response);
46
        return $response->setBody(json_encode($data));
47
    }
48
49
    /**
50
     * Add one of an item to a cart (Category Page)
51
     *
52
     * @see 'add' function of ShoppingCart_Controller ($this->owner)
53
     * @param SS_HTTPRequest $request
54
     * @param AjaxHTTPResponse $response
0 ignored issues
show
Bug introduced by
The type AntonyThorpe\SilverShopJ...sponse\AjaxHTTPResponse 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...
55
     * @param Buyable $product [optional]
0 ignored issues
show
Bug introduced by
The type AntonyThorpe\SilverShopJsonResponse\Buyable 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...
56
     * @param int $quantity [optional]
57
     */
58
    public function updateAddResponse(&$request, &$response, $product = null, $quantity = 1)
59
    {
60
        if ($request->isAjax()) {
61
            if (!$response) {
0 ignored issues
show
introduced by
$response is of type AntonyThorpe\SilverShopJ...sponse\AjaxHTTPResponse, thus it always evaluated to true.
Loading history...
62
                $response = $this->owner->getResponse();
63
            }
64
            $response->removeHeader('Content-Type');
65
            $response->addHeader('Content-Type', 'application/json; charset=utf-8');
66
            $shoppingcart = ShoppingCart::curr();
67
            $shoppingcart->calculate(); // recalculate the shopping cart
68
69
            $data = array(
70
                'id' => (string) $product->ID,
71
                'internalItemID' => $product->InternalItemID,
72
                'title' => $product->Title,
73
                'url' => $product->URLSegment,
74
                'categories' => $product->getCategories()->column('Title'),
0 ignored issues
show
Bug introduced by
The method getCategories() 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

74
                'categories' => $product->/** @scrutinizer ignore-call */ getCategories()->column('Title'),

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...
75
                'message' => array(
76
                    'content' => $this->owner->cart->getMessage(),
77
                    'type' => $this->owner->cart->getMessageType(),
78
                ),
79
            );
80
            $this->owner->cart->clearMessage();
81
82
            // add separately as these are absent with variations
83
            if (method_exists($product, "getPrice")) {
84
                $data['unitPrice'] = $product->getPrice();
85
            }
86
            if (method_exists($product, "addLink")) {
87
                $data['addLink'] = $product->addLink();
88
            }
89
            if (method_exists($product, "removeLink")) {
90
                $data['removeLink'] = $product->removeLink();
91
            }
92
            if (method_exists($product, "removeallLink")) {
93
                $data['removeallLink'] = $product->removeallLink();
94
            }
95
            if (method_exists($product->Item(), "setquantityLink")) {
96
                $data['setquantityLink'] = $product->Item()->setquantityLink();
97
            }
98
99
            if ($shoppingcart) {
0 ignored issues
show
introduced by
$shoppingcart is of type SilverShop\Model\Order, thus it always evaluated to true.
Loading history...
100
                $data['subTotal'] = $shoppingcart->SubTotal();
101
                $data['grandTotal'] = $shoppingcart->GrandTotal();
102
            }
103
104
            $this->owner->extend('updateAddResponseShopJsonResponse', $data, $request, $response, $product, $quantity);
105
            $response->setBody(json_encode($data));
106
        }
107
    }
108
109
    /**
110
     * Remove one of an item from a cart (Cart Page)
111
     *
112
     * @see 'remove' function of ShoppingCart_Controller ($this->owner)
113
     * @param SS_HTTPRequest $request
114
     * @param AjaxHTTPResponse $response
115
     * @param Buyable $product [optional]
116
     * @param int $quantity [optional]
117
     */
118
    public function updateRemoveResponse(&$request, &$response, $product = null, $quantity = 1)
119
    {
120
        if ($request->isAjax()) {
121
            if (!$response) {
0 ignored issues
show
introduced by
$response is of type AntonyThorpe\SilverShopJ...sponse\AjaxHTTPResponse, thus it always evaluated to true.
Loading history...
122
                $response = $this->owner->getResponse();
123
            }
124
            $response->removeHeader('Content-Type');
125
            $response->addHeader('Content-Type', 'application/json; charset=utf-8');
126
            $shoppingcart = ShoppingCart::curr();
127
            $shoppingcart->calculate(); // recalculate the shopping cart
128
129
            $data = array(
130
                'id' => (string) $product->ID,
131
                'message' => array(
132
                    'content' => $this->owner->cart->getMessage(),
133
                    'type' => $this->owner->cart->getMessageType(),
134
                ),
135
            );
136
            $this->owner->cart->clearMessage();
137
138
            if ($shoppingcart) {
0 ignored issues
show
introduced by
$shoppingcart is of type SilverShop\Model\Order, thus it always evaluated to true.
Loading history...
139
                $data['subTotal'] = $shoppingcart->SubTotal();
140
                $data['grandTotal'] = $shoppingcart->GrandTotal();
141
            }
142
143
            $this->owner->extend('updateRemoveResponseShopJsonResponse', $data, $request, $response, $product, $quantity);
144
            $response->setBody(json_encode($data));
145
        }
146
    }
147
148
    /**
149
     * Remove all of an item from a cart (Cart Page)
150
     * Quantity is NIL
151
     *
152
     * @see 'removeall' function of ShoppingCart_Controller ($this->owner)
153
     * @param SS_HTTPRequest $request
154
     * @param AjaxHTTPResponse $response
155
     * @param Buyable $product [optional]
156
     */
157
    public function updateRemoveAllResponse(&$request, &$response, $product = null)
158
    {
159
        if ($request->isAjax()) {
160
            if (!$response) {
0 ignored issues
show
introduced by
$response is of type AntonyThorpe\SilverShopJ...sponse\AjaxHTTPResponse, thus it always evaluated to true.
Loading history...
161
                $response = $this->owner->getResponse();
162
            }
163
            $response->removeHeader('Content-Type');
164
            $response->addHeader('Content-Type', 'application/json; charset=utf-8');
165
            $shoppingcart = ShoppingCart::curr();
166
            $shoppingcart->calculate(); // recalculate the shopping cart
167
168
            $data = array(
169
                'id' => (string) $product->ID,
170
                'message' => array(
171
                    'content' => $this->owner->cart->getMessage(),
172
                    'type' => $this->owner->cart->getMessageType(),
173
                ),
174
            );
175
            $this->owner->cart->clearMessage();
176
177
            if ($shoppingcart) {
0 ignored issues
show
introduced by
$shoppingcart is of type SilverShop\Model\Order, thus it always evaluated to true.
Loading history...
178
                $data['subTotal'] = $shoppingcart->SubTotal();
179
                $data['grandTotal'] = $shoppingcart->GrandTotal();
180
            }
181
182
            $this->owner->extend('updateRemoveAllResponseShopJsonResponse', $data, $request, $response, $product);
183
            $response->setBody(json_encode($data));
184
        }
185
    }
186
187
    /**
188
     * Update the quantity of an item in a cart (Cart Page)
189
     *
190
     * @see 'setquantity' function of ShoppingCart_Controller ($this->owner)
191
     * @param SS_HTTPRequest $request
192
     * @param AjaxHTTPResponse $response
193
     * @param Buyable $product [optional]
194
     * @param int $quantity [optional]
195
     */
196
    public function updateSetQuantityResponse(&$request, &$response, $product = null, $quantity = 1)
0 ignored issues
show
Unused Code introduced by
The parameter $quantity 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

196
    public function updateSetQuantityResponse(&$request, &$response, $product = null, /** @scrutinizer ignore-unused */ $quantity = 1)

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...
197
    {
198
        if ($request->isAjax()) {
199
            if (!$response) {
0 ignored issues
show
introduced by
$response is of type AntonyThorpe\SilverShopJ...sponse\AjaxHTTPResponse, thus it always evaluated to true.
Loading history...
200
                $response = $this->owner->getResponse();
201
            }
202
            $response->removeHeader('Content-Type');
203
            $response->addHeader('Content-Type', 'application/json; charset=utf-8');
204
            $shoppingcart = ShoppingCart::curr();
205
            $shoppingcart->calculate(); // recalculate the shopping cart
206
207
            $currentquantity = (int) $product->Item()->Quantity; // quantity of the order item left now in the cart
208
209
            $data = array(
210
                'id' => (string) $product->ID,
211
                'quantity' => $currentquantity,
212
                'message' => array(
213
                    'content' => $this->owner->cart->getMessage(),
214
                    'type' => $this->owner->cart->getMessageType(),
215
                ),
216
            );
217
            $this->owner->cart->clearMessage();
218
219
            // include totals if required
220
            if ($shoppingcart) {
0 ignored issues
show
introduced by
$shoppingcart is of type SilverShop\Model\Order, thus it always evaluated to true.
Loading history...
221
                $data['subTotal'] = $shoppingcart->SubTotal();
222
                $data['grandTotal'] = $shoppingcart->GrandTotal();
223
            }
224
225
            $this->owner->extend('updateSetQuantityResponseShopJsonResponse', $data, $request, $response, $product, $currentquantity);
226
            $response->setBody(json_encode($data));
227
        }
228
    }
229
230
    /**
231
     * Clear all items from the cart (Cart Page)
232
     *
233
     * @see 'clear' function of ShoppingCart_Controller ($this->owner)
234
     * @param SS_HTTPRequest $request
235
     * @param AjaxHTTPResponse $response
236
     */
237
    public function updateClearResponse(&$request, &$response)
238
    {
239
        if ($request->isAjax()) {
240
            if (!$response) {
0 ignored issues
show
introduced by
$response is of type AntonyThorpe\SilverShopJ...sponse\AjaxHTTPResponse, thus it always evaluated to true.
Loading history...
241
                $response = $this->owner->getResponse();
242
            }
243
            $response->removeHeader('Content-Type');
244
            $response->addHeader('Content-Type', 'application/json; charset=utf-8');
245
246
            $data = array(
247
                'message' => array(
248
                    'content' => $this->owner->cart->getMessage(),
249
                    'type' => $this->owner->cart->getMessageType(),
250
                ),
251
            );
252
            $this->owner->cart->clearMessage();
253
254
            $this->owner->extend('updateClearResponseShopJsonResponse', $data, $request, $response);
255
            $response->setBody(json_encode($data));
256
        }
257
    }
258
259
    /**
260
     * Update the variations of a product (Cart Page)
261
     *
262
     * @see 'addtocart' function of VariationForm ($this->owner)
263
     * @param SS_HTTPRequest $request
264
     * @param AjaxHTTPResponse $response
265
     * @param Buyable $variation [optional]
266
     * @param int $quantity [optional]
267
     * @param VariationForm $form [optional]
0 ignored issues
show
Bug introduced by
The type AntonyThorpe\SilverShopJsonResponse\VariationForm 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...
268
     */
269
    public function updateVariationFormResponse(&$request, &$response, $variation = null, $quantity = 1, $form = null)
270
    {
271
        if ($request->isAjax()) {
272
            if (!$response) {
0 ignored issues
show
introduced by
$response is of type AntonyThorpe\SilverShopJ...sponse\AjaxHTTPResponse, thus it always evaluated to true.
Loading history...
273
                $response = $this->owner->getResponse();
274
            }
275
            $response->removeHeader('Content-Type');
276
            $response->addHeader('Content-Type', 'application/json; charset=utf-8');
277
            $shoppingcart = ShoppingCart::curr();
278
            $shoppingcart->calculate(); // recalculate the shopping cart
279
280
            $data = array(
281
                'id' => (string) $variation->ID,
282
                'message' => array(
283
                    'content' => $form->Message(),
0 ignored issues
show
Bug introduced by
The method Message() 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

283
                    'content' => $form->/** @scrutinizer ignore-call */ Message(),

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...
284
                    'type' => $form->MessageType(),
285
                ),
286
            );
287
            $form->clearMessage();
288
289
            // include totals if required
290
            if ($shoppingcart) {
0 ignored issues
show
introduced by
$shoppingcart is of type SilverShop\Model\Order, thus it always evaluated to true.
Loading history...
291
                $data['subTotal'] = $shoppingcart->SubTotal();
292
                $data['grandTotal'] = $shoppingcart->GrandTotal();
293
            }
294
295
            $this->owner->extend('updateVariationFormResponseShopJsonResponse', $data, $request, $response, $variation, $quantity, $form);
296
            $response->setBody(json_encode($data));
297
        }
298
    }
299
300
    /**
301
     * Add one of an item to a cart (Product Page)
302
     *
303
     * @see the addtocart function within AddProductForm class
304
     * @param SS_HTTPRequest $request
305
     * @param AjaxHTTPResponse $response
306
     * @param Buyable $buyable [optional]
307
     * @param int $quantity [optional]
308
     * @param AddProductForm $form [optional]
0 ignored issues
show
Bug introduced by
The type AntonyThorpe\SilverShopJsonResponse\AddProductForm 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...
309
     */
310
    public function updateAddProductFormResponse(&$request, &$response, $buyable, $quantity, $form)
311
    {
312
        if ($request->isAjax()) {
313
            if (!$response) {
0 ignored issues
show
introduced by
$response is of type AntonyThorpe\SilverShopJ...sponse\AjaxHTTPResponse, thus it always evaluated to true.
Loading history...
314
                $response = $this->owner->getController()->getResponse();
315
            }
316
            $response->removeHeader('Content-Type');
317
            $response->addHeader('Content-Type', 'application/json; charset=utf-8');
318
            $shoppingcart = ShoppingCart::curr();
319
            $shoppingcart->calculate(); // recalculate the shopping cart
320
321
            $data = array(
322
                'id' => (string) $buyable->ID,
323
                'internalItemID' => $buyable->InternalItemID,
324
                'title' => $buyable->Title,
325
                'url' => $buyable->URLSegment,
326
                'categories' => $buyable->getCategories()->column('Title'),
327
                'addLink' => $buyable->addLink(),
328
                'removeLink' => $buyable->removeLink(),
329
                'removeallLink' => $buyable->removeallLink(),
330
                'setquantityLink' => $buyable->Item()->setquantityLink(),
331
                'message' => array(
332
                    'content' => $form->Message(),
333
                    'type' => $form->MessageType(),
334
                ),
335
            );
336
            $form->clearMessage();
337
338
            // include totals if required
339
            if ($shoppingcart) {
0 ignored issues
show
introduced by
$shoppingcart is of type SilverShop\Model\Order, thus it always evaluated to true.
Loading history...
340
                $data['subTotal'] = $shoppingcart->SubTotal();
341
                $data['grandTotal'] = $shoppingcart->GrandTotal();
342
            }
343
344
            $this->owner->extend('updateAddProductFormResponseShopJsonResponse', $data, $request, $response, $buyable, $quantity, $form);
345
            $response->setBody(json_encode($data));
346
        }
347
    }
348
349
    /**
350
     * Provide a copy of the current order in the required format
351
     * Note the id is the cart's id
352
     * @return array of product id, subTotal, grandTotal, and items & modifiers
353
     */
354
    public function getCurrentShoppingCart()
355
    {
356
        $result = [];
357
358
        if ($shoppingcart = ShoppingCart::curr()) {
359
            $result['id'] = (string) $shoppingcart->getReference();
360
361
            if ($items = $this->getCurrentShoppingCartItems()) {
362
                $result['items'] = $items;
363
            }
364
365
            if ($modifiers = $this->getCurrentShoppingCartModifiers()) {
366
                $result['modifiers'] = $modifiers;
367
            }
368
369
            $result['subTotal'] = $shoppingcart->SubTotal();
370
            $result['grandTotal'] = $shoppingcart->GrandTotal();
371
        }
372
        return $result;
373
    }
374
375
    /**
376
     * Provide a copy of the current order's items, including image details and variations
377
     * @todo  what about subTitles?  i.e the variation choosen (I think)
378
     * @return array
379
     */
380
    protected function getCurrentShoppingCartItems()
381
    {
382
        $result = array();
383
        $items = ShoppingCart::curr()->Items();
384
385
        if ($items->exists()) {
386
            foreach ($items->getIterator() as $item) {
387
                // Definitions
388
                $data = array();
389
                $product = $item->Product();
390
391
                $data["id"] = (string) $item->ProductID;
392
                $data["internalItemID"] = $product->InternalItemID;
393
                $data["title"] = $product->Title;
394
                $data["quantity"] = (int) $item->Quantity;
395
                $data["unitPrice"] = $product->getPrice();
396
                $data["href"] = $item->Link();
397
                $data['categories'] = $product->getCategories()->column('Title');
398
                $data["addLink"] = $item->addLink();
399
                $data["removeLink"] = $item->removeLink();
400
                $data["removeallLink"] = $item->removeallLink();
401
                $data["setquantityLink"] = $item->setquantityLink();
402
403
                // Image
404
                if ($item->Image()) {
405
                    $image = $item->Image()->ScaleWidth((int) ProductImageExtension::config()->cart_image_width);
406
                    $data["image"] = array(
407
                        'alt' => $image->Title,
408
                        'src' => $image->Filename,
409
                        'width' => $image->Width,
410
                        'height' => $image->Height,
411
                    );
412
                }
413
414
                // Variations
415
                $extension = Product::has_extension(ProductVariationsExtension::class);
416
                if ($extension && Variation::get()->filter('ProductID', $item->ID)->first()) {
417
                    $variations = $product->Variations();
418
                    if ($variations->exists()) {
419
                        $data['variations'] = [];
420
                        foreach ($variations as $variation) {
421
                            $data['variations'][] = array(
422
                                'id' => (string) $variation->ID,
423
                                'title' => $variation->Title,
424
                            );
425
                        }
426
                    }
427
                }
428
                $result[] = $data;
429
            }
430
        }
431
        return $result;
432
    }
433
434
    /**
435
     * Provide a copy of the current order's modifiers
436
     * @todo Only FlatTaxModifier tested
437
     * @return array of modifiers (note: this excludes subtotal and grandtotal)
438
     */
439
    protected function getCurrentShoppingCartModifiers()
440
    {
441
        $result = array();
442
        $modifiers = ShoppingCart::curr()->Modifiers();
443
444
        if ($modifiers->exists()) {
445
            foreach ($modifiers->sort('Sort')->getIterator() as $modifier) {
446
                if ($modifier->ShowInTable()) {
447
                    $data = array(
448
                        'id' => (string) $modifier->ID,
449
                        'tableTitle' => $modifier->getTableTitle(),
450
                        'tableValue' => (float) $modifier->TableValue(),
451
                    );
452
453
                    if (method_exists($modifier, 'Link')) {
454
                        // add if there is a link
455
                        $data["href"] = $modifier->Link();
456
                    }
457
458
                    if (method_exists($modifier, 'removeLink')) {
459
                        // add if there is a canRemove method
460
                        $data["removeLink"] = $modifier->removeLink();
461
                    }
462
463
                    $result[] = $data;
464
                }
465
            }
466
        }
467
        $this->owner->extend('updateGetCurrentShoppingCartModifiers', $result);
468
        return $result;
469
    }
470
}
471