From 6724e4985f9c0ea5337f314f22105f76f41d4e8a Mon Sep 17 00:00:00 2001 From: Carsten Jonstrup Date: Wed, 25 May 2022 16:50:33 +0200 Subject: [PATCH] Update to php 8 (#15) * Cleanup interface * Fix readme * Added quantity test --- .github/workflows/php.yml | 2 +- .styleci.yml | 1 + README.md | 2 +- composer.json | 13 ++++--- phpstan.neon.dist | 2 + src/Basket.php | 66 +++++++++++++++++---------------- src/IdentifierInterface.php | 6 +-- src/Item.php | 74 +++++++++++++++++++++++-------------- src/ItemInterface.php | 36 +++++++++++++----- src/Storage/Runtime.php | 12 +++--- src/Storage/Session.php | 2 +- src/StorageInterface.php | 22 +++++------ src/Tax.php | 30 +++++++-------- tests/BasketTest.php | 4 +- tests/ItemTest.php | 20 ++++++++++ 15 files changed, 177 insertions(+), 115 deletions(-) create mode 100644 .styleci.yml diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index ae35444..25daab4 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -15,7 +15,7 @@ jobs: strategy: fail-fast: false matrix: - php: ['7.4', '8.0', '8.1'] + php: ['8.0', '8.1'] dependency-version: [ prefer-stable ] name: P${{ matrix.php }} - ${{ matrix.dependency-version }} diff --git a/.styleci.yml b/.styleci.yml new file mode 100644 index 0000000..c3bb259 --- /dev/null +++ b/.styleci.yml @@ -0,0 +1 @@ +preset: laravel \ No newline at end of file diff --git a/README.md b/README.md index 7ea468a..714bbbf 100755 --- a/README.md +++ b/README.md @@ -15,8 +15,8 @@ would like your basket data to be stored elsewhere. Using [composer](https://packagist.org/packages/lenius/basket): ```bash -$ composer require lenius/basket:^3.0 $ composer require lenius/basket:^4.0 (PHP7.4) +$ composer require lenius/basket:^5.0 (PHP8.x) ``` ## Usage diff --git a/composer.json b/composer.json index f9b161f..82746a6 100755 --- a/composer.json +++ b/composer.json @@ -13,15 +13,15 @@ "minimum-stability": "dev", "prefer-stable": true, "require": { - "php": "^7.4|^8.0" + "php": "^8.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "3.4.0", + "friendsofphp/php-cs-fixer": "^3.4", "php-coveralls/php-coveralls": "2.5.2", - "phpstan/phpstan": "0.12.99", - "phpunit/phpunit": "^8.0|^9.0", + "phpstan/phpstan": "^1.7", + "phpunit/phpunit": "^9.0", "squizlabs/php_codesniffer": "3.6.2", - "vimeo/psalm": "4.15.0" + "vimeo/psalm": "^4.3" }, "config": { "sort-packages": true @@ -39,7 +39,8 @@ "scripts": { "psalm": "vendor/bin/psalm --show-info=true", "fix": "vendor/bin/php-cs-fixer fix --allow-risky=yes", - "test": "XDEBUG_MODE=coverage vendor/bin/phpunit --coverage-clover build/logs/clover.xml --coverage-html build/logs/phpunit-html/", + "test-coverage": "XDEBUG_MODE=coverage vendor/bin/phpunit --coverage-clover build/logs/clover.xml --coverage-html build/logs/phpunit-html/", + "test": "vendor/bin/phpunit", "stan": "vendor/bin/phpstan analyse" } } diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 2359c3d..b61ba7f 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -5,3 +5,5 @@ parameters: reportUnmatchedIgnoredErrors: false checkGenericClassInNonGenericObjectType: false checkMissingIterableValueType: false + excludePaths: + - './vendor' diff --git a/src/Basket.php b/src/Basket.php index 749a521..385465b 100755 --- a/src/Basket.php +++ b/src/Basket.php @@ -4,14 +4,14 @@ * This file is part of Lenius Basket, a PHP package to handle * your shopping basket. * - * Copyright (c) 2017 Lenius. + * Copyright (c) 2022 Lenius. * https://github.com/lenius/basket * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @author Carsten Jonstrup - * @copyright 2017 Lenius. + * @copyright 2022 Lenius. * * @version production * @@ -48,8 +48,8 @@ class Basket /** * Basket constructor. * - * @param StorageInterface $store The interface for storing the cart data - * @param IdentifierInterface $identifier The interface for storing the identifier + * @param StorageInterface $store + * @param IdentifierInterface $identifier */ public function __construct(StorageInterface $store, IdentifierInterface $identifier) { @@ -71,9 +71,9 @@ public function __construct(StorageInterface $store, IdentifierInterface $identi * * @param bool $asArray * - * @return array An array of Item objects + * @return array */ - public function &contents($asArray = false): array + public function &contents(bool $asArray = false): array { return $this->store->data($asArray); } @@ -82,7 +82,8 @@ public function &contents($asArray = false): array * Insert an item into the basket. * * @param ItemInterface $item - * @return string A unique item identifier + * + * @return string */ public function insert(ItemInterface $item): string { @@ -91,7 +92,7 @@ public function insert(ItemInterface $item): string $itemIdentifier = $this->createItemIdentifier($item); if ($this->has($itemIdentifier) && $this->item($itemIdentifier) instanceof ItemInterface) { - $item->quantity = $this->item($itemIdentifier)->quantity + $item->quantity; + $item->setQuantity($this->item($itemIdentifier)->getQuantity() + $item->getQuantity()); $this->update($itemIdentifier, $item); return $itemIdentifier; @@ -107,13 +108,13 @@ public function insert(ItemInterface $item): string /** * Update an item. * - * @param string $itemIdentifier The unique item identifier - * @param mixed $key The key to update, or an array of key-value pairs - * @param mixed $value The value to set $key to + * @param string $itemIdentifier + * @param mixed $key + * @param mixed $value */ public function update(string $itemIdentifier, $key, $value = null): void { - /** @var Item $item */ + /** @var ItemInterface $item */ foreach ($this->contents() as $item) { if ($item->identifier == $itemIdentifier) { $item->update($key, $value); @@ -126,7 +127,7 @@ public function update(string $itemIdentifier, $key, $value = null): void /** * Remove an item from the basket. * - * @param string $identifier Unique item identifier + * @param string $identifier */ public function remove(string $identifier): void { @@ -144,9 +145,9 @@ public function destroy(): void /** * Check if the basket has a specific item. * - * @param string $itemIdentifier The unique item identifier + * @param string $itemIdentifier * - * @return bool Yes or no? + * @return bool */ public function has(string $itemIdentifier): bool { @@ -156,23 +157,23 @@ public function has(string $itemIdentifier): bool /** * Return a specific item object by identifier. * - * @param string $itemIdentifier The unique item identifier + * @param string $itemIdentifier * - * @return Item|bool + * @return ItemInterface|bool */ - public function item(string $itemIdentifier) + public function item(string $itemIdentifier): ItemInterface|bool { return $this->store->item($itemIdentifier); } /** - * Returns the first occurance of an item with a given id. + * Returns the first occurrence of an item with a given id. * - * @param string $id The item id + * @param string $id * - * @return bool|Item + * @return bool|ItemInterface */ - public function find(string $id) + public function find(string $id): ItemInterface|bool { return $this->store->find($id); } @@ -180,7 +181,7 @@ public function find(string $id) /** * The total tax value for the basket. * - * @return float The total tax value + * @return float */ public function tax(): float { @@ -197,7 +198,7 @@ public function tax(): float /** * The total weight value for the basket. * - * @return float The total weight value + * @return float */ public function weight(): float { @@ -214,11 +215,11 @@ public function weight(): float /** * The total value of the basket. * - * @param bool $includeTax Include tax on the total? + * @param bool $includeTax * - * @return float The total basket value + * @return float */ - public function total($includeTax = true): float + public function total(bool $includeTax = true): float { $total = 0; @@ -233,17 +234,17 @@ public function total($includeTax = true): float /** * The total number of items in the basket. * - * @param bool $unique Just return unique items? + * @param bool $unique * - * @return int Total number of items + * @return int */ - public function totalItems($unique = false): int + public function totalItems(bool $unique = false): int { $total = 0; /** @var Item $item */ foreach ($this->contents() as $item) { - $total += $unique ? 1 : $item->quantity; + $total += $unique ? 1 : $item->getQuantity(); } return $total; @@ -265,7 +266,8 @@ public function setIdentifier(string $identifier): void * Create a unique item identifier. * * @param ItemInterface $item - * @return string An md5 hash of item + * + * @return string */ protected function createItemIdentifier(ItemInterface $item): string { diff --git a/src/IdentifierInterface.php b/src/IdentifierInterface.php index 980c941..59d1623 100755 --- a/src/IdentifierInterface.php +++ b/src/IdentifierInterface.php @@ -4,14 +4,14 @@ * This file is part of Lenius Basket, a PHP package to handle * your shopping basket. * - * Copyright (c) 2017 Lenius. + * Copyright (c) 2022 Lenius. * https://github.com/lenius/basket * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @author Carsten Jonstrup - * @copyright 2017 Lenius. + * @copyright 2022 Lenius. * * @version production * @@ -35,7 +35,7 @@ public function get(): string; /** * Regenerate the identifier. * - * @return string The identifier + * @return string */ public function regenerate(): string; diff --git a/src/Item.php b/src/Item.php index 1e3ea69..45489c9 100755 --- a/src/Item.php +++ b/src/Item.php @@ -4,14 +4,14 @@ * This file is part of Lenius Basket, a PHP package to handle * your shopping basket. * - * Copyright (c) 2017 Lenius. + * Copyright (c) 2022 Lenius. * https://github.com/lenius/basket * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @author Carsten Jonstrup - * @copyright 2017 Lenius. + * @copyright 2022 Lenius. * * @version production * @@ -41,6 +41,7 @@ class Item implements ItemInterface /** * Construct the item. + * * @param array $item */ public function __construct(array $item) @@ -49,7 +50,7 @@ public function __construct(array $item) $this->data[$key] = $value; } - $item['tax'] = isset($item['tax']) ? $item['tax'] : 0; + $item['tax'] = $item['tax'] ?? 0; $this->tax = new Tax($item['tax']); } @@ -79,15 +80,15 @@ public function __get(string $param) /** * Update data array using set magic method. * - * @param mixed $param The key to set - * @param mixed $value The value to set $param to + * @param mixed $param + * @param mixed $value */ - public function __set($param, $value): void + public function __set(mixed $param, mixed $value): void { $this->data[$param] = $value; if ('tax' == $param) { - $this->tax = new Tax($value); + $this->tax = new Tax(floatval($value)); } } @@ -98,10 +99,7 @@ public function __set($param, $value): void */ public function tax(): float { - $price = $this->totalPrice(); - $quantity = $this->quantity; - - return $this->tax->rate($price * $quantity); + return $this->tax->rate($this->totalPrice() * $this->getQuantity()); } /** @@ -111,7 +109,7 @@ public function tax(): float */ private function totalPrice(): float { - $price = $this->price; + $price = $this->data['price']; if ($this->hasOptions()) { foreach ($this->data['options'] as $item) { @@ -127,11 +125,11 @@ private function totalPrice(): float /** * Return the total of the item, with or without tax. * - * @param bool $includeTax Whether or not to include tax + * @param bool $includeTax * - * @return float The total, as a float + * @return float */ - public function total($includeTax = true): float + public function total(bool $includeTax = true): float { $price = $this->totalPrice(); @@ -139,17 +137,17 @@ public function total($includeTax = true): float $price = $this->tax->add($price); } - return ($price * $this->quantity); + return ($price * $this->getQuantity()); } /** * Return the total weight of the item. * - * @return float The weight, as a float + * @return float */ public function weight(): float { - $weight = $this->weight; + $weight = $this->data['weight']; if ($this->hasOptions()) { foreach ($this->data['options'] as $item) { @@ -159,17 +157,17 @@ public function weight(): float } } - return (float) ($weight * $this->quantity); + return (float) ($weight * $this->getQuantity()); } /** * Return the total of the item, with or without tax. * - * @param bool $includeTax Whether or not to include tax + * @param bool $includeTax * - * @return float The total, as a float + * @return float */ - public function single($includeTax = true): float + public function single(bool $includeTax = true): float { $price = $this->totalPrice(); @@ -183,10 +181,10 @@ public function single($includeTax = true): float /** * Update a single key for this item, or multiple. * - * @param mixed $key The array key to update, or an array of key-value pairs to update - * @param mixed $value + * @param mixed $key + * @param mixed|null $value */ - public function update($key, $value = null): void + public function update(mixed $key, mixed $value = null): void { if ($key instanceof ItemInterface) { foreach ($key->toArray() as $updateKey => $updateValue) { @@ -205,7 +203,7 @@ public function update($key, $value = null): void /** * Check if this item has options. * - * @return bool Yes or no? + * @return bool */ public function hasOptions(): bool { @@ -215,10 +213,32 @@ public function hasOptions(): bool /** * Convert the item into an array. * - * @return array The item data + * @return array */ public function toArray(): array { return $this->data; } + + /** + * Return quantity + * + * @return int + */ + public function getQuantity(): int + { + return $this->data['quantity']; + } + + /** + * Set quantity + * + * @param int $quantity + * + * @return void + */ + public function setQuantity(int $quantity): void + { + $this->data['quantity'] = $quantity; + } } diff --git a/src/ItemInterface.php b/src/ItemInterface.php index d4fe19b..29d5368 100755 --- a/src/ItemInterface.php +++ b/src/ItemInterface.php @@ -4,14 +4,14 @@ * This file is part of Lenius Basket, a PHP package to handle * your shopping basket. * - * Copyright (c) 2017 Lenius. + * Copyright (c) 2022 Lenius. * https://github.com/lenius/basket * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @author Carsten Jonstrup - * @copyright 2017 Lenius. + * @copyright 2022 Lenius. * * @version production * @@ -49,7 +49,23 @@ public function tax(): float; * * @return float */ - public function total($includeTax = true): float; + public function total(bool $includeTax = true): float; + + /** + * Return the quantity of the item. + * + * @return int + */ + public function getQuantity(): int; + + /** + * Set the quantity of the item. + * + * @param int $quantity + * + * @return void + */ + public function setQuantity(int $quantity): void; /** * Return the total weight of the item. @@ -61,19 +77,19 @@ public function weight(): float; /** * Return the total of the item, with or without tax. * - * @param bool $includeTax Whether or not to include tax + * @param bool $includeTax * - * @return float The total, as a float + * @return float */ - public function single($includeTax = true): float; + public function single(bool $includeTax = true): float; /** * Update a single key for this item, or multiple. * - * @param mixed $key The array key to update, or an array of key-value pairs to update - * @param mixed $value + * @param mixed $key + * @param mixed|null $value */ - public function update($key, $value = null): void; + public function update(mixed $key, mixed $value = null): void; /** * Check if this item has options. @@ -95,7 +111,7 @@ public function toArray(): array; * @param mixed $param * @param mixed $value */ - public function __set($param, $value): void; + public function __set(mixed $param, mixed $value): void; /** * Return the value of protected methods. diff --git a/src/Storage/Runtime.php b/src/Storage/Runtime.php index 0c9bee8..0ab5dae 100755 --- a/src/Storage/Runtime.php +++ b/src/Storage/Runtime.php @@ -55,7 +55,7 @@ public function insertUpdate(ItemInterface $item): void * * @return array */ - public function &data($asArray = false): array + public function &data(bool $asArray = false): array { $cart = &static::$cart[$this->id]; @@ -97,11 +97,11 @@ public function has(string $identifier): bool * * @param string $identifier * - * @return bool|Item + * @return ItemInterface|bool * * @internal param mixed $id The item id */ - public function item(string $identifier) + public function item(string $identifier): ItemInterface|bool { foreach (static::$cart[$this->id] as $item) { if ($item->identifier == $identifier) { @@ -117,9 +117,9 @@ public function item(string $identifier) * * @param string $id The item id * - * @return bool|Item + * @return ItemInterface|bool */ - public function find(string $id) + public function find(string $id): ItemInterface|bool { foreach (static::$cart[$this->id] as $item) { if ($item->id == $id) { @@ -180,7 +180,7 @@ public function getIdentifier(): string public function restore(): void { if (isset($_SESSION['cart'])) { - static::$cart = unserialize($_SESSION['cart']); + static::$cart = (array) unserialize($_SESSION['cart']); } } } diff --git a/src/Storage/Session.php b/src/Storage/Session.php index 3ed532b..1978990 100755 --- a/src/Storage/Session.php +++ b/src/Storage/Session.php @@ -35,7 +35,7 @@ public function restore(): void session_id() || session_start(); if (isset($_SESSION['cart'])) { - static::$cart = unserialize($_SESSION['cart']); + static::$cart = (array) unserialize($_SESSION['cart']); } } diff --git a/src/StorageInterface.php b/src/StorageInterface.php index 18b3459..637e7cb 100755 --- a/src/StorageInterface.php +++ b/src/StorageInterface.php @@ -4,14 +4,14 @@ * This file is part of Lenius Basket, a PHP package to handle * your shopping basket. * - * Copyright (c) 2017 Lenius. + * Copyright (c) 2022 Lenius. * https://github.com/lenius/basket * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @author Carsten Jonstrup - * @copyright 2017 Lenius. + * @copyright 2022 Lenius. * * @version production * @@ -28,7 +28,7 @@ interface StorageInterface /** * Add or update an item in the cart. * - * @param ItemInterface $item The item to insert or update + * @param ItemInterface $item */ public function insertUpdate(ItemInterface $item): void; @@ -39,7 +39,7 @@ public function insertUpdate(ItemInterface $item): void; * * @return array */ - public function &data($asArray = false): array; + public function &data(bool $asArray = false): array; /** * Check if the item exists in the cart. @@ -53,20 +53,20 @@ public function has(string $identifier): bool; /** * Get a single cart item by id. * - * @param string $identifier The item id + * @param string $identifier * - * @return bool|Item + * @return ItemInterface|bool */ - public function item(string $identifier); + public function item(string $identifier): ItemInterface|bool; /** - * Returns the first occurance of an item with a given id. + * Returns the first occurrence of an item with a given id. * - * @param string $id The item id + * @param string $id * - * @return bool|Item + * @return ItemInterface|bool */ - public function find(string $id); + public function find(string $id): ItemInterface|bool; /** * Remove an item from the cart. diff --git a/src/Tax.php b/src/Tax.php index 5e30494..dcd11f8 100755 --- a/src/Tax.php +++ b/src/Tax.php @@ -4,14 +4,14 @@ * This file is part of Lenius Basket, a PHP package to handle * your shopping basket. * - * Copyright (c) 2017 Lenius. + * Copyright (c) 2022 Lenius. * https://github.com/lenius/basket * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * @author Carsten Jonstrup - * @copyright 2017 Lenius. + * @copyright 2022 Lenius. * * @version production * @@ -40,15 +40,15 @@ class Tax * tax and have the library work out the tax rate * automatically. * - * @param float $value The percentage of your tax (or price before tax) - * @param null|mixed $after The value after tax + * @param float $value + * @param mixed|null $after */ - public function __construct(float $value, $after = null) + public function __construct(float $value, mixed $after = null) { $this->percentage = $value; if ($after != null && is_numeric($after)) { - $this->percentage = (float) ((($after - $value) / $value) * 100); + $this->percentage = ((($after - $value) / $value) * 100); } $this->deductModifier = (1 - ($this->percentage / 100)); @@ -58,36 +58,36 @@ public function __construct(float $value, $after = null) /** * Deduct tax from a specified price. * - * @param float $price The price you want to deduct tax from + * @param float $price * - * @return float $price - tax + * @return float */ public function deduct(float $price): float { - return ($price * $this->deductModifier); + return $price * $this->deductModifier; } /** * Add tax to a specified price. * - * @param float $price The value you want to add tax to + * @param float $price * - * @return float $price + tax + * @return float */ public function add(float $price): float { - return ($price * $this->addModifier); + return $price * $this->addModifier; } /** * Calculate the tax rate from a price. * - * @param float $price The price (after tax) + * @param float $price * - * @return float The tax rate + * @return float */ public function rate(float $price): float { - return ($price - $this->deduct($price)); + return $price - $this->deduct($price); } } diff --git a/tests/BasketTest.php b/tests/BasketTest.php index 0db8045..07f11a2 100755 --- a/tests/BasketTest.php +++ b/tests/BasketTest.php @@ -28,7 +28,7 @@ class BasketTest extends TestCase { /** @var Basket */ - private $basket; + private Basket $basket; public function setUp(): void { @@ -255,7 +255,7 @@ public function testTotalItems(): void $adding = rand(1, 200); $actualTotal = 0; - for ($i = 1; $i <= $adding; ++$i) { + for ($i = 1; $i <= $adding; $i++) { $quantity = rand(1, 20); $this->basket->insert(new Item([ diff --git a/tests/ItemTest.php b/tests/ItemTest.php index e4e7e4a..02a4258 100755 --- a/tests/ItemTest.php +++ b/tests/ItemTest.php @@ -74,6 +74,26 @@ public function testWeight(): void $this->assertEquals(($weight * $quantity), $this->item->weight()); } + public function testQuantity(): void + { + $weight = rand(200, 300); + $quantity = rand(1, 10); + + $item = [ + 'id' => 'foo', + 'name' => 'bar', + 'price' => 100, + 'quantity' => $quantity, + 'weight' => $weight, + ]; + + $this->item = new Item($item); + $this->assertEquals($quantity, $this->item->getQuantity()); + + $this->item->setQuantity(12); + $this->assertEquals(12, $this->item->getQuantity()); + } + public function testWeightWithOption(): void { $weight = rand(200, 300);