Skip to content

Commit

Permalink
Add Symfony 7 support and bump to PHP 8.1
Browse files Browse the repository at this point in the history
  • Loading branch information
mbabker committed Dec 13, 2023
1 parent 8a6caad commit eccba16
Show file tree
Hide file tree
Showing 34 changed files with 261 additions and 262 deletions.
12 changes: 5 additions & 7 deletions .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,22 @@ jobs:
strategy:
fail-fast: true
matrix:
php: ['7.4', '8.0', '8.1', '8.2']
symfony: ['5.4.*', '6.3.*']
php: ['8.1', '8.2', '8.3']
symfony: ['5.4.*', '6.3.*', '6.4.*', '7.0.*']
composer-flags: ['--prefer-stable']
can-fail: [false]
has-mongodb: [true]
extensions: ['curl, iconv, mbstring, mongodb, pdo, pdo_sqlite, sqlite, zip']
include:
- php: '7.4'
- php: '8.1'
symfony: '5.4.*'
composer-flags: '--prefer-stable --prefer-lowest'
extensions: 'curl, iconv, mbstring, mongodb, pdo, pdo_sqlite, sqlite, zip'
can-fail: false
has-mongodb: true
exclude:
- php: '7.4'
symfony: '6.3.*'
- php: '8.0'
symfony: '6.3.*'
- php: '8.1'
symfony: '7.0.*'

name: "PHP ${{ matrix.php }} - Symfony ${{ matrix.symfony }}${{ matrix.composer-flags != '' && format(' - Composer {0}', matrix.composer-flags) || '' }}"

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/static-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ jobs:
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
php-version: '8.3'
tools: composer:v2,flex
extensions: curl, iconv, mbstring, mongodb, pdo, pdo_sqlite, sqlite, zip
coverage: none

- name: Install dependencies
run: composer update --prefer-stable --prefer-dist
env:
SYMFONY_REQUIRE: '6.3.*'
SYMFONY_REQUIRE: '7.0.*'

- name: Run PHPStan
run: vendor/bin/phpstan analyze --error-format=github
5 changes: 2 additions & 3 deletions .php-cs-fixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@
->setRules([
'@Symfony' => true,
'@Symfony:risky' => true,
'@PHP74Migration' => true,
'@PHP74Migration:risky' => true,
'@PHP81Migration' => true,
'@PHP80Migration:risky' => true,
'@PHPUnit84Migration:risky' => true,
'array_syntax' => ['syntax' => 'short'],
'blank_line_after_opening_tag' => false,
'fopen_flags' => false,
'get_class_to_class_keyword' => false, // Re-enable when dropping PHP 7.4 support
'linebreak_after_opening_tag' => false,
'no_superfluous_phpdoc_tags' => ['remove_inheritdoc' => true],
'nullable_type_declaration_for_default_null_value' => ['use_nullable_type_declaration' => true],
Expand Down
47 changes: 23 additions & 24 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,42 +5,41 @@
"keywords": ["money", "moneyphp", "currency", "symfony"],
"license": "MIT",
"require": {
"php": "^7.4 || ^8.0",
"php": "^8.1",
"moneyphp/money": "^3.3 || ^4.0",
"symfony/config": "^5.4 || ^6.3",
"symfony/dependency-injection": "^5.4 || ^6.3",
"symfony/config": "^5.4 || ^6.3 || ^7.0",
"symfony/dependency-injection": "^5.4 || ^6.3 || ^7.0",
"symfony/deprecation-contracts": "^2.1 || ^3.0",
"symfony/http-kernel": "^5.4 || ^6.3",
"symfony/polyfill-php80": "^1.16"
"symfony/http-kernel": "^5.4 || ^6.3 || ^7.0"
},
"require-dev": {
"doctrine/doctrine-bundle": "^2.0",
"doctrine/mongodb-odm": "^2.1.2",
"doctrine/mongodb-odm-bundle": "^4.0.1",
"doctrine/orm": "^2.7.3",
"jms/serializer": "^3.2",
"jms/serializer-bundle": "^3.5 || ^4.0 || ^5.0",
"matthiasnoback/symfony-dependency-injection-test": "^4.3",
"doctrine/doctrine-bundle": "^2.1.1",
"doctrine/mongodb-odm": "^2.2",
"doctrine/mongodb-odm-bundle": "^4.3",
"doctrine/orm": "^2.8",
"jms/serializer": "^3.14",
"jms/serializer-bundle": "^3.8 || ^4.0 || ^5.0",
"matthiasnoback/symfony-dependency-injection-test": "^4.3.1 || ^5.0",
"phpstan/extension-installer": "^1.3",
"phpstan/phpstan": "1.10.34",
"phpstan/phpstan-phpunit": "1.3.14",
"phpstan/phpstan-symfony": "1.3.2",
"phpunit/phpunit": "9.6.12",
"symfony/form": "^5.4 || ^6.3",
"symfony/intl": "^5.4 || ^6.3",
"symfony/phpunit-bridge": "^5.4 || ^6.3",
"symfony/property-access": "^5.4 || ^6.3",
"symfony/serializer": "^5.4 || ^6.3",
"symfony/twig-bundle": "^5.4 || ^6.3",
"symfony/validator": "^5.4 || ^6.3",
"symfony/form": "^5.4 || ^6.3 || ^7.0",
"symfony/intl": "^5.4 || ^6.3 || ^7.0",
"symfony/phpunit-bridge": "^5.4 || ^6.3 || ^7.0",
"symfony/property-access": "^5.4 || ^6.3 || ^7.0",
"symfony/serializer": "^5.4 || ^6.3 || ^7.0",
"symfony/twig-bundle": "^5.4 || ^6.3 || ^7.0",
"symfony/validator": "^5.4 || ^6.3 || ^7.0",
"twig/twig": "^2.13 || ^3.0"
},
"conflict": {
"doctrine/doctrine-bundle": "<2.0",
"doctrine/mongodb-odm": "<2.1.2",
"doctrine/mongodb-odm-bundle": "<4.0.1",
"doctrine/orm": "<2.7.3",
"jms/serializer": "<3.5",
"doctrine/doctrine-bundle": "<2.1.1",
"doctrine/mongodb-odm": "<2.2",
"doctrine/mongodb-odm-bundle": "<4.3",
"doctrine/orm": "<2.8",
"jms/serializer": "<3.14",
"symfony/form": "<5.4 || >=6.0 <6.3",
"symfony/serializer": "<5.4 || >=6.0 <6.3",
"symfony/validator": "<5.4 || >=6.0 <6.3",
Expand Down
2 changes: 1 addition & 1 deletion phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ parameters:
path: tests/Form/DataTransformer/MoneyToLocalizedStringTransformerTest.php

-
message: "#^Parameter \\#2 \\$locale of function setlocale expects string\\|null, string\\|false given\\.$#"
message: "#^Parameter \\#2 \\$locale of function setlocale expects string\\|null, bool\\|string given\\.$#"
count: 1
path: tests/Form/DataTransformer/MoneyToLocalizedStringTransformerTest.php

Expand Down
2 changes: 2 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,7 @@ parameters:
paths:
- %currentWorkingDirectory%/src
- %currentWorkingDirectory%/tests
excludePaths:
- %currentWorkingDirectory%/src/Serializer/Normalizer/LegacyMoneyNormalizer.php
checkMissingIterableValueType: false
treatPhpDocTypesAsCertain: false
3 changes: 2 additions & 1 deletion phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
</listeners>

<php>
<env name="SYMFONY_DEPRECATIONS_HELPER" value="max[direct]=3"/>
<!-- Ignore deprecations from lowest stable -->
<env name="SYMFONY_DEPRECATIONS_HELPER" value="max[direct]=7&amp;max[indirect]=14"/>
</php>
</phpunit>
2 changes: 1 addition & 1 deletion src/BabDevMoneyBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public function build(ContainerBuilder $container): void

public function getContainerExtension(): ?ExtensionInterface
{
if (null === $this->extension) {
if (!isset($this->extension)) {
$this->extension = new BabDevMoneyExtension();
}

Expand Down
13 changes: 13 additions & 0 deletions src/DependencyInjection/BabDevMoneyExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@

namespace BabDev\MoneyBundle\DependencyInjection;

use BabDev\MoneyBundle\Serializer\Normalizer\LegacyMoneyNormalizer;
use Composer\InstalledVersions;
use JMS\Serializer\SerializerInterface;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpKernel\DependencyInjection\ConfigurableExtension;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
Expand Down Expand Up @@ -40,6 +43,16 @@ protected function loadInternal(array $mergedConfig, ContainerBuilder $container

if (ContainerBuilder::willBeAvailable('symfony/serializer', NormalizerInterface::class, ['babdev/money-bundle'])) {
$loader->load('serializer.php');

if (class_exists(InstalledVersions::class)) {
$version = InstalledVersions::getVersion('symfony/serializer');

if (null !== $version && version_compare($version, '6.3', '<')) {
$container->register('money.serializer.normalizer.legacy', LegacyMoneyNormalizer::class)
->setDecoratedService('money.serializer.normalizer')
->addArgument(new Reference('.inner'));
}
}
}

if (ContainerBuilder::willBeAvailable('symfony/validator', ValidatorInterface::class, ['babdev/money-bundle'])) {
Expand Down
25 changes: 10 additions & 15 deletions src/Factory/Exception/UnsupportedFormatException.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,23 @@
final class UnsupportedFormatException extends \InvalidArgumentException
{
/**
* @var string[]
* @param list<string> $formats
*
* @phpstan-var array<Format::*>
* @phpstan-param list<Format::*> $formats
*/
private array $formats;

/**
* @param string[] $formats
*
* @phpstan-param array<Format::*> $formats
*/
public function __construct(array $formats, string $message = '', int $code = 0, ?\Throwable $previous = null)
{
public function __construct(
private readonly array $formats,
string $message = '',
int $code = 0,
?\Throwable $previous = null,
) {
parent::__construct($message, $code, $previous);

$this->formats = $formats;
}

/**
* @return string[]
* @return list<string>
*
* @phpstan-return array<Format::*>
* @phpstan-return list<Format::*>
*/
public function getFormats(): array
{
Expand Down
7 changes: 1 addition & 6 deletions src/Factory/FormatterFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,7 @@ final class FormatterFactory implements FormatterFactoryInterface
Format::INTL_MONEY => IntlMoneyFormatter::class,
];

private string $defaultLocale;

public function __construct(string $defaultLocale)
{
$this->defaultLocale = $defaultLocale;
}
public function __construct(private readonly string $defaultLocale) {}

/**
* @phpstan-param Format::* $format
Expand Down
7 changes: 1 addition & 6 deletions src/Factory/ParserFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,7 @@ final class ParserFactory implements ParserFactoryInterface
Format::INTL_MONEY => IntlMoneyParser::class,
];

private string $defaultLocale;

public function __construct(string $defaultLocale)
{
$this->defaultLocale = $defaultLocale;
}
public function __construct(private readonly string $defaultLocale) {}

/**
* @phpstan-param Format::* $format
Expand Down
22 changes: 10 additions & 12 deletions src/Form/DataTransformer/MoneyToLocalizedStringTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
/**
* Transforms between a normalized format and a localized money string.
*
* Class is based on \Symfony\Component\Form\Extension\Core\DataTransformer\MoneyToLocalizedStringTransformer
* Class is based on {@see \Symfony\Component\Form\Extension\Core\DataTransformer\MoneyToLocalizedStringTransformer}
*
* @template T of Money
* @template R of string
Expand All @@ -25,19 +25,22 @@
*/
final class MoneyToLocalizedStringTransformer implements DataTransformerInterface
{
private FormatterFactoryInterface $formatterFactory;
private ParserFactoryInterface $parserFactory;
private Currency $currency;
private ?string $locale;
private NumberToLocalizedStringTransformer $numberTransformer;

/**
* @param NumberToLocalizedStringTransformer|int|null $scaleOrTransformer
*
* @throws InvalidArgumentException if an invalid constructor parameter is provided
*/
public function __construct(FormatterFactoryInterface $formatterFactory, ParserFactoryInterface $parserFactory, Currency $currency, $scaleOrTransformer = 2, ?bool $grouping = true, ?int $roundingMode = \NumberFormatter::ROUND_HALFUP, ?string $locale = null)
{
public function __construct(
private readonly FormatterFactoryInterface $formatterFactory,
private readonly ParserFactoryInterface $parserFactory,
private readonly Currency $currency,
$scaleOrTransformer = 2,
?bool $grouping = true,
?int $roundingMode = \NumberFormatter::ROUND_HALFUP,
private readonly ?string $locale = null,
) {
if ($scaleOrTransformer instanceof NumberToLocalizedStringTransformer) {
$this->numberTransformer = $scaleOrTransformer;
} elseif (\is_int($scaleOrTransformer) || null === $scaleOrTransformer) {
Expand All @@ -47,11 +50,6 @@ public function __construct(FormatterFactoryInterface $formatterFactory, ParserF
} else {
throw new InvalidArgumentException(sprintf('The fourth argument to the %s constructor must be an instance of %s, an integer, or null; %s given', self::class, NumberToLocalizedStringTransformer::class, get_debug_type($scaleOrTransformer)));
}

$this->formatterFactory = $formatterFactory;
$this->parserFactory = $parserFactory;
$this->currency = $currency;
$this->locale = $locale;
}

/**
Expand Down
18 changes: 9 additions & 9 deletions src/Form/Type/MoneyType.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use BabDev\MoneyBundle\Factory\ParserFactoryInterface;
use BabDev\MoneyBundle\Form\DataTransformer\MoneyToLocalizedStringTransformer;
use Money\Currency;
use Money\Money;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Exception\LogicException;
use Symfony\Component\Form\Extension\Core\DataTransformer\NumberToLocalizedStringTransformer;
Expand All @@ -16,15 +17,13 @@
use Symfony\Component\OptionsResolver\OptionsResolver;

/**
* Alternative money form type supporting a `Money\Money` object as a data input.
* Alternative money form type supporting a {@see Money} object as a data input.
*
* Class is based on \Symfony\Component\Form\Extension\Core\Type\MoneyType
* Class is based on {@see \Symfony\Component\Form\Extension\Core\Type\MoneyType}
*/
final class MoneyType extends AbstractType
{
private FormatterFactoryInterface $formatterFactory;
private ParserFactoryInterface $parserFactory;
private Currency $defaultCurrency;
private readonly Currency $defaultCurrency;

/**
* @var array<string, array<string, string>>
Expand All @@ -34,10 +33,11 @@ final class MoneyType extends AbstractType
/**
* @phpstan-param non-empty-string $defaultCurrency
*/
public function __construct(FormatterFactoryInterface $formatterFactory, ParserFactoryInterface $parserFactory, string $defaultCurrency)
{
$this->formatterFactory = $formatterFactory;
$this->parserFactory = $parserFactory;
public function __construct(
private readonly FormatterFactoryInterface $formatterFactory,
private readonly ParserFactoryInterface $parserFactory,
string $defaultCurrency,
) {
$this->defaultCurrency = new Currency($defaultCurrency);
}

Expand Down
43 changes: 43 additions & 0 deletions src/Serializer/Normalizer/LegacyMoneyNormalizer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php declare(strict_types=1);

namespace BabDev\MoneyBundle\Serializer\Normalizer;

use Money\Money;
use Symfony\Component\Serializer\Normalizer\CacheableSupportsMethodInterface;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;

/**
* Decorator for {@see MoneyNormalizer} implementing the legacy {@see CacheableSupportsMethodInterface} for older Symfony version support.
*
* @internal
*/
final class LegacyMoneyNormalizer implements NormalizerInterface, DenormalizerInterface, CacheableSupportsMethodInterface
{
public function __construct(private readonly MoneyNormalizer $normalizer) {}

public function normalize($object, ?string $format = null, array $context = []): array
{
return $this->normalizer->normalize($object, $format, $context);
}

public function supportsNormalization($data, ?string $format = null, array $context = []): bool
{
return $this->normalizer->supportsNormalization($data, $format, $context);
}

public function denormalize($data, string $type, ?string $format = null, array $context = []): Money
{
return $this->normalizer->denormalize($data, $type, $format, $context);
}

public function supportsDenormalization($data, string $type, ?string $format = null, array $context = []): bool
{
return $this->normalizer->supportsDenormalization($data, $type, $format, $context);
}

public function hasCacheableSupportsMethod(): bool
{
return true;
}
}
Loading

0 comments on commit eccba16

Please sign in to comment.