diff --git a/.phive/phars.xml b/.phive/phars.xml new file mode 100644 index 0000000..9aa6dfe --- /dev/null +++ b/.phive/phars.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/composer.json b/composer.json index a5b1b16..4783206 100644 --- a/composer.json +++ b/composer.json @@ -24,19 +24,21 @@ }, "scripts": { "check": [ - "@test", - "@cs-check" + "@cs-check", + "@test" ], - "analyse": [ - "@stan", + "cs-check": "phpcs --colors --parallel=16 -p src/ tests/", + "cs-fix": "phpcbf --colors --parallel=16 -p src/ tests/", + "phpstan": "tools/phpstan analyse", + "psalm": "tools/psalm --show-info=false", + "stan": [ + "@phpstan", "@psalm" ], - "cs-check": "phpcs -n -p --standard=vendor/cakephp/cakephp-codesniffer/CakePHP ./src ./tests", - "cs-fix": "phpcbf --standard=vendor/cakephp/cakephp-codesniffer/CakePHP ./src ./tests", - "test": "phpunit --stderr", - "stan": "phpstan analyse src/", - "psalm": "php vendor/psalm/phar/psalm.phar --show-info=false src/ ", - "stan-setup": "cp composer.json composer.backup && composer require --dev phpstan/phpstan:0.12.88 psalm/phar:~4.7.0 && mv composer.backup composer.json", - "coverage-test": "phpunit --stderr --coverage-clover=clover.xml" + "phpstan-tests": "tools/phpstan analyze -c tests/phpstan.neon", + "phpstan-baseline": "tools/phpstan --generate-baseline", + "psalm-baseline": "tools/psalm --set-baseline=psalm-baseline.xml", + "stan-setup": "phive install", + "test": "phpunit" } } diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon new file mode 100644 index 0000000..364905f --- /dev/null +++ b/phpstan-baseline.neon @@ -0,0 +1,2 @@ +parameters: + ignoreErrors: diff --git a/phpstan.neon b/phpstan.neon index 2bc6593..7dc051f 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,7 +1,10 @@ +includes: + - phpstan-baseline.neon parameters: - level: 6 - autoload_files: - - tests/bootstrap.php - ignoreErrors: - - '#Method CakeDC\\Auth\\Rbac\\Rules\\AbstractRule::_getTableFromRequest\(\) should return Cake\\ORM\\Table but returns Cake\\Datasource\\RepositoryInterface.#' -services: + level: 8 + checkMissingIterableValueType: false + checkGenericClassInNonGenericObjectType: false + bootstrapFiles: + - tests/bootstrap.php + paths: + - src/ diff --git a/psalm.xml b/psalm.xml index cc8fde3..3ee6ae7 100644 --- a/psalm.xml +++ b/psalm.xml @@ -6,6 +6,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="https://getpsalm.org/schema/config" xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd" + autoloader="tests/bootstrap.php" > @@ -42,7 +43,7 @@ - + diff --git a/src/Money.php b/src/Money.php index 4d7a075..a068dbe 100644 --- a/src/Money.php +++ b/src/Money.php @@ -87,14 +87,14 @@ public function __construct(MoneyPHP $money) } /** - * @param $name - * @param $arguments + * @param string $name + * @param array $arguments * @return false|mixed */ - public function __call($name, $arguments) + public function __call(string $name, array $arguments) { $arguments = self::processArguments($arguments); - + // @phpstan-ignore-next-line $result = call_user_func_array([$this->_money, $name], $arguments); if ($result instanceof MoneyPHP) { return new self($result); @@ -104,14 +104,15 @@ public function __call($name, $arguments) } /** - * @param $name - * @param $arguments + * @param string $name + * @param array $arguments * @return false|mixed */ - public static function __callStatic($name, $arguments) + public static function __callStatic(string $name, array $arguments) { $arguments = self::processArguments($arguments); + // @phpstan-ignore-next-line return new self(forward_static_call_array([MoneyPHP::class, $name], $arguments)); } diff --git a/src/Plugin.php b/src/Plugin.php index 929d838..2541eea 100644 --- a/src/Plugin.php +++ b/src/Plugin.php @@ -14,7 +14,7 @@ use Cake\Core\BasePlugin; use Cake\Core\PluginApplicationInterface; -use Cake\Database\Type; +use Cake\Database\TypeFactory; use Cake\Http\MiddlewareQueue; use Cake\Routing\RouteBuilder; use CakeDC\Money\Database\Type\MoneyType; @@ -35,7 +35,7 @@ class Plugin extends BasePlugin */ public function bootstrap(PluginApplicationInterface $app): void { - Type::map('money', MoneyType::class); + TypeFactory::map('money', MoneyType::class); } /** @@ -64,7 +64,7 @@ function (RouteBuilder $builder) { /** * Add middleware for the plugin. * - * @param \Cake\Http\MiddlewareQueue $middleware The middleware queue to update. + * @param \Cake\Http\MiddlewareQueue $middlewareQueue The middleware queue to update. * @return \Cake\Http\MiddlewareQueue */ public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue diff --git a/src/Utility/MoneyUtil.php b/src/Utility/MoneyUtil.php index 3813bdd..e7182d2 100644 --- a/src/Utility/MoneyUtil.php +++ b/src/Utility/MoneyUtil.php @@ -29,18 +29,18 @@ class MoneyUtil { /** - * @var MoneyFormatter + * @var \Money\MoneyFormatter[] */ protected static $_moneyFormatters = []; /** * Returns a new object of type Money * - * @param int|float|string $value + * @param \CakeDC\Money\Money|int|float|string $value * @param boolean $fromDb * @return Money */ - public static function money($value, $fromDb = false) : ?Money + public static function money($value, bool $fromDb = false) : ?Money { if (!is_numeric($value) && empty($value)) { return null; @@ -50,12 +50,12 @@ public static function money($value, $fromDb = false) : ?Money } if (!$fromDb) { - $parts = explode('.', $value ); + $parts = explode('.', (string)$value); if (!isset($parts[1])) { $parts[1] = '00'; } - $decimalLength = strlen($parts[1] ?? ''); + $decimalLength = strlen($parts[1]); if ($decimalLength == 1) { $parts[1] = $parts[1] . '0'; @@ -65,7 +65,8 @@ public static function money($value, $fromDb = false) : ?Money } $currency = Configure::read('Money.currency', 'USD'); - return Money::{$currency}(!empty($value) ? str_replace(',', '', $value) : 0); + + return Money::{$currency}(!empty($value) ? str_replace(',', '', (string)$value) : 0); } /** @@ -74,7 +75,7 @@ public static function money($value, $fromDb = false) : ?Money */ public static function float(Money $money) : float { - return $money->getAmount() / 100; + return ((float)$money->getAmount()) / 100; } /** @@ -121,6 +122,7 @@ protected static function _loadMoneyFormatter(Currency $currency) : MoneyFormatt */ public static function zero() : Money { + /** @var Money */ return self::money(0); } diff --git a/src/View/Helper/MoneyHelper.php b/src/View/Helper/MoneyHelper.php index 7dbd8e7..861dc08 100644 --- a/src/View/Helper/MoneyHelper.php +++ b/src/View/Helper/MoneyHelper.php @@ -18,9 +18,14 @@ /** * Class MoneyHelper * @package CakeDC\Money\View\Helper + * @property \Cake\View\Helper\HtmlHelper $Html + * @property \Cake\View\Helper\NumberHelper $Number */ class MoneyHelper extends Helper { + /** + * @inheritDoc + */ protected $helpers = ['Html', 'Number']; /** @@ -36,7 +41,7 @@ public function initialize(array $config): void /** * Format number or money as currency. - * @param $value + * @param \CakeDC\Money\Money|float|string $value * @return string */ public function currency($value): string diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 7003609..0913431 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -32,7 +32,7 @@ * and define the data required by your plugin here. */ require_once $root . '/vendor/cakephp/cakephp/tests/bootstrap.php'; - +class_alias(\Cake\Controller\Controller::class, 'App\Controller\AppController'); if (file_exists($root . '/config/bootstrap.php')) { require $root . '/config/bootstrap.php';