Compare commits

...
34 Commits
Author SHA1 Message Date
Joel Male b3ef4c38fc 1.0.11 2024-09-23 07:48:27 +10:00
Joel Male a45121ca63 Merge pull request #20 from wearepixel/task/fix-subtotal-always-being-used-if-the-total-is-$0
Task: Fix subtotal always being used when cart conditions on the total bring it to $0
2024-09-23 07:48:06 +10:00
Joel Male 5505f121c7 fix subtotal always being used 2024-09-23 07:45:59 +10:00
Joel Male 472d505041 wip: fix issue with conditions not being properly removed 2024-09-18 15:56:12 +10:00
Joel Male c6c4240c5f 1.0.9 2024-09-08 18:27:44 +10:00
Joel Male 54d7c8a54f Merge pull request #17 from wearepixel/feature/livewire-support-for-nested-collections
Better Livewire Support
2024-09-08 12:23:22 +10:00
Joel Male a8d743eb9b remove php formatting 2024-09-08 12:22:03 +10:00
Pixel Tech b7381573e8 Apply Laravel Pint
Signed-off-by: Pixel Tech <tech@wearepixel.com.au>
2024-09-08 02:21:01 +00:00
Joel Male d4d4df7d58 pint fixes 2024-09-08 12:20:36 +10:00
Pixel Tech 6ea2cb3b8b Apply Laravel Pint
Signed-off-by: Pixel Tech <tech@wearepixel.com.au>
2024-09-07 22:36:00 +00:00
Joel Male 7a2c41e02d add better livewire support
- and reset collection indexes properly
2024-09-08 08:32:51 +10:00
Joel Male 9a59857825 Merge pull request #12 from wearepixel/feature/targets-to-activate-cart-conditions
Feature: Add targets to cart conditions
2024-09-04 09:38:34 +10:00
Joel Male 43238b6f2e revert php 8.0 support 2024-09-04 09:33:49 +10:00
Joel Male c0f0fcd2f0 fix 8.0 tests 2024-09-04 09:30:28 +10:00
Joel Male 185c4572ae fix tests 2024-09-04 09:26:50 +10:00
Pixel Tech c111cda3aa Apply Laravel Pint
Signed-off-by: Pixel Tech <tech@wearepixel.com.au>
2024-09-03 23:16:53 +00:00
Joel Male ab9eb6c873 fix tests 2024-09-04 09:16:15 +10:00
Joel Male 7ee26add8d undo extra changes 2024-09-04 09:14:23 +10:00
Joel Male 05318b7b13 working on deprecations and code cleanup 2024-09-03 21:41:45 +10:00
Joel Male 4d2efcdeae fix tests for cart conditions 2024-09-03 21:07:58 +10:00
Joel Male a269c188e4 initial functionality 2024-09-03 20:22:03 +10:00
Joel Male 2ccba20119 1.0.8 2024-08-30 10:08:47 +10:00
Joel Male 313a4f7aa2 Revert "1.0.7"
This reverts commit 4a312a37e2.
2024-08-30 10:08:27 +10:00
Joel Male 4a312a37e2 1.0.7 2024-08-30 09:44:40 +10:00
github-actions[bot] 274a8504af Merge pull request #10 from wearepixel/dependabot/composer/master/pestphp/pest-2.35.1
Bump pestphp/pest from 2.35.0 to 2.35.1
2024-08-26 12:56:01 +00:00
dependabot[bot] 4f22672ca5 Bump pestphp/pest from 2.35.0 to 2.35.1
Bumps [pestphp/pest](https://github.com/pestphp/pest) from 2.35.0 to 2.35.1.
- [Release notes](https://github.com/pestphp/pest/releases)
- [Changelog](https://github.com/pestphp/pest/blob/2.x/RELEASE.md)
- [Commits](https://github.com/pestphp/pest/compare/v2.35.0...v2.35.1)

---
updated-dependencies:
- dependency-name: pestphp/pest
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-26 12:55:45 +00:00
Joel Male 61475a7060 1.0.6 2024-08-26 10:58:14 +10:00
Joel Male 6604cf984d fix tests & validation errors 2024-08-26 10:57:02 +10:00
Joel Male 7d955d722c Merge pull request #9 from wearepixel/task/add-items-with-no-price
Add items with no price
2024-08-26 10:49:47 +10:00
Joel Male 54d94d8d12 Add items with no price 2024-08-26 10:38:20 +10:00
Joel Male e49ebe02e0 1.0.4 2024-08-20 16:58:57 +10:00
Joel Male 28b451583d Merge pull request #8 from wearepixel/issue/cart-conditions-break-if-one-makes-the-subtotal-free-and-another-adds-to-the-subtotal
Cart conditions break if one makes the subtotal free and another adds to the subtotal
2024-08-20 16:58:24 +10:00
Joel Male 3673f360b7 feat: fix tests 2024-08-20 16:57:11 +10:00
Joel Male f6447ad4d9 feat: add failing tests 2024-08-20 16:57:06 +10:00
10 changed files with 909 additions and 466 deletions
-25
View File
@@ -1,25 +0,0 @@
name: PHP Formatting
on: pull_request
jobs:
php-formatting:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: "Run Pint"
uses: aglipanci/laravel-pint-action@latest
with:
verboseMode: true
configPath: "pint.json"
pintVersion: 1.17.2
- name: Commit changes
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: "Apply Laravel Pint"
commit_options: '--no-verify --signoff'
file_pattern: "*.php"
commit_user_name: "Pixel Tech"
commit_user_email: "tech@wearepixel.com.au"
commit_author: "Pixel Tech<tech@wearepixel.com.au>"
+1 -1
View File
@@ -13,7 +13,7 @@ jobs:
strategy: strategy:
fail-fast: true fail-fast: true
matrix: matrix:
php: ['8.1','8.2', '8.3'] php: ['8.1', '8.2', '8.3']
stability: [prefer-stable] stability: [prefer-stable]
steps: steps:
+111 -8
View File
@@ -76,9 +76,9 @@ ### Round Mode
'round_mode' => env('LARAVEL_CART_ROUND_MODE', 'down'), 'round_mode' => env('LARAVEL_CART_ROUND_MODE', 'down'),
``` ```
## HOW TO USE ## Usage
- [Usage](#usage) - [Basic Usage](#basic-usage)
- [Conditions](#conditions) - [Conditions](#conditions)
- [Items](#items) - [Items](#items)
- [Associating Models](#associating-models) - [Associating Models](#associating-models)
@@ -288,12 +288,14 @@ ### Clearing the Cart: **Cart::clear()**
## Conditions ## Conditions
Conditions are very useful in terms for adding things like discounts, taxes, shipping costs, etc. Conditions are very useful for adding things like discounts, taxes, shipping, etc.
Conditions can be added on the entire cart or on individual items. Conditions can be added on the entire cart or on individual items, and can even be applied only at certain cart values.
Conditions on a cart level should always have a `target` of `subtotal` or `total`. This tells the cart which value to apply the condition to. Conditions on a cart level should always have a `target` of `subtotal` or `total`. This tells the cart which value to apply the condition to.
You can provide an optional `minimum` value which should be the dollar value in which the target (subtotal or total) needs to be for the condition to be active and impact the cart.
You can also provide an `order` to cart conditions which tells the cart in what order to apply the conditions. Item level conditions do not support the `order` parameter. You can also provide an `order` to cart conditions which tells the cart in what order to apply the conditions. Item level conditions do not support the `order` parameter.
### Conditions on the cart ### Conditions on the cart
@@ -362,18 +364,81 @@ #### Getting conditions on the cart: **Cart::getConditions()**
$condition->getType(); // the type $condition->getType(); // the type
$condition->getValue(); // the value of the condition $condition->getValue(); // the value of the condition
$condition->getOrder(); // the order of the condition $condition->getOrder(); // the order of the condition
$condition->getMinimum(); // the minimum dollar amount of the target, needed to activate the condition
$condition->getMaximum(); // the maximum dollar amount of the target, needed to keep the condition active
$condition->getAttributes(); // the attributes of the condition, returns an empty [] if no attributes added $condition->getAttributes(); // the attributes of the condition, returns an empty [] if no attributes added
} }
```
#### Getting conditions on the cart as an array: **Cart::getConditions(array: true)**
You can get all cart conditions in array format by passing "array: true". This is useful if you want to store the carts conditions on a Livewire component since by default we have collections inside collections for conditions which Livewire does not support.
```php
$cartConditions = Cart::getConditions(true);
$cartConditions = Cart::getConditions(active: true);
foreach ($cartConditions as $condition) {
$condition['name']; // the name of the condition
$condition['type']; // the type
$condition['value']; // the value of the condition
$condition['order']; // the order of the condition
$condition['minimum']; // the minimum dollar amount of the target, needed to activate the condition
$condition['maximum']; // the maximum dollar amount of the target, needed to keep the condition active
$condition['attributes']; // the attributes of the condition, returns an empty [] if no attributes added
}
```
#### Getting conditions by name: **Cart::getCondition($conditionName)**
```php
$condition = Cart::getCondition('GST');
// You can also get a condition that has been applied on the cart by using its name:
$condition = Cart::getCondition('Tax: 10%');
$condition->getTarget(); // the target of which the condition was applied $condition->getTarget(); // the target of which the condition was applied
$condition->getName(); // the name of the condition $condition->getName(); // the name of the condition
$condition->getType(); // the type $condition->getType(); // the type
$condition->getValue(); // the value of the condition $condition->getValue(); // the value of the condition
$condition->getMinimum(); // the minimum dollar amount of the target, needed to activate the condition
$condition->getMaximum(); // the maximum dollar amount of the target, needed to keep the condition active
$condition->getAttributes(); // the attributes of the condition, returns an empty [] if no attributes added $condition->getAttributes(); // the attributes of the condition, returns an empty [] if no attributes added
``` ```
#### Getting active conditions on the cart: **Cart::getConditions(active: true)**
You can get only active conditions by passsing `active: true` to the `getConditions()` method.
This will return conditions that are actively being applied to the cart (i.e if they meet their minimum or maximum value)
```php
$tenPercentOff = new CartCondition([
'name' => '10% Off',
'type' => 'discount',
'target' => 'subtotal',
'value' => '-10%',
'minimum' => 120,
'order' => 1,
]);
Cart::getConditions(active: true);
// will return "10% Off" if the subtotal of the cart is $200.
// will return no conditions if the subtotal is $100.
$shipping = new CartCondition([
'name' => 'Shipping',
'type' => 'discount',
'target' => 'subtotal',
'value' => '10',
'maximum' => 200,
'order' => 1,
]);
Cart::getConditions(active: true);
// will return "Shipping" if the subtotal of the cart is less than or equal 200
// will return no conditions if the subtotal is $210
```
### Calculating condition value ### Calculating condition value
There are 2 ways to calculate the value of a condition: There are 2 ways to calculate the value of a condition:
@@ -385,7 +450,7 @@ #### Using the `getCalculatedValue` method on the condition instance
```php ```php
$subTotal = Cart::getSubTotal(); $subTotal = Cart::getSubTotal();
$condition = Cart::getCondition('VAT 12.5%'); $condition = Cart::getCondition('10% GST');
$conditionCalculatedValue = $condition->getCalculatedValue($subTotal); $conditionCalculatedValue = $condition->getCalculatedValue($subTotal);
``` ```
@@ -422,6 +487,44 @@ #### Using the `getCalculatedValueForCondition` method on the cart instance
Cart::getCalculatedValueForCondition('Gift Card'); // returns 0 as the coupon discount is applied first and brings the subtotal to 0 Cart::getCalculatedValueForCondition('Gift Card'); // returns 0 as the coupon discount is applied first and brings the subtotal to 0
``` ```
### Adding conditions that activate once a minimum value is met
You can add a `minimum` amount required for a condition to activate.
This is useful for applying discounts only after certain cart values, i.e: 10% off for any purchases over $120.
```php
$tenPercentOff = new CartCondition([
'name' => '10% Off',
'type' => 'discount',
'target' => 'subtotal',
'value' => '-10%',
'minimum' => 120,
'order' => 1,
]);
Cart::condition($tenPercentOff)
```
### Adding conditions that only activate up to a maximum value
You can add a `maximum` amount required for a condition to activate.
This is useful for applying discounts up until amounts, i.e shipping for anything below $200, and free shipping above.
```php
$shipping = new CartCondition([
'name' => 'Shipping',
'type' => 'discount',
'target' => 'subtotal',
'value' => '12',
'maximum' => 200,
'order' => 1,
]);
Cart::condition($shipping)
```
### Condition on items ### Condition on items
Item conditions are useful if you have discounts to be applied specifically on an item and not on the whole cart value. Item conditions are useful if you have discounts to be applied specifically on an item and not on the whole cart value.
@@ -483,7 +586,7 @@ ### Condition on items
$cartSubTotal = Cart::getSubTotal(); $cartSubTotal = Cart::getSubTotal();
``` ```
#### Add condition to existing Item on the cart: **Cart::addItemCondition($productId, $itemCondition)** #### Add a condition to an existing item on the cart: **Cart::addItemCondition($productId, $itemCondition)**
Adding Condition to an existing Item on the cart is simple as well. Adding Condition to an existing Item on the cart is simple as well.
+4 -4
View File
@@ -1,6 +1,6 @@
{ {
"name": "wearepixel/laravel-cart", "name": "wearepixel/laravel-cart",
"version": "1.0.3", "version": "1.0.11",
"description": "A cart implementation for Laravel", "description": "A cart implementation for Laravel",
"keywords": [ "keywords": [
"laravel", "laravel",
@@ -26,9 +26,9 @@
}, },
"require-dev": { "require-dev": {
"mockery/mockery": "^1.4.2", "mockery/mockery": "^1.4.2",
"laravel/pint": "dev-main", "laravel/pint": "^1.17",
"pestphp/pest": "2.35.0", "pestphp/pest": "2.35.1",
"larapack/dd": "dev-master" "larapack/dd": "1.1"
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {
Generated
+165 -166
View File
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "f22ad76e04818683f42bf13aa7a5e4ef", "content-hash": "bf8d3b76695f06430eaf04e5eeacb58c",
"packages": [ "packages": [
{ {
"name": "brick/math", "name": "brick/math",
@@ -378,12 +378,12 @@
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/illuminate/collections.git", "url": "https://github.com/illuminate/collections.git",
"reference": "dc68a7ccad93f3c2baa0bc8f559431c06391aa75" "reference": "66d2c9bdf5641599735d402c1c504b54734a9cca"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/illuminate/collections/zipball/dc68a7ccad93f3c2baa0bc8f559431c06391aa75", "url": "https://api.github.com/repos/illuminate/collections/zipball/66d2c9bdf5641599735d402c1c504b54734a9cca",
"reference": "dc68a7ccad93f3c2baa0bc8f559431c06391aa75", "reference": "66d2c9bdf5641599735d402c1c504b54734a9cca",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -425,7 +425,7 @@
"issues": "https://github.com/laravel/framework/issues", "issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework" "source": "https://github.com/laravel/framework"
}, },
"time": "2024-08-01T18:54:27+00:00" "time": "2024-08-23T18:49:36+00:00"
}, },
{ {
"name": "illuminate/conditionable", "name": "illuminate/conditionable",
@@ -479,12 +479,12 @@
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/illuminate/container.git", "url": "https://github.com/illuminate/container.git",
"reference": "f47be671981a4438257c4fbfc3ad257f4e3e929a" "reference": "85e3396fde3139eae3f37128222c9a7746ca4bbb"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/illuminate/container/zipball/f47be671981a4438257c4fbfc3ad257f4e3e929a", "url": "https://api.github.com/repos/illuminate/container/zipball/85e3396fde3139eae3f37128222c9a7746ca4bbb",
"reference": "f47be671981a4438257c4fbfc3ad257f4e3e929a", "reference": "85e3396fde3139eae3f37128222c9a7746ca4bbb",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -522,7 +522,7 @@
"issues": "https://github.com/laravel/framework/issues", "issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework" "source": "https://github.com/laravel/framework"
}, },
"time": "2024-08-05T15:04:01+00:00" "time": "2024-08-21T16:01:30+00:00"
}, },
{ {
"name": "illuminate/contracts", "name": "illuminate/contracts",
@@ -530,12 +530,12 @@
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/illuminate/contracts.git", "url": "https://github.com/illuminate/contracts.git",
"reference": "34ead9385e0eab7e947807d77da66faf9bdf95ff" "reference": "af9b459f195d57f279ec30a45446ddaeb3337bcb"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/illuminate/contracts/zipball/34ead9385e0eab7e947807d77da66faf9bdf95ff", "url": "https://api.github.com/repos/illuminate/contracts/zipball/af9b459f195d57f279ec30a45446ddaeb3337bcb",
"reference": "34ead9385e0eab7e947807d77da66faf9bdf95ff", "reference": "af9b459f195d57f279ec30a45446ddaeb3337bcb",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -570,7 +570,7 @@
"issues": "https://github.com/laravel/framework/issues", "issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework" "source": "https://github.com/laravel/framework"
}, },
"time": "2024-08-01T19:08:33+00:00" "time": "2024-08-21T16:02:16+00:00"
}, },
{ {
"name": "illuminate/filesystem", "name": "illuminate/filesystem",
@@ -578,12 +578,12 @@
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/illuminate/filesystem.git", "url": "https://github.com/illuminate/filesystem.git",
"reference": "43b8d2af61dd6ca882e192fa4ca803d2294d4507" "reference": "7e44057ac57635465c91c3fc6247c5d87bd1feed"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/illuminate/filesystem/zipball/43b8d2af61dd6ca882e192fa4ca803d2294d4507", "url": "https://api.github.com/repos/illuminate/filesystem/zipball/7e44057ac57635465c91c3fc6247c5d87bd1feed",
"reference": "43b8d2af61dd6ca882e192fa4ca803d2294d4507", "reference": "7e44057ac57635465c91c3fc6247c5d87bd1feed",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -637,7 +637,7 @@
"issues": "https://github.com/laravel/framework/issues", "issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework" "source": "https://github.com/laravel/framework"
}, },
"time": "2024-06-28T20:10:30+00:00" "time": "2024-09-03T13:20:49+00:00"
}, },
{ {
"name": "illuminate/macroable", "name": "illuminate/macroable",
@@ -691,12 +691,12 @@
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/illuminate/support.git", "url": "https://github.com/illuminate/support.git",
"reference": "089c989beac69bd2633466d72d6ed07068b623ac" "reference": "51efc0516526413b4be641a1731d15d4394de2ff"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/illuminate/support/zipball/089c989beac69bd2633466d72d6ed07068b623ac", "url": "https://api.github.com/repos/illuminate/support/zipball/51efc0516526413b4be641a1731d15d4394de2ff",
"reference": "089c989beac69bd2633466d72d6ed07068b623ac", "reference": "51efc0516526413b4be641a1731d15d4394de2ff",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -757,7 +757,7 @@
"issues": "https://github.com/laravel/framework/issues", "issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework" "source": "https://github.com/laravel/framework"
}, },
"time": "2024-08-07T14:43:54+00:00" "time": "2024-09-03T13:21:20+00:00"
}, },
{ {
"name": "illuminate/translation", "name": "illuminate/translation",
@@ -877,12 +877,12 @@
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/briannesbitt/Carbon.git", "url": "https://github.com/briannesbitt/Carbon.git",
"reference": "cb4374784c87d0a0294e8513a52eb63c0aff3139" "reference": "bbd3eef89af8ba66a3aa7952b5439168fbcc529f"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/cb4374784c87d0a0294e8513a52eb63c0aff3139", "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/bbd3eef89af8ba66a3aa7952b5439168fbcc529f",
"reference": "cb4374784c87d0a0294e8513a52eb63c0aff3139", "reference": "bbd3eef89af8ba66a3aa7952b5439168fbcc529f",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -976,7 +976,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2024-07-16T22:29:20+00:00" "time": "2024-08-19T06:22:39+00:00"
}, },
{ {
"name": "psr/clock", "name": "psr/clock",
@@ -1206,18 +1206,86 @@
], ],
"time": "2024-08-06T10:13:52+00:00" "time": "2024-08-06T10:13:52+00:00"
}, },
{
"name": "symfony/deprecation-contracts",
"version": "dev-main",
"source": {
"type": "git",
"url": "https://github.com/symfony/deprecation-contracts.git",
"reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1",
"reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1",
"shasum": ""
},
"require": {
"php": ">=8.1"
},
"default-branch": true,
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "3.5-dev"
},
"thanks": {
"name": "symfony/contracts",
"url": "https://github.com/symfony/contracts"
}
},
"autoload": {
"files": [
"function.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "A generic function and convention to trigger deprecation notices",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2024-04-18T09:32:20+00:00"
},
{ {
"name": "symfony/finder", "name": "symfony/finder",
"version": "7.2.x-dev", "version": "7.2.x-dev",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/finder.git", "url": "https://github.com/symfony/finder.git",
"reference": "0470b8dc10ca08d23aeaabbed5b961c928e4d89d" "reference": "afa87bce0d224a744963ecc8db07b1f0f96a3518"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/finder/zipball/0470b8dc10ca08d23aeaabbed5b961c928e4d89d", "url": "https://api.github.com/repos/symfony/finder/zipball/afa87bce0d224a744963ecc8db07b1f0f96a3518",
"reference": "0470b8dc10ca08d23aeaabbed5b961c928e4d89d", "reference": "afa87bce0d224a744963ecc8db07b1f0f96a3518",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -1268,7 +1336,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2024-08-13T14:29:53+00:00" "time": "2024-09-03T13:22:29+00:00"
}, },
{ {
"name": "symfony/http-foundation", "name": "symfony/http-foundation",
@@ -1276,12 +1344,12 @@
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/http-foundation.git", "url": "https://github.com/symfony/http-foundation.git",
"reference": "79d0023c23d92d49c43be47c726e92366b4d3a81" "reference": "5a92e38016224d35a68ded60297b94d87b21a494"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/79d0023c23d92d49c43be47c726e92366b4d3a81", "url": "https://api.github.com/repos/symfony/http-foundation/zipball/5a92e38016224d35a68ded60297b94d87b21a494",
"reference": "79d0023c23d92d49c43be47c726e92366b4d3a81", "reference": "5a92e38016224d35a68ded60297b94d87b21a494",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -1345,7 +1413,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2024-08-13T12:32:31+00:00" "time": "2024-09-03T14:09:19+00:00"
}, },
{ {
"name": "symfony/mime", "name": "symfony/mime",
@@ -1836,16 +1904,17 @@
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/translation.git", "url": "https://github.com/symfony/translation.git",
"reference": "a50ed69ace45368e096bc3981f456089253ed6cb" "reference": "a1c4be3a5885b9785b131c5a30d93e611848cb1d"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/translation/zipball/a50ed69ace45368e096bc3981f456089253ed6cb", "url": "https://api.github.com/repos/symfony/translation/zipball/a1c4be3a5885b9785b131c5a30d93e611848cb1d",
"reference": "a50ed69ace45368e096bc3981f456089253ed6cb", "reference": "a1c4be3a5885b9785b131c5a30d93e611848cb1d",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=8.2", "php": ">=8.2",
"symfony/deprecation-contracts": "^2.5|^3",
"symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-mbstring": "~1.0",
"symfony/translation-contracts": "^2.5|^3.0" "symfony/translation-contracts": "^2.5|^3.0"
}, },
@@ -1922,7 +1991,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2024-08-05T08:22:14+00:00" "time": "2024-08-19T08:28:32+00:00"
}, },
{ {
"name": "symfony/translation-contracts", "name": "symfony/translation-contracts",
@@ -2223,16 +2292,16 @@
}, },
{ {
"name": "fidry/cpu-core-counter", "name": "fidry/cpu-core-counter",
"version": "1.1.0", "version": "1.2.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/theofidry/cpu-core-counter.git", "url": "https://github.com/theofidry/cpu-core-counter.git",
"reference": "f92996c4d5c1a696a6a970e20f7c4216200fcc42" "reference": "8520451a140d3f46ac33042715115e290cf5785f"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/f92996c4d5c1a696a6a970e20f7c4216200fcc42", "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/8520451a140d3f46ac33042715115e290cf5785f",
"reference": "f92996c4d5c1a696a6a970e20f7c4216200fcc42", "reference": "8520451a140d3f46ac33042715115e290cf5785f",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -2272,7 +2341,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/theofidry/cpu-core-counter/issues", "issues": "https://github.com/theofidry/cpu-core-counter/issues",
"source": "https://github.com/theofidry/cpu-core-counter/tree/1.1.0" "source": "https://github.com/theofidry/cpu-core-counter/tree/1.2.0"
}, },
"funding": [ "funding": [
{ {
@@ -2280,7 +2349,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2024-02-07T09:43:46+00:00" "time": "2024-08-06T10:04:20+00:00"
}, },
{ {
"name": "filp/whoops", "name": "filp/whoops",
@@ -2508,16 +2577,16 @@
}, },
{ {
"name": "laravel/pint", "name": "laravel/pint",
"version": "dev-main", "version": "v1.5.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/laravel/pint.git", "url": "https://github.com/laravel/pint.git",
"reference": "e24a6aa83b23c0b64ab3486d68fbc88ab266e03f" "reference": "e0a8cef58b74662f27355be9cdea0e726bbac362"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/laravel/pint/zipball/e24a6aa83b23c0b64ab3486d68fbc88ab266e03f", "url": "https://api.github.com/repos/laravel/pint/zipball/e0a8cef58b74662f27355be9cdea0e726bbac362",
"reference": "e24a6aa83b23c0b64ab3486d68fbc88ab266e03f", "reference": "e0a8cef58b74662f27355be9cdea0e726bbac362",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -2525,18 +2594,17 @@
"ext-mbstring": "*", "ext-mbstring": "*",
"ext-tokenizer": "*", "ext-tokenizer": "*",
"ext-xml": "*", "ext-xml": "*",
"php": "^8.1.0" "php": "^8.0"
}, },
"require-dev": { "require-dev": {
"friendsofphp/php-cs-fixer": "^3.61.1", "friendsofphp/php-cs-fixer": "^3.14.4",
"illuminate/view": "^10.48.18", "illuminate/view": "^9.51.0",
"larastan/larastan": "^2.9.8", "laravel-zero/framework": "^9.2.0",
"laravel-zero/framework": "^10.4.0", "mockery/mockery": "^1.5.1",
"mockery/mockery": "^1.6.12", "nunomaduro/larastan": "^2.4.0",
"nunomaduro/termwind": "^1.15.1", "nunomaduro/termwind": "^1.15.1",
"pestphp/pest": "^2.35.0" "pestphp/pest": "^1.22.4"
}, },
"default-branch": true,
"bin": [ "bin": [
"builds/pint" "builds/pint"
], ],
@@ -2571,7 +2639,7 @@
"issues": "https://github.com/laravel/pint/issues", "issues": "https://github.com/laravel/pint/issues",
"source": "https://github.com/laravel/pint" "source": "https://github.com/laravel/pint"
}, },
"time": "2024-08-06T15:12:57+00:00" "time": "2023-02-14T16:31:02+00:00"
}, },
{ {
"name": "mockery/mockery", "name": "mockery/mockery",
@@ -2963,21 +3031,21 @@
}, },
{ {
"name": "pestphp/pest", "name": "pestphp/pest",
"version": "v2.35.0", "version": "v2.35.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/pestphp/pest.git", "url": "https://github.com/pestphp/pest.git",
"reference": "d0ff2c8ec294b7aa7fcb0f3ddc4fdec864234646" "reference": "b13acb630df52c06123588d321823c31fc685545"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/pestphp/pest/zipball/d0ff2c8ec294b7aa7fcb0f3ddc4fdec864234646", "url": "https://api.github.com/repos/pestphp/pest/zipball/b13acb630df52c06123588d321823c31fc685545",
"reference": "d0ff2c8ec294b7aa7fcb0f3ddc4fdec864234646", "reference": "b13acb630df52c06123588d321823c31fc685545",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"brianium/paratest": "^7.3.1", "brianium/paratest": "^7.3.1",
"nunomaduro/collision": "^7.10.0|^8.3.0", "nunomaduro/collision": "^7.10.0|^8.4.0",
"nunomaduro/termwind": "^1.15.1|^2.0.1", "nunomaduro/termwind": "^1.15.1|^2.0.1",
"pestphp/pest-plugin": "^2.1.1", "pestphp/pest-plugin": "^2.1.1",
"pestphp/pest-plugin-arch": "^2.7.0", "pestphp/pest-plugin-arch": "^2.7.0",
@@ -3055,7 +3123,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/pestphp/pest/issues", "issues": "https://github.com/pestphp/pest/issues",
"source": "https://github.com/pestphp/pest/tree/v2.35.0" "source": "https://github.com/pestphp/pest/tree/v2.35.1"
}, },
"funding": [ "funding": [
{ {
@@ -3067,7 +3135,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2024-08-02T10:57:29+00:00" "time": "2024-08-20T21:41:50+00:00"
}, },
{ {
"name": "pestphp/pest-plugin", "name": "pestphp/pest-plugin",
@@ -3510,16 +3578,16 @@
}, },
{ {
"name": "phpstan/phpdoc-parser", "name": "phpstan/phpdoc-parser",
"version": "1.29.1", "version": "1.30.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/phpstan/phpdoc-parser.git", "url": "https://github.com/phpstan/phpdoc-parser.git",
"reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4" "reference": "5ceb0e384997db59f38774bf79c2a6134252c08f"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/fcaefacf2d5c417e928405b71b400d4ce10daaf4", "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/5ceb0e384997db59f38774bf79c2a6134252c08f",
"reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4", "reference": "5ceb0e384997db59f38774bf79c2a6134252c08f",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -3551,9 +3619,9 @@
"description": "PHPDoc parser with support for nullable, intersection and generic types", "description": "PHPDoc parser with support for nullable, intersection and generic types",
"support": { "support": {
"issues": "https://github.com/phpstan/phpdoc-parser/issues", "issues": "https://github.com/phpstan/phpdoc-parser/issues",
"source": "https://github.com/phpstan/phpdoc-parser/tree/1.29.1" "source": "https://github.com/phpstan/phpdoc-parser/tree/1.30.0"
}, },
"time": "2024-05-31T08:52:43+00:00" "time": "2024-08-29T09:54:52+00:00"
}, },
{ {
"name": "phpunit/php-code-coverage", "name": "phpunit/php-code-coverage",
@@ -3561,28 +3629,28 @@
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
"reference": "09d5f55e54c20f2353a790d09772db3ad577b9ac" "reference": "7e308268858ed6baedc8704a304727d20bc07c77"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/09d5f55e54c20f2353a790d09772db3ad577b9ac", "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/7e308268858ed6baedc8704a304727d20bc07c77",
"reference": "09d5f55e54c20f2353a790d09772db3ad577b9ac", "reference": "7e308268858ed6baedc8704a304727d20bc07c77",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"ext-dom": "*", "ext-dom": "*",
"ext-libxml": "*", "ext-libxml": "*",
"ext-xmlwriter": "*", "ext-xmlwriter": "*",
"nikic/php-parser": "^4.18 || ^5.0", "nikic/php-parser": "^4.19.1 || ^5.1.0",
"php": ">=8.1", "php": ">=8.1",
"phpunit/php-file-iterator": "^4.0", "phpunit/php-file-iterator": "^4.1.0",
"phpunit/php-text-template": "^3.0", "phpunit/php-text-template": "^3.0.1",
"sebastian/code-unit-reverse-lookup": "^3.0", "sebastian/code-unit-reverse-lookup": "^3.0.0",
"sebastian/complexity": "^3.0", "sebastian/complexity": "^3.2.0",
"sebastian/environment": "^6.0", "sebastian/environment": "^6.1.0",
"sebastian/lines-of-code": "^2.0", "sebastian/lines-of-code": "^2.0.2",
"sebastian/version": "^4.0", "sebastian/version": "^4.0.1",
"theseer/tokenizer": "^1.2.0" "theseer/tokenizer": "^1.2.3"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^10.1" "phpunit/phpunit": "^10.1"
@@ -3623,7 +3691,7 @@
"support": { "support": {
"issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
"security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy",
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1" "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.16"
}, },
"funding": [ "funding": [
{ {
@@ -3631,7 +3699,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2024-07-17T05:15:22+00:00" "time": "2024-08-22T04:31:57+00:00"
}, },
{ {
"name": "phpunit/php-file-iterator", "name": "phpunit/php-file-iterator",
@@ -3985,12 +4053,12 @@
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/php-fig/log.git", "url": "https://github.com/php-fig/log.git",
"reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" "reference": "79dff0b268932c640297f5208d6298f71855c03e"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", "url": "https://api.github.com/repos/php-fig/log/zipball/79dff0b268932c640297f5208d6298f71855c03e",
"reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", "reference": "79dff0b268932c640297f5208d6298f71855c03e",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -4026,9 +4094,9 @@
"psr-3" "psr-3"
], ],
"support": { "support": {
"source": "https://github.com/php-fig/log/tree/3.0.0" "source": "https://github.com/php-fig/log/tree/3.0.1"
}, },
"time": "2021-07-14T16:46:02+00:00" "time": "2024-08-21T13:31:24+00:00"
}, },
{ {
"name": "sebastian/cli-parser", "name": "sebastian/cli-parser",
@@ -4959,12 +5027,12 @@
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/console.git", "url": "https://github.com/symfony/console.git",
"reference": "cc2dd55c49e04b10cec4aa6e47e099a2d1656845" "reference": "ee7ee22b1dabcff731b7d79d3633c96251ad8404"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/cc2dd55c49e04b10cec4aa6e47e099a2d1656845", "url": "https://api.github.com/repos/symfony/console/zipball/ee7ee22b1dabcff731b7d79d3633c96251ad8404",
"reference": "cc2dd55c49e04b10cec4aa6e47e099a2d1656845", "reference": "ee7ee22b1dabcff731b7d79d3633c96251ad8404",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -5044,75 +5112,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2024-08-15T22:49:18+00:00" "time": "2024-08-30T15:40:32+00:00"
},
{
"name": "symfony/deprecation-contracts",
"version": "dev-main",
"source": {
"type": "git",
"url": "https://github.com/symfony/deprecation-contracts.git",
"reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1",
"reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1",
"shasum": ""
},
"require": {
"php": ">=8.1"
},
"default-branch": true,
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "3.5-dev"
},
"thanks": {
"name": "symfony/contracts",
"url": "https://github.com/symfony/contracts"
}
},
"autoload": {
"files": [
"function.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "A generic function and convention to trigger deprecation notices",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2024-04-18T09:32:20+00:00"
}, },
{ {
"name": "symfony/polyfill-ctype", "name": "symfony/polyfill-ctype",
@@ -5511,12 +5511,12 @@
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/var-dumper.git", "url": "https://github.com/symfony/var-dumper.git",
"reference": "122ba59267fc82caa8f1f509332d4b94a223013b" "reference": "f74e6c4199357f1b566a67bbe834ebd7de658839"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/122ba59267fc82caa8f1f509332d4b94a223013b", "url": "https://api.github.com/repos/symfony/var-dumper/zipball/f74e6c4199357f1b566a67bbe834ebd7de658839",
"reference": "122ba59267fc82caa8f1f509332d4b94a223013b", "reference": "f74e6c4199357f1b566a67bbe834ebd7de658839",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -5532,7 +5532,7 @@
"symfony/http-kernel": "^6.4|^7.0", "symfony/http-kernel": "^6.4|^7.0",
"symfony/process": "^6.4|^7.0", "symfony/process": "^6.4|^7.0",
"symfony/uid": "^6.4|^7.0", "symfony/uid": "^6.4|^7.0",
"twig/twig": "^3.0.4" "twig/twig": "^3.12|^4.0"
}, },
"bin": [ "bin": [
"Resources/bin/var-dump-server" "Resources/bin/var-dump-server"
@@ -5586,7 +5586,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2024-08-13T14:29:53+00:00" "time": "2024-09-02T15:30:47+00:00"
}, },
{ {
"name": "ta-tikoma/phpunit-architecture-test", "name": "ta-tikoma/phpunit-architecture-test",
@@ -5759,7 +5759,6 @@
"aliases": [], "aliases": [],
"minimum-stability": "dev", "minimum-stability": "dev",
"stability-flags": { "stability-flags": {
"laravel/pint": 20,
"larapack/dd": 20 "larapack/dd": 20
}, },
"prefer-stable": false, "prefer-stable": false,
+69 -72
View File
@@ -10,59 +10,22 @@
class Cart class Cart
{ {
/**
* the item storage
*/
protected $session; protected $session;
/**
* the event dispatcher
*/
protected $events; protected $events;
/**
* the cart session key
*/
protected $instanceName; protected $instanceName;
/**
* the session key use for the cart
*/
protected $sessionKey; protected $sessionKey;
/**
* the session key use to persist cart items
*/
protected $sessionKeyCartItems; protected $sessionKeyCartItems;
/**
* the session key use to persist cart conditions
*/
protected $sessionKeyCartConditions; protected $sessionKeyCartConditions;
/**
* Configuration to pass to ItemCollection
*/
protected $config; protected $config;
/**
* This holds the currently added item id in cart for association
*/
protected $currentItemId; protected $currentItemId;
/**
* The number of decimals to use when formatting prices
*/
protected $decimals; protected $decimals;
/**
* The decimal point character
*/
protected $decPoint; protected $decPoint;
/**
* our object constructor
*/
public function __construct($session, $events, $instanceName, $session_key, $config) public function __construct($session, $events, $instanceName, $session_key, $config)
{ {
$this->events = $events; $this->events = $events;
@@ -73,6 +36,7 @@ public function __construct($session, $events, $instanceName, $session_key, $con
$this->sessionKeyCartConditions = $this->sessionKey . '_cart_conditions'; $this->sessionKeyCartConditions = $this->sessionKey . '_cart_conditions';
$this->config = $config; $this->config = $config;
$this->currentItemId = null; $this->currentItemId = null;
$this->fireEvent('created'); $this->fireEvent('created');
} }
@@ -109,20 +73,16 @@ public function getInstanceName()
/** /**
* get an item on a cart by item ID * get an item on a cart by item ID
*
* @return mixed
*/ */
public function get($itemId) public function get($itemId): ?ItemCollection
{ {
return $this->getContent()->get($itemId); return $this->getContent()->get($itemId);
} }
/** /**
* check if an item exists by item ID * check if we have this item in the cart by item ID
*
* @return bool
*/ */
public function has($itemId) public function has($itemId): bool
{ {
return $this->getContent()->has($itemId); return $this->getContent()->has($itemId);
} }
@@ -144,16 +104,15 @@ public function add(
array|CartCondition $conditions = [], array|CartCondition $conditions = [],
?string $associatedModel = null ?string $associatedModel = null
): self { ): self {
// check if its an array of items // check if we are adding an array of items
if (is_array($id)) { if (is_array($id)) {
// the first argument is an array, now we will need to check if it is a multi dimensional // check if we are adding a multi dimensional array
// array, if so, we will iterate through each item and call add again
if (Helpers::isMultiArray($id)) { if (Helpers::isMultiArray($id)) {
foreach ($id as $item) { foreach ($id as $item) {
$this->add( $this->add(
$item['id'], $item['id'],
$item['name'], $item['name'],
$item['price'], isset($item['price']) ? $item['price'] : null,
$item['quantity'], $item['quantity'],
Helpers::issetAndHasValueOrAssignDefault($item['attributes'], []), Helpers::issetAndHasValueOrAssignDefault($item['attributes'], []),
Helpers::issetAndHasValueOrAssignDefault($item['conditions'], []), Helpers::issetAndHasValueOrAssignDefault($item['conditions'], []),
@@ -164,7 +123,7 @@ public function add(
$this->add( $this->add(
$id['id'], $id['id'],
$id['name'], $id['name'],
$id['price'], isset($id['price']) ? $id['price'] : null,
$id['quantity'], $id['quantity'],
Helpers::issetAndHasValueOrAssignDefault($id['attributes'], []), Helpers::issetAndHasValueOrAssignDefault($id['attributes'], []),
Helpers::issetAndHasValueOrAssignDefault($id['conditions'], []), Helpers::issetAndHasValueOrAssignDefault($id['conditions'], []),
@@ -175,6 +134,7 @@ public function add(
return $this; return $this;
} }
// if we are here, we are adding a single item
$data = [ $data = [
'id' => $id, 'id' => $id,
'name' => $name, 'name' => $name,
@@ -191,11 +151,8 @@ public function add(
// validate data // validate data
$item = $this->validate($data); $item = $this->validate($data);
// get the cart
$inCart = $this->get($id);
// if the item is already in the cart we will just update it // if the item is already in the cart we will just update it
if ($inCart) { if ($this->get($id)) {
$this->update($id, $item); $this->update($id, $item);
} else { } else {
$this->addItem($id, $item); $this->addItem($id, $item);
@@ -337,6 +294,9 @@ public function clear()
return true; return true;
} }
/**
* Adds a condition to the cart
*/
/** /**
* Adds a condition to the cart * Adds a condition to the cart
* *
@@ -378,11 +338,29 @@ public function condition(array|CartCondition $condition): self
/** /**
* get conditions applied on the cart * get conditions applied on the cart
* *
* @return CartConditionCollection * @param bool $active - If true, only conditions actually applied on the cart are returned
*/ */
public function getConditions() public function getConditions(bool $array = false, bool $active = false): CartConditionCollection|array
{ {
return new CartConditionCollection($this->session->get($this->sessionKeyCartConditions)); $conditions = new CartConditionCollection(
$this->session->get($this->sessionKeyCartConditions)
);
if ($active) {
return $conditions->filter(function (CartCondition $condition) {
$amount = $condition->getTarget() == 'subtotal' ? $this->getSubTotal(false) : $this->getTotal();
return $condition->getMinimum() === null || $condition->getMinimum() <= $amount;
})->filter(function (CartCondition $condition) {
$amount = $condition->getTarget() == 'subtotal' ? $this->getSubTotal(false) : $this->getTotal();
return $condition->getMaximum() === null || $condition->getMaximum() >= $amount;
});
}
return $array ? $conditions->map(function (CartCondition $condition) {
return $condition->toArray();
})->toArray() : $conditions;
} }
/** /**
@@ -411,12 +389,8 @@ public function getConditionsByType($type)
/** /**
* Remove all the condition with the $type specified * Remove all the condition with the $type specified
* Please Note that this will only remove condition added on cart bases, not those conditions added
* specifically on an per item bases
*
* @return $this
*/ */
public function removeConditionsByType($type) public function removeConditionsByType(string $type)
{ {
$this->getConditionsByType($type)->each(function ($condition) { $this->getConditionsByType($type)->each(function ($condition) {
$this->removeCartCondition($condition->getName()); $this->removeCartCondition($condition->getName());
@@ -424,12 +398,7 @@ public function removeConditionsByType($type)
} }
/** /**
* removes a condition on a cart by condition name, * Remove a condition from the cart
* this can only remove conditions that are added on cart bases not conditions that are added on an item/product.
* If you wish to remove a condition that has been added for a specific item/product, you may
* use the removeItemCondition(itemId, conditionName) method instead.
*
* @return void
*/ */
public function removeCartCondition($conditionName) public function removeCartCondition($conditionName)
{ {
@@ -575,6 +544,12 @@ public function getSubTotal($formatted = true): int|float|string
->filter(function (CartCondition $condition) { ->filter(function (CartCondition $condition) {
return $condition->getTarget() === 'subtotal'; return $condition->getTarget() === 'subtotal';
}) })
->filter(function (CartCondition $condition) use ($subTotalSum) {
return $condition->getMinimum() === null || $condition->getMinimum() <= $subTotalSum;
})
->filter(function (CartCondition $condition) use ($subTotalSum) {
return $condition->getMaximum() === null || $condition->getMaximum() >= $subTotalSum;
})
->sortBy(function (CartCondition $condition) { ->sortBy(function (CartCondition $condition) {
return $condition->getOrder(); return $condition->getOrder();
}); });
@@ -607,6 +582,15 @@ public function getTotal(): int|float
$conditionsForTotal = $this->getConditions() $conditionsForTotal = $this->getConditions()
->filter(function (CartCondition $condition) { ->filter(function (CartCondition $condition) {
return $condition->getTarget() === 'total'; return $condition->getTarget() === 'total';
})
->filter(function (CartCondition $condition) use ($subTotal) {
return $condition->getMinimum() === null || $condition->getMinimum() <= $subTotal;
})
->filter(function (CartCondition $condition) use ($subTotal) {
return $condition->getMaximum() === null || $condition->getMaximum() >= $subTotal;
})
->sortBy(function (CartCondition $condition) {
return $condition->getOrder();
}); });
// if no conditions were added, just return the sub total // if no conditions were added, just return the sub total
@@ -614,10 +598,14 @@ public function getTotal(): int|float
return Helpers::formatValue($subTotal, $this->config['format_numbers'], $this->config); return Helpers::formatValue($subTotal, $this->config['format_numbers'], $this->config);
} }
$conditionsForTotal->each(function (CartCondition $condition) use ($subTotal, &$total) { $index = 0;
$toBeCalculated = $total > 0 ? $total : $subTotal;
$conditionsForTotal->each(function (CartCondition $condition) use ($subTotal, &$total, &$index) {
$toBeCalculated = ($index > 0) ? $total : $subTotal;
$total = $condition->applyCondition($toBeCalculated); $total = $condition->applyCondition($toBeCalculated);
$index++;
}); });
return Helpers::formatValue($total, $this->config['format_numbers'], $this->config); return Helpers::formatValue($total, $this->config['format_numbers'], $this->config);
@@ -698,15 +686,24 @@ protected function validate($item)
{ {
$rules = [ $rules = [
'id' => 'required', 'id' => 'required',
'price' => 'required|numeric',
'quantity' => 'required|numeric|min:0.1',
'name' => 'required', 'name' => 'required',
'quantity' => 'required|numeric|min:0.1',
]; ];
$validator = CartItemValidator::make($item, $rules); $validator = CartItemValidator::make($item, $rules);
if ($validator->fails()) { if ($validator->fails()) {
throw new InvalidItemException($validator->messages()->first()); if ($validator->errors()->first('id') === 'validation.required') {
throw new InvalidItemException('The id field is required.');
}
if ($validator->errors()->first('name') === 'validation.required') {
throw new InvalidItemException('The name field is required.');
}
if ($validator->errors()->first('quantity') === 'validation.min.numeric') {
throw new InvalidItemException('The quantity must be at least 0.1.');
}
} }
return $item; return $item;
+22 -10
View File
@@ -8,15 +8,12 @@
class CartCondition class CartCondition
{ {
/**
* @var array
*/
private $args; private $args;
/** /**
* the parsed raw value of the condition * the parsed raw value of the condition
*/ */
public $parsedRawValue = 0; private $parsedRawValue = 0;
/** /**
* @param array $args (name, type, target, value) * @param array $args (name, type, target, value)
@@ -65,6 +62,22 @@ public function getType()
return $this->args['type']; return $this->args['type'];
} }
/**
* Get the minimum value of this condition
*/
public function getMinimum(): int|float|null
{
return $this->args['minimum'] ?? null;
}
/**
* Get the maximum value of this condition
*/
public function getMaximum(): int|float|null
{
return $this->args['maximum'] ?? null;
}
/** /**
* get the additional attributes of a condition * get the additional attributes of a condition
* *
@@ -145,12 +158,6 @@ public function getCalculatedValue($totalOrSubTotalOrPrice = null): int|float
*/ */
protected function apply($totalOrSubTotalOrPrice, $conditionValue) protected function apply($totalOrSubTotalOrPrice, $conditionValue)
{ {
if ($totalOrSubTotalOrPrice <= 0) {
$this->parsedRawValue = 0;
return;
}
// if value has a percentage sign on it, we will get first // if value has a percentage sign on it, we will get first
// its percentage then we will evaluate again if the value // its percentage then we will evaluate again if the value
// has a minus or plus sign so we can decide what to do with the // has a minus or plus sign so we can decide what to do with the
@@ -259,4 +266,9 @@ protected function validate($args)
throw new InvalidConditionException($validator->messages()->first()); throw new InvalidConditionException($validator->messages()->first());
} }
} }
public function toArray(): array
{
return $this->args;
}
} }
+1 -1
View File
@@ -7,7 +7,7 @@ class Helpers
/** /**
* Normalize prices * Normalize prices
*/ */
public static function normalizePrice($price): float public static function normalizePrice($price): ?float
{ {
return (is_string($price)) ? floatval($price) : $price; return (is_string($price)) ? floatval($price) : $price;
} }
+504 -163
View File
@@ -2,6 +2,7 @@
use Wearepixel\Cart\Cart; use Wearepixel\Cart\Cart;
use Wearepixel\Cart\CartCondition; use Wearepixel\Cart\CartCondition;
use Wearepixel\Cart\CartConditionCollection;
use Wearepixel\Cart\Tests\Helpers\SessionMock; use Wearepixel\Cart\Tests\Helpers\SessionMock;
beforeEach(function () { beforeEach(function () {
@@ -9,11 +10,11 @@
$events->shouldReceive('dispatch'); $events->shouldReceive('dispatch');
$this->cart = new Cart( $this->cart = new Cart(
new SessionMock, new SessionMock(),
$events, $events,
'cart', 'cart',
'SAMPLESESSIONKEY', 'SAMPLESESSIONKEY',
require (__DIR__ . '/../Helpers/ConfigConditionsMock.php') require(__DIR__ . '/../Helpers/ConfigConditionsMock.php')
); );
}); });
@@ -21,7 +22,168 @@
Mockery::close(); Mockery::close();
}); });
describe('conditions', function () {
test('can be completely cleared', function () {
$siteWideDiscount = new CartCondition([
'name' => 'Site Wide Discount',
'type' => 'discount',
'target' => 'total',
'value' => '-5%',
]);
$giftCard = new CartCondition([
'name' => 'Gift Card',
'type' => 'gift_card',
'target' => 'total',
'value' => '-25',
]);
$itemCondition = new CartCondition([
'name' => 'Item Discount',
'type' => 'discount',
'value' => '-5%',
]);
$item = [
'id' => 1,
'name' => 'Backpack',
'price' => 168.72,
'quantity' => 1,
'attributes' => [],
'conditions' => [$itemCondition],
];
$this->cart->add($item);
$this->cart->condition([$siteWideDiscount, $giftCard]);
expect($this->cart->getConditions()->count())->toEqual(2, 'Cart should have two conditions');
expect($this->cart->get(1)['conditions'])->toHaveCount(1, 'Cart should have one condition');
$this->cart->clearAllConditions();
expect($this->cart->getConditions()->count())->toEqual(0, 'Cart should have no conditions now');
expect($this->cart->get(1)['conditions'])->toHaveCount(0, 'Cart items should have no conditions now');
});
test('can be converted to array', function () {
$condition = new CartCondition([
'name' => 'Site Wide Discount',
'type' => 'discount',
'target' => 'total',
'value' => '-5%',
]);
$this->cart->condition($condition);
$conditions = $this->cart->getConditions(true);
expect($conditions)->toHaveCount(1, 'Cart should have one condition');
expect($conditions['Site Wide Discount'])->toEqual([
'name' => 'Site Wide Discount',
'type' => 'discount',
'target' => 'total',
'value' => '-5%',
'order' => 1,
]);
});
test('can be removed by name', function () {
$conditionOne = new CartCondition([
'name' => '5% Site Wide Sale',
'type' => 'sale',
'value' => '-5%',
]);
$conditionTwo = new CartCondition([
'name' => 'Mother\'s Day Gift Pack',
'type' => 'promo',
'value' => '-25',
]);
$this->cart->add([
'id' => 1,
'name' => 'Body Scrub Kit',
'price' => 100,
'quantity' => 1,
'attributes' => [],
]);
$this->cart->condition([$conditionOne, $conditionTwo]);
// let's very first the item has 2 conditions in it
expect($this->cart->getConditions())->toHaveCount(2, 'The item should have two conditions');
// now let's remove a condition on that item using the condition name
$this->cart->removeCartCondition('5% Site Wide Sale');
// now we should have only 1 condition left on that item
expect($this->cart->getConditions())->toHaveCount(1, 'Item should have one condition left');
expect($this->cart->getConditions()->first()->getName())->toEqual('Mother\'s Day Gift Pack');
});
});
describe('cart level conditions', function () { describe('cart level conditions', function () {
test('can get conditions', function () {
$this->cart->add([
'id' => 456,
'name' => 'Leather Shoes',
'price' => 129.99,
'quantity' => 1,
]);
$condition = new CartCondition([
'name' => '$5 Discount',
'type' => 'tax',
'target' => 'subtotal',
'value' => '-5',
]);
$this->cart->condition($condition);
$conditions = $this->cart->getConditions();
expect($conditions)->toHaveCount(1, 'Cart should have one condition');
expect($conditions)->toBeInstanceOf(CartConditionCollection::class);
});
test('can get conditions by name', function () {
$this->cart->add([
'id' => 456,
'name' => 'Leather Shoes',
'price' => 129.99,
'quantity' => 1,
]);
$conditionOne = new CartCondition([
'name' => '$5 Discount',
'type' => 'tax',
'target' => 'subtotal',
'value' => '-5',
]);
$conditionTwo = new CartCondition([
'name' => '5% Off',
'type' => 'tax',
'target' => 'subtotal',
'value' => '-5%',
]);
$this->cart->condition($conditionOne);
$this->cart->condition($conditionTwo);
$conditions = $this->cart->getConditions();
expect($conditions)->toHaveCount(2, 'Cart should have two conditions');
expect($conditions)->toBeInstanceOf(CartConditionCollection::class);
$condition = $this->cart->getCondition('5% Off');
expect($condition)->toBeInstanceOf(CartCondition::class);
expect($condition->getName())->toEqual('5% Off');
expect($condition->getValue())->toEqual('-5%');
});
test('can discount the subtotal by dollar amount', function () { test('can discount the subtotal by dollar amount', function () {
$this->cart->add([ $this->cart->add([
'id' => 456, 'id' => 456,
@@ -792,43 +954,307 @@
expect($giftCard->getCalculatedValue())->toEqual(0, 'Gift Card value should be 0'); expect($giftCard->getCalculatedValue())->toEqual(0, 'Gift Card value should be 0');
}); });
test('can be cleared', function () { test('calculate the subtotal correctly when one condition makes it $0, and the other adds $10', function () {
$siteWideDiscount = new CartCondition([ $this->cart->add([
'name' => 'Site Wide Discount', [
'type' => 'discount', 'id' => 456,
'target' => 'total', 'name' => 'Sample Item 1',
'value' => '-5%', 'price' => 67.99,
'quantity' => 1,
'attributes' => [],
],
[
'id' => 568,
'name' => 'Sample Item 2',
'price' => 69.25,
'quantity' => 1,
'attributes' => [],
],
]); ]);
$giftCard = new CartCondition([ expect($this->cart->getSubTotal())->toEqual(137.24, 'Cart should have sub total of 137.24');
'name' => 'Gift Card', expect($this->cart->getTotal())->toEqual(137.24, 'Cart should have total of 137.24');
'type' => 'gift_card',
// add conditions
$couponCode = new CartCondition([
'name' => 'Coupon code',
'type' => 'discount',
'target' => 'subtotal',
'order' => '1',
'value' => '-100%',
]);
$shipping = new CartCondition([
'name' => 'Shipping',
'type' => 'shipping',
'target' => 'subtotal',
'order' => '2',
'value' => '10',
]);
$this->cart->condition($couponCode);
$this->cart->condition($shipping);
expect($this->cart->getSubTotal())->toEqual(10.00, 'Cart should have sub total of 10.00');
expect($this->cart->getTotal())->toEqual(10.00, 'Cart should have a total of 10.00');
});
test('calculate the subtotal correctly when one condition makes it $0 (with dollars), and the other adds $10', function () {
$this->cart->add([
[
'id' => 456,
'name' => 'Sample Item 1',
'price' => 67.99,
'quantity' => 1,
'attributes' => [],
],
[
'id' => 568,
'name' => 'Sample Item 2',
'price' => 69.25,
'quantity' => 1,
'attributes' => [],
],
]);
expect($this->cart->getSubTotal())->toEqual(137.24, 'Cart should have sub total of 137.24');
expect($this->cart->getTotal())->toEqual(137.24, 'Cart should have total of 137.24');
// add conditions
$couponCode = new CartCondition([
'name' => 'Coupon code',
'type' => 'discount',
'target' => 'subtotal',
'order' => '1',
'value' => '-137.24',
]);
$shipping = new CartCondition([
'name' => 'Shipping',
'type' => 'shipping',
'target' => 'subtotal',
'order' => '2',
'value' => '10',
]);
$this->cart->condition($couponCode);
$this->cart->condition($shipping);
expect($this->cart->getSubTotal())->toEqual(10.00, 'Cart should have sub total of 10.00');
expect($this->cart->getTotal())->toEqual(10.00, 'Cart should have a total of 10.00');
});
test('can activate a dollar discount when a minimum amount is met', function () {
$condition = new CartCondition([
'name' => 'Get $10 off when you spend $100',
'type' => 'target',
'target' => 'total', 'target' => 'total',
'value' => '-25', 'value' => '-10',
'minimum' => '100',
]);
$this->cart->add([
'id' => 1,
'name' => 'Apple iPhone 15',
'price' => 90,
'quantity' => 1,
'attributes' => [],
]);
$this->cart->condition($condition);
expect($this->cart->getTotal())->toEqual(90, 'Cart should have total of 90');
$this->cart->clear();
$this->cart->add([
'id' => 1,
'name' => 'Apple iPhone 15',
'price' => 90,
'quantity' => 2,
'attributes' => [],
]);
expect($this->cart->getTotal())->toEqual(170, 'Cart should have total of 170');
});
test('can activate a percentage discount when a minimum amount is met', function () {
$condition = new CartCondition([
'name' => 'Get 10% off when you spend $100',
'type' => 'target',
'target' => 'total',
'value' => '-10%',
'minimum' => '100',
]);
$this->cart->add([
'id' => 1,
'name' => 'Apple iPhone 15',
'price' => 90,
'quantity' => 1,
'attributes' => [],
]);
$this->cart->condition($condition);
expect($this->cart->getTotal())->toEqual(90, 'Cart should have total of 90');
$this->cart->clear();
$this->cart->add([
'id' => 1,
'name' => 'Apple iPhone 15',
'price' => 90,
'quantity' => 2,
'attributes' => [],
]);
expect($this->cart->getTotal())->toEqual(162, 'Cart should have total of 162');
});
test('can remove a dollar value condition when a maximum is met', function () {
$condition = new CartCondition([
'name' => 'Shipping',
'type' => 'target',
'target' => 'total',
'value' => '18',
'maximum' => '160',
]);
$this->cart->add([
'id' => 1,
'name' => 'Apple iPhone 15',
'price' => 90,
'quantity' => 1,
'attributes' => [],
]);
$this->cart->condition($condition);
expect($this->cart->getTotal())->toEqual(108, 'Cart should have total of 108');
$this->cart->clear();
$this->cart->add([
'id' => 1,
'name' => 'Apple iPhone 15',
'price' => 90,
'quantity' => 2,
'attributes' => [],
]);
expect($this->cart->getTotal())->toEqual(180, 'Cart should have total of 180');
});
test('can remove a percentage condition when a maximum is met', function () {
$condition = new CartCondition([
'name' => 'Low Cart Tax',
'type' => 'target',
'target' => 'total',
'value' => '10%',
'maximum' => '140',
]);
$this->cart->add([
'id' => 1,
'name' => 'Apple iPhone 15',
'price' => 90,
'quantity' => 1,
'attributes' => [],
]);
$this->cart->condition($condition);
expect($this->cart->getTotal())->toEqual(99, 'Cart should have total of 99');
$this->cart->clear();
$this->cart->add([
'id' => 1,
'name' => 'Apple iPhone 15',
'price' => 90,
'quantity' => 2,
'attributes' => [],
]);
expect($this->cart->getTotal())->toEqual(180, 'Cart should have total of 180');
});
test('return cart conditions only when they are active', function () {
$condition = new CartCondition([
'name' => 'Get $10 off when you spend $100',
'type' => 'target',
'target' => 'total',
'value' => '-10',
'minimum' => '100',
]);
$this->cart->add([
'id' => 1,
'name' => 'Apple iPhone 15',
'price' => 90,
'quantity' => 1,
'attributes' => [],
]);
$this->cart->condition($condition);
expect($this->cart->getConditions(active: true))->toHaveCount(0, 'Cart should have 0 conditions');
$this->cart->clear();
$this->cart->add([
'id' => 1,
'name' => 'Apple iPhone 15',
'price' => 90,
'quantity' => 2,
'attributes' => [],
]);
expect($this->cart->getConditions(active: true))->toHaveCount(1, 'Cart should have 1 condition');
});
test('can be removed by condition name', function () {
$shipping = new CartCondition([
'name' => 'Shipping',
'type' => 'shipping',
'target' => 'total',
'value' => '12',
]);
$tax = new CartCondition([
'name' => 'Tax',
'type' => 'tax',
'target' => 'total',
'value' => '2.50',
]); ]);
$item = [ $item = [
'id' => 1, 'id' => 456,
'name' => 'Backpack', 'name' => 'Sample Item 1',
'price' => 168.72, 'price' => 100,
'quantity' => 1, 'quantity' => 1,
'attributes' => [], 'attributes' => [],
]; ];
$this->cart->add($item); $this->cart->add($item);
$this->cart->condition([$siteWideDiscount, $giftCard]); $this->cart->condition([$shipping, $tax]);
// let's prove first we have now two conditions in the cart
expect($this->cart->getConditions()->count())->toEqual(2, 'Cart should have two conditions'); expect($this->cart->getConditions()->count())->toEqual(2, 'Cart should have two conditions');
$this->cart->clearCartConditions(); // now let's remove a specific condition by condition name
$this->cart->removeCartCondition('Tax');
expect($this->cart->getConditions()->count())->toEqual(0, 'Cart should have no conditions now'); // cart should have now only 1 condition
expect($this->cart->getConditions()->count())->toEqual(1, 'Cart should have one condition');
expect($this->cart->getConditions()->first()->getName())->toEqual('Shipping');
}); });
}); });
describe('item level conditions', function () { describe('item level conditions', function () {
test('can add an item with a condition', function () { test('can be added to an item', function () {
$saleCondition = new CartCondition([ $saleCondition = new CartCondition([
'name' => '5% Discount', 'name' => '5% Discount',
'type' => 'sale', 'type' => 'sale',
@@ -852,6 +1278,41 @@
expect($this->cart->getTotal())->toEqual(18, 'Cart should have total of 18'); expect($this->cart->getTotal())->toEqual(18, 'Cart should have total of 18');
}); });
test('can be removed by name', function () {
$itemCondition1 = new CartCondition([
'name' => '5% Site Wide Sale',
'type' => 'sale',
'value' => '-5%',
]);
$itemCondition2 = new CartCondition([
'name' => 'Mother\'s Day Gift Pack',
'type' => 'promo',
'value' => '-25',
]);
$item = [
'id' => 1,
'name' => 'Body Scrub Kit',
'price' => 100,
'quantity' => 1,
'attributes' => [],
'conditions' => [$itemCondition1, $itemCondition2],
];
$this->cart->add($item);
// let's very first the item has 2 conditions in it
expect($this->cart->get(1)['conditions'])->toHaveCount(2, 'The item should have two conditions');
// now let's remove a condition on that item using the condition name
$this->cart->removeItemCondition(1, '5% Site Wide Sale');
// now we should have only 1 condition left on that item
expect($this->cart->get(1)['conditions'])->toHaveCount(1, 'Item should have one condition left');
expect($this->cart->get(1)['conditions'][1]->getName())->toEqual('Mother\'s Day Gift Pack');
});
test('can add item with multiple negative item conditions', function () { test('can add item with multiple negative item conditions', function () {
$saleCondition = new CartCondition([ $saleCondition = new CartCondition([
'name' => '5% Sale', 'name' => '5% Sale',
@@ -992,110 +1453,36 @@
expect($this->cart->get(1)->getPriceSumWithConditions())->toEqual(0.00, "The item's price should be prevented from going below zero."); expect($this->cart->get(1)->getPriceSumWithConditions())->toEqual(0.00, "The item's price should be prevented from going below zero.");
}); });
// test('get cart condition by condition name', function () { test('can be removed by condition name', function () {
// $itemCondition1 = new CartCondition([ $heavyItemSurcharge = new CartCondition([
// 'name' => 'SALE 5%', 'name' => 'Heavy Item Surcharge',
// 'type' => 'sale', 'type' => 'surcharge',
// 'target' => 'total', 'value' => '10',
// 'value' => '-5%', ]);
// ]);
// $itemCondition2 = new CartCondition([
// 'name' => 'Item Gift Pack 25.00',
// 'type' => 'promo',
// 'target' => 'total',
// 'value' => '-25',
// ]);
// $item = [ $tax = new CartCondition([
// 'id' => 456, 'name' => 'Tax',
// 'name' => 'Sample Item 1', 'type' => 'tax',
// 'price' => 100, 'value' => '10%',
// 'quantity' => 1, ]);
// 'attributes' => [],
// ];
// $this->cart->add($item); $item = [
'id' => 12,
'name' => 'Beer (1 box)',
'price' => 410.60,
'quantity' => 1,
'attributes' => [],
'conditions' => [$heavyItemSurcharge, $tax],
];
// $this->cart->condition([$itemCondition1, $itemCondition2]); $this->cart->add($item);
// // get a condition applied on cart by condition name expect($this->cart->get(12)['conditions'])->toHaveCount(2, 'Item should have two conditions');
// $condition = $this->cart->getCondition($itemCondition1->getName());
// expect('SALE 5%')->toEqual($condition->getName()); $this->cart->removeItemCondition(12, 'Tax');
// expect('total')->toEqual($condition->getTarget());
// expect('sale')->toEqual($condition->getType());
// expect('-5%')->toEqual($condition->getValue());
// });
// test('remove cart condition by condition name', function () { expect($this->cart->get(12)['conditions'])->toHaveCount(1, 'Item should have one condition');
// $itemCondition1 = new CartCondition([ });
// 'name' => 'SALE 5%',
// 'type' => 'sale',
// 'target' => 'total',
// 'value' => '-5%',
// ]);
// $itemCondition2 = new CartCondition([
// 'name' => 'Item Gift Pack 25.00',
// 'type' => 'promo',
// 'target' => 'total',
// 'value' => '-25',
// ]);
// $item = [
// 'id' => 456,
// 'name' => 'Sample Item 1',
// 'price' => 100,
// 'quantity' => 1,
// 'attributes' => [],
// ];
// $this->cart->add($item);
// $this->cart->condition([$itemCondition1, $itemCondition2]);
// // let's prove first we have now two conditions in the cart
// expect($this->cart->getConditions()->count())->toEqual(2, 'Cart should have two conditions');
// // now let's remove a specific condition by condition name
// $this->cart->removeCartCondition('SALE 5%');
// // cart should have now only 1 condition
// expect($this->cart->getConditions()->count())->toEqual(1, 'Cart should have one condition');
// expect($this->cart->getConditions()->first()->getName())->toEqual('Item Gift Pack 25.00');
// });
// test('remove item condition by condition name', function () {
// $itemCondition1 = new CartCondition([
// 'name' => 'SALE 5%',
// 'type' => 'sale',
// 'value' => '-5%',
// ]);
// $itemCondition2 = new CartCondition([
// 'name' => 'Item Gift Pack 25.00',
// 'type' => 'promo',
// 'value' => '-25',
// ]);
// $item = [
// 'id' => 456,
// 'name' => 'Sample Item 1',
// 'price' => 100,
// 'quantity' => 1,
// 'attributes' => [],
// 'conditions' => [$itemCondition1, $itemCondition2],
// ];
// $this->cart->add($item);
// // let's very first the item has 2 conditions in it
// expect($this->cart->get(456)['conditions'])->toHaveCount(2, 'Item should have two conditions');
// // now let's remove a condition on that item using the condition name
// $this->cart->removeItemCondition(456, 'SALE 5%');
// // now we should have only 1 condition left on that item
// expect($this->cart->get(456)['conditions'])->toHaveCount(1, 'Item should have one condition left');
// });
// test('remove item condition by condition name scenario two', function () { // test('remove item condition by condition name scenario two', function () {
// // NOTE: in this scenario, we will add the conditions not in array format // // NOTE: in this scenario, we will add the conditions not in array format
@@ -1466,50 +1853,4 @@
// expect($this->cart->getConditions()->first()->getName())->toEqual('Item Gift Pack 20'); // expect($this->cart->getConditions()->first()->getName())->toEqual('Item Gift Pack 20');
// expect($this->cart->getConditions()->last()->getName())->toEqual('TAX'); // expect($this->cart->getConditions()->last()->getName())->toEqual('TAX');
// }); // });
});
describe('conditions', function () {
test('can be completely cleared', function () {
$siteWideDiscount = new CartCondition([
'name' => 'Site Wide Discount',
'type' => 'discount',
'target' => 'total',
'value' => '-5%',
]);
$giftCard = new CartCondition([
'name' => 'Gift Card',
'type' => 'gift_card',
'target' => 'total',
'value' => '-25',
]);
$itemCondition = new CartCondition([
'name' => 'Item Discount',
'type' => 'discount',
'value' => '-5%',
]);
$item = [
'id' => 1,
'name' => 'Backpack',
'price' => 168.72,
'quantity' => 1,
'attributes' => [],
'conditions' => [$itemCondition],
];
$this->cart->add($item);
$this->cart->condition([$siteWideDiscount, $giftCard]);
expect($this->cart->getConditions()->count())->toEqual(2, 'Cart should have two conditions');
expect($this->cart->get(1)['conditions'])->toHaveCount(1, 'Cart should have one condition');
$this->cart->clearAllConditions();
expect($this->cart->getConditions()->count())->toEqual(0, 'Cart should have no conditions now');
expect($this->cart->get(1)['conditions'])->toHaveCount(0, 'Cart items should have no conditions now');
});
}); });
+31 -15
View File
@@ -49,6 +49,19 @@
expect($this->cart->getTotal())->toEqual(0, 'Total should be 0'); expect($this->cart->getTotal())->toEqual(0, 'Total should be 0');
}); });
test('can add an item an array with no price', function () {
$this->cart->add([
'id' => 455,
'name' => 'Sample Item',
'quantity' => 2,
]);
expect($this->cart->isEmpty())->toBeFalse('Cart should not be empty');
expect($this->cart->getContent()->count())->toEqual(1, 'Cart content should be 1');
expect($this->cart->getContent()->first()['id'])->toEqual(455, 'Item added has ID of 455 so first content ID should be 455');
expect($this->cart->getTotal())->toEqual(0, 'Total should be 0');
});
test('can add an item without attributes', function () { test('can add an item without attributes', function () {
$item = [ $item = [
'id' => 1, 'id' => 1,
@@ -283,6 +296,24 @@
expect($item['quantity'])->toEqual(9.9, 'Item quantity should be 9.9'); expect($item['quantity'])->toEqual(9.9, 'Item quantity should be 9.9');
}); });
test('should throw an exception when no quantity is provided', function () {
$this->expectException('Wearepixel\Cart\Exceptions\InvalidItemException');
$this->expectExceptionMessage('The quantity must be at least 0.1.');
$this->cart->add(455, 'Sample Item', 100.99, 0, []);
});
test('should throw an exception when no id is provided', function () {
$this->expectException('Wearepixel\Cart\Exceptions\InvalidItemException');
$this->expectExceptionMessage('The id field is required.');
$this->cart->add('', 'Sample Item', 100.99, 2, []);
});
test('should throw an exception when no name is provided', function () {
$this->expectException('Wearepixel\Cart\Exceptions\InvalidItemException');
$this->expectExceptionMessage('The name field is required.');
$this->cart->add(523, '', 100.99, 2, []);
});
}); });
test('cart items attributes', function () { test('cart items attributes', function () {
@@ -542,21 +573,6 @@
expect($item['quantity'])->toEqual(3, 'Item quantity of with item ID of 456 should now be reduced to 2'); expect($item['quantity'])->toEqual(3, 'Item quantity of with item ID of 456 should now be reduced to 2');
}); });
test('should throw exception when provided invalid values scenario one', function () {
$this->expectException('Wearepixel\Cart\Exceptions\InvalidItemException');
$this->cart->add(455, 'Sample Item', 100.99, 0, []);
});
test('should throw exception when provided invalid values scenario two', function () {
$this->expectException('Wearepixel\Cart\Exceptions\InvalidItemException');
$this->cart->add('', 'Sample Item', 100.99, 2, []);
});
test('should throw exception when provided invalid values scenario three', function () {
$this->expectException('Wearepixel\Cart\Exceptions\InvalidItemException');
$this->cart->add(523, '', 100.99, 2, []);
});
test('clearing cart', function () { test('clearing cart', function () {
$items = [ $items = [
[ [