Passed
Push — master ( e09f2e...a7489f )
by Antony
01:48
created

getCurrentShoppingCartItems()   A

Complexity

Conditions 5
Paths 2

Size

Total Lines 43
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
cc 5
eloc 28
c 4
b 0
f 0
nc 2
nop 0
dl 0
loc 43
rs 9.1608
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\Forms\AddProductForm;
9
use SilverShop\Forms\VariationForm;
10
use SilverShop\Model\Buyable;
11
use SilverShop\Model\Variation\Variation;
12
use SilverStripe\Core\Extension;
13
use SilverStripe\Control\HTTPRequest;
14
use SilverStripe\Control\HTTPResponse;
15
16
/**
17
 * ShopJsonResponse
18
 *
19
 * Json Response for shopping cart of Silverstripe Shop
20
 * @package shop
21
 */
22
class SilvershopJsonResponse extends Extension
23
{
24
    /**
25
     * Allow get action to obtain a copy of the shopping cart
26
     */
27
    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...
28
        'get'
29
    );
30
31
    /**
32
     * get the shopping cart
33
     *
34
     * @param HTTPRequest $request
35
     * @return HTTPResponse $response with JSON body
36
     */
37
    public function get(HTTPRequest $request)
38
    {
39
        if (!$request->isAjax()) {
40
            return $this->owner->httpError(404, _t(ShoppingCart::class . 'GetCartAjaxOnly', 'Ajax request only Bo'));
41
        }
42
        $response = $this->owner->getResponse();
43
        $response->removeHeader('Content-Type');
44
        $response->addHeader('Content-Type', 'application/json; charset=utf-8');
45
46
        $data = $this->getCurrentShoppingCart();
47
48
        $this->owner->extend('updateGet', $data, $request, $response);
49
        return $response->setBody(json_encode($data));
50
    }
51
52
    /**
53
     * Add one of an item to a cart (Category Page)
54
     *
55
     * @see 'add' function of ShoppingCart_Controller ($this->owner)
56
     * @param HTTPRequest $request
57
     * @param HTTPResponse $response
58
     * @param Buyable $product [optional]
59
     * @param int $quantity [optional]
60
     */
61
    public function updateAddResponse(&$request, &$response, $product = null, $quantity = 1)
62
    {
63
        if ($request->isAjax()) {
64
            if (!$response) {
0 ignored issues
show
introduced by
$response is of type SilverStripe\Control\HTTPResponse, thus it always evaluated to true.
Loading history...
65
                $response = $this->owner->getResponse();
66
            }
67
            $response->removeHeader('Content-Type');
68
            $response->addHeader('Content-Type', 'application/json; charset=utf-8');
69
            $shoppingcart = ShoppingCart::curr();
70
            $shoppingcart->calculate(); // recalculate the shopping cart
71
72
            $data = $this->getCurrentShoppingCart();
73
            $data['message'] = [
74
                'content' => $this->owner->cart->getMessage(),
75
                'type' => $this->owner->cart->getMessageType()
76
            ];
77
            $this->owner->cart->clearMessage();
78
79
            $this->owner->extend('updateAddResponseShopJsonResponse', $data, $request, $response, $product, $quantity);
80
            $response->setBody(json_encode($data));
81
        }
82
    }
83
84
    /**
85
     * Remove one of an item from a cart (Cart Page)
86
     *
87
     * @see 'remove' function of ShoppingCart_Controller ($this->owner)
88
     * @param HTTPRequest $request
89
     * @param HTTPResponse $response
90
     * @param Buyable $product [optional]
91
     * @param int $quantity [optional]
92
     */
93
    public function updateRemoveResponse(&$request, &$response, $product = null, $quantity = 1)
94
    {
95
        if ($request->isAjax()) {
96
            if (!$response) {
0 ignored issues
show
introduced by
$response is of type SilverStripe\Control\HTTPResponse, thus it always evaluated to true.
Loading history...
97
                $response = $this->owner->getResponse();
98
            }
99
            $response->removeHeader('Content-Type');
100
            $response->addHeader('Content-Type', 'application/json; charset=utf-8');
101
            $shoppingcart = ShoppingCart::curr();
102
            $shoppingcart->calculate(); // recalculate the shopping cart
103
104
            $data = $this->getCurrentShoppingCart();
105
            $data['message'] = [
106
                'content' => $this->owner->cart->getMessage(),
107
                'type' => $this->owner->cart->getMessageType()
108
            ];
109
            $this->owner->cart->clearMessage();
110
111
            $this->owner->extend('updateRemoveResponseShopJsonResponse', $data, $request, $response, $product, $quantity);
112
            $response->setBody(json_encode($data));
113
        }
114
    }
115
116
    /**
117
     * Remove all of an item from a cart (Cart Page)
118
     * Quantity is NIL
119
     *
120
     * @see 'removeall' function of ShoppingCart_Controller ($this->owner)
121
     * @param HTTPRequest $request
122
     * @param HTTPResponse $response
123
     * @param Buyable $product [optional]
124
     */
125
    public function updateRemoveAllResponse(&$request, &$response, $product = null)
126
    {
127
        if ($request->isAjax()) {
128
            if (!$response) {
0 ignored issues
show
introduced by
$response is of type SilverStripe\Control\HTTPResponse, thus it always evaluated to true.
Loading history...
129
                $response = $this->owner->getResponse();
130
            }
131
            $response->removeHeader('Content-Type');
132
            $response->addHeader('Content-Type', 'application/json; charset=utf-8');
133
            $shoppingcart = ShoppingCart::curr();
134
            $shoppingcart->calculate(); // recalculate the shopping cart
135
136
            $data = $this->getCurrentShoppingCart();
137
            $data['message'] = [
138
                'content' => $this->owner->cart->getMessage(),
139
                'type' => $this->owner->cart->getMessageType()
140
            ];
141
            $this->owner->cart->clearMessage();
142
143
            $this->owner->extend('updateRemoveAllResponseShopJsonResponse', $data, $request, $response, $product);
144
            $response->setBody(json_encode($data));
145
        }
146
    }
147
148
    /**
149
     * Update the quantity of an item in a cart (Cart Page)
150
     *
151
     * @see 'setquantity' function of ShoppingCart_Controller ($this->owner)
152
     * @param HTTPRequest $request
153
     * @param HTTPResponse $response
154
     * @param Buyable $product [optional]
155
     * @param int $quantity [optional]
156
     */
157
    public function updateSetQuantityResponse(&$request, &$response, $product = null, $quantity = 1)
158
    {
159
        if ($request->isAjax()) {
160
            if (!$response) {
0 ignored issues
show
introduced by
$response is of type SilverStripe\Control\HTTPResponse, 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 = $this->getCurrentShoppingCart();
169
            $data['message'] = [
170
                'content' => $this->owner->cart->getMessage(),
171
                'type' => $this->owner->cart->getMessageType()
172
            ];
173
            $this->owner->cart->clearMessage();
174
175
            $this->owner->extend('updateSetQuantityResponseShopJsonResponse', $data, $request, $response, $product, $quantity);
176
            $response->setBody(json_encode($data));
177
        }
178
    }
179
180
    /**
181
     * Clear all items from the cart (Cart Page)
182
     *
183
     * @see 'clear' function of ShoppingCart_Controller ($this->owner)
184
     * @param HTTPRequest $request
185
     * @param HTTPResponse $response
186
     */
187
    public function updateClearResponse(&$request, &$response)
188
    {
189
        if ($request->isAjax()) {
190
            if (!$response) {
0 ignored issues
show
introduced by
$response is of type SilverStripe\Control\HTTPResponse, thus it always evaluated to true.
Loading history...
191
                $response = $this->owner->getResponse();
192
            }
193
            $response->removeHeader('Content-Type');
194
            $response->addHeader('Content-Type', 'application/json; charset=utf-8');
195
196
            $data = $this->getCurrentShoppingCart();
197
            $data['message'] = [
198
                'content' => $this->owner->cart->getMessage(),
199
                'type' => $this->owner->cart->getMessageType()
200
            ];
201
            $this->owner->cart->clearMessage();
202
203
            $this->owner->extend('updateClearResponseShopJsonResponse', $data, $request, $response);
204
            $response->setBody(json_encode($data));
205
        }
206
    }
207
208
    /**
209
     * Update the variations of a product (Cart Page)
210
     *
211
     * @see 'addtocart' function of VariationForm ($this->owner)
212
     * @param HTTPRequest $request
213
     * @param HTTPResponse $response
214
     * @param Buyable $variation [optional]
215
     * @param int $quantity [optional]
216
     * @param VariationForm $form [optional]
217
     */
218
    public function updateVariationFormResponse(&$request, &$response, $variation = null, $quantity = 1, $form = null)
219
    {
220
        if ($request->isAjax()) {
221
            if (!$response) {
0 ignored issues
show
introduced by
$response is of type SilverStripe\Control\HTTPResponse, thus it always evaluated to true.
Loading history...
222
                $response = $this->owner->getResponse();
223
            }
224
            $response->removeHeader('Content-Type');
225
            $response->addHeader('Content-Type', 'application/json; charset=utf-8');
226
            $shoppingcart = ShoppingCart::curr();
227
            $shoppingcart->calculate(); // recalculate the shopping cart
228
229
            $data = $this->getCurrentShoppingCart();
230
            if ($form) {
231
                $data['message'] = [
232
                    'content' => $form->getMessage(),
233
                    'type' => $form->getMessageType()
234
                ];
235
                $form->clearMessage();
236
            }
237
238
239
            $this->owner->extend('updateVariationFormResponseShopJsonResponse', $data, $request, $response, $variation, $quantity, $form);
240
            $response->setBody(json_encode($data));
241
        }
242
    }
243
244
    /**
245
     * Add one of an item to a cart (Product Page)
246
     *
247
     * @see the addtocart function within AddProductForm class
248
     * @param HTTPRequest $request
249
     * @param HTTPResponse $response
250
     * @param Buyable $buyable [optional]
251
     * @param int $quantity [optional]
252
     * @param AddProductForm $form [optional]
253
     */
254
    public function updateAddProductFormResponse(&$request, &$response, $buyable, $quantity, $form)
255
    {
256
        if ($request->isAjax()) {
257
            if (!$response) {
0 ignored issues
show
introduced by
$response is of type SilverStripe\Control\HTTPResponse, thus it always evaluated to true.
Loading history...
258
                $response = $this->owner->getController()->getResponse();
259
            }
260
            $response->removeHeader('Content-Type');
261
            $response->addHeader('Content-Type', 'application/json; charset=utf-8');
262
            $shoppingcart = ShoppingCart::curr();
263
            $shoppingcart->calculate(); // recalculate the shopping cart
264
265
            $data = $this->getCurrentShoppingCart();
266
            if ($form) {
0 ignored issues
show
introduced by
$form is of type SilverShop\Forms\AddProductForm, thus it always evaluated to true.
Loading history...
267
                $data['message'] = [
268
                    'content' => $form->getMessage(),
269
                    'type' => $form->getMessageType()
270
                ];
271
                $form->clearMessage();
272
            }
273
274
            $this->owner->extend('updateAddProductFormResponseShopJsonResponse', $data, $request, $response, $buyable, $quantity, $form);
275
            $response->setBody(json_encode($data));
276
        }
277
    }
278
279
    /**
280
     * Provide a copy of the current order in the required format
281
     * Note the id is the cart's id
282
     * @return array of product id, subTotal, grandTotal, and items & modifiers
283
     */
284
    public function getCurrentShoppingCart()
285
    {
286
        $result = [];
287
288
        if ($shoppingcart = ShoppingCart::curr()) {
289
            $result['id'] = (string) $shoppingcart->getReference();
290
291
            if ($items = $this->getCurrentShoppingCartItems()) {
292
                $result['items'] = $items;
293
            }
294
295
            if ($modifiers = $this->getCurrentShoppingCartModifiers()) {
296
                $result['modifiers'] = $modifiers;
297
            }
298
299
            if ($shoppingcart->SubTotal()) {
300
                $result['subTotal'] = $shoppingcart->SubTotal();
301
                $result['grandTotal'] = $shoppingcart->GrandTotal();
302
            }
303
        }
304
        return $result;
305
    }
306
307
    /**
308
     * Provide a copy of the current order's items, including image details and variations
309
     * @return array
310
     */
311
    protected function getCurrentShoppingCartItems()
312
    {
313
        $result = [];
314
        $shoppingcart = ShoppingCart::curr();
315
316
        if ($shoppingcart->Items()->exists()) {
317
            foreach ($shoppingcart->Items()->getIterator() as $item) {
318
                // Definitions
319
                $data = [];
320
                $product = $item->Product();
321
322
                $data["id"] = (string) $item->ProductID;
323
                $data["internalItemID"] = $product->InternalItemID;
324
                $data["title"] = $product->getTitle();
325
                $data["quantity"] = (int) $item->Quantity;
326
                $data["unitPrice"] = $product->getPrice();
327
                $data["href"] = $item->Link();
328
                $data['categories'] = $product->getCategories()->column('Title');
329
                $data["addLink"] = $item->addLink();
330
                $data["removeLink"] = $item->removeLink();
331
                $data["removeallLink"] = $item->removeallLink();
332
                $data["setquantityLink"] = $item->setquantityLink();
333
334
                // Image
335
                if ($item->Image()) {
336
                    $image = $item->Image()->ScaleWidth((int) ProductImageExtension::config()->cart_image_width);
337
                    $data["image"] = array(
338
                        'alt' => $image->getTitle(),
339
                        'src' => $image->getAbsoluteURL(),
340
                        'width' => $image->getWidth(),
341
                        'height' => $image->getHeight(),
342
                    );
343
                }
344
345
                // Variations
346
                if ($subtitle = $item->SubTitle()) {
347
                    $data['subtitle'] = $subtitle;
348
                }
349
350
                $result[] = $data;
351
            }
352
        }
353
        return $result;
354
    }
355
356
    /**
357
     * Provide a copy of the current order's modifiers
358
     * @return array of modifiers (note: this excludes subtotal and grandtotal)
359
     */
360
    protected function getCurrentShoppingCartModifiers()
361
    {
362
        $result = [];
363
        $shoppingcart = ShoppingCart::curr();
364
365
        if ($shoppingcart->Modifiers()->exists()) {
366
            $modifiers = $shoppingcart->Modifiers();
367
            foreach ($modifiers->sort('Sort')->getIterator() as $modifier) {
368
                if ($modifier->ShowInTable()) {
369
                    $data = array(
370
                        'id' => (string) $modifier->ID,
371
                        'tableTitle' => $modifier->getTableTitle(),
372
                        'tableValue' => (float) $modifier->TableValue(),
373
                    );
374
375
                    if (method_exists($modifier, 'Link')) {
376
                        // add if there is a link
377
                        $data["href"] = $modifier->Link();
378
                    }
379
380
                    if (method_exists($modifier, 'removeLink')) {
381
                        // add if there is a canRemove method
382
                        $data["removeLink"] = $modifier->removeLink();
383
                    }
384
385
                    $result[] = $data;
386
                }
387
            }
388
        }
389
        return $result;
390
    }
391
}
392