refactor #12148 Support for Symfony 5 (pamil)

This PR was merged into the 1.9-dev branch.

Discussion
----------

Based on #12084.

Commits
-------

3384d30d04 Allow for Symfony ^4.4 || ^5.2
6b9a46e114 Include Symfony ^5.2 in the matrix
3077b3da77 Remove usage of removed Event class
31a10b04fd [User] Requrie symfony/security-core instead of symfony/security
326d38f9e0 Fix bugs reported by Psalm
333c4e278c [CI] Restrict Symfony version correctly
db4d4f8004 [AddressingBundle] Fix compatibility with Symfony 5
e35a3a0163 [ChannelBundle] Fix compatibility with Symfony 5
2655e7f2d0 [OrderBundle] Partially fix compatibility with Symfony 5
447e865027 [CI] Mark Symfony ^5.2 builds as experimental
15696e3e04 Allow for gedmo/doctrine-extensions ^3.0
ec688e7b41 Make installable with Symfony ^5.2
8d5b9c7dd0 Require symfony/string:^5.2, it's used by StringInflector
0c2cb8e3d1 Require sylius-labs/association-hydrator:^1.1.3
14869ea0eb [Psalm] Do not fail on invalid docblock in \Doctrine\ORM\EntityRepository::__construct
bcf9be87dd [Psalm] Ignore missing Symfony\Bundle\FrameworkBundle\Templating\EngineInterface
11303b6489 Use tweaked DoctrineStorage for Payum that accepts new Doctrine Persistence API
81178e9a56 Use sylius-labs/polyfill-symfony-security to account for removed AdvancedUserInterface
8144de2da8 [Psalm] Improve configuration
f0df509e23 Remove use of deprecated method Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent::getException
a419508ef4 [Psalm] Improve configuration
25b38747be Use sylius-labs/polyfill-symfony-framework-bundle to account for removed ContainerAwareCommand
e6170fe53a [Psalm] Fix configuration for Symfony ^4.4 deprecations
a36c90e06a Remove unnecessary Twig routes in dev environment
aa1d930bfa Rename "message_bus" service to "messenger.default_bus" to comply with Symfony 5.2
11d9f9aba4 Make commands' execute() always return int
0714e77abd Fix packages builds by requiring SyliusLabs polyfill libraries
d683ad6d78 [ApiBundle] Fix event dispatcher usage
1033ef35e9 [ApiBundle] Fix ViewEvent mocking in specs
18a474801f [Core] Require symfony/mime explicitly
468d71fd42 [UiBundle] Replace templating with Twig in specs
5cfc2b6eec [ShopBundle] Fix event dispatcher usage
3187650971 [CoreBundle] Fix InteractiveLoginEvent mocks
0c28301ef8 [UserBundle] Fix InteractiveLoginEvent mocks
2d65663328 Remove unnecessary "sylius.translator.listener" service
c9ffd51994 [CoreBundle] Fix mocks of ExceptionEvent in tests
bd41054e18 [CoreBundle] Prevent from polluting the filesystem with test application cache and logs
75f070fc38 [CoreBundle] Ignore PHPUnit result cache in Git
16e99feb06 [CoreBundle] Fix payment method fixture configuration test
a74f084862 Require sylius/theme-bundle ^2.1.1 which supports Symfony 5
a32efb3af0 Do not pass int form keys, cast them to string instead
beb414255c Fix all the rest of event dispatcher calls
ca218e6886 Account for plain password being null in Symfony 5
ac2d41aa68 Fix ZoneType choice_filter
c03b3f6180 Do not use integer keys in forms - ChangePaymentMethodType
f5f9284c10 Make index.php compatible with Symfony 5
cf2b90e0b7 Fix products edit page by not rendering the same field twice
c18f11efac Fix inifite loop caused by form widget theme block rendering itself
e9e191bb4e Fix redirects using Symfony's RedirectController
9a6e0d414a [PayumBundle] Fix application crash while capturing payments
eb40b5a679 [ApiBundle] Fix the issue with too few arguments passed to has* methods
fdb07fa1ad [Behat] Fix theme-related tests
a91875c277 [CI] Remove marking Symfony 5.2 builds as experimental
9f2063695c [PayumBundle] Remove commented out code from PayumExtension
e6ae947429 Delete debugging code
This commit is contained in:
Kamil Kokot 2021-01-21 15:13:17 +01:00 committed by GitHub
commit 07ff6930a8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
112 changed files with 1520 additions and 407 deletions

View file

@ -30,8 +30,8 @@ jobs:
fail-fast: false
matrix:
php: [7.3, 7.4]
symfony: [^4.4]
symfony: [^4.4, ^5.2]
steps:
-
uses: actions/checkout@v2
@ -49,7 +49,9 @@ jobs:
-
name: Restrict Symfony version
if: matrix.symfony != ''
run: composer config extra.symfony.require "${{ matrix.symfony }}"
run: |
composer global require --no-progress --no-scripts --no-plugins "symfony/flex:^1.10"
composer config extra.symfony.require "${{ matrix.symfony }}"
-
name: Get Composer cache directory
@ -116,7 +118,7 @@ jobs:
fail-fast: false
matrix:
php: [7.3, 7.4]
symfony: [^4.4]
symfony: [^4.4, ^5.2]
mysql: [5.7]
env:
@ -151,7 +153,9 @@ jobs:
-
name: Restrict Symfony version
if: matrix.symfony != ''
run: composer config extra.symfony.require "${{ matrix.symfony }}"
run: |
composer global require --no-progress --no-scripts --no-plugins "symfony/flex:^1.10"
composer config extra.symfony.require "${{ matrix.symfony }}"
-
name: Get Composer cache directory
@ -242,10 +246,10 @@ jobs:
fail-fast: false
matrix:
php: [7.3, 7.4]
symfony: [^4.4]
symfony: [^4.4, ^5.2]
node: [10.x]
mysql: [5.7]
env:
APP_ENV: test_cached
DATABASE_URL: "mysql://root:root@127.0.0.1/sylius?serverVersion=${{ matrix.mysql }}"
@ -278,7 +282,9 @@ jobs:
-
name: Restrict Symfony version
if: matrix.symfony != ''
run: composer config extra.symfony.require "${{ matrix.symfony }}"
run: |
composer global require --no-progress --no-scripts --no-plugins "symfony/flex:^1.10"
composer config extra.symfony.require "${{ matrix.symfony }}"
-
name: Install certificates

View file

@ -49,9 +49,9 @@ jobs:
fail-fast: false
matrix:
php: [7.3, 7.4]
symfony: [4.4.*]
symfony: [^4.4, ^5.2]
package: "${{ fromJson(needs.list.outputs.packages) }}"
steps:
-
uses: actions/checkout@v2

View file

@ -28,7 +28,7 @@
"behat/transliterator": "^1.3",
"doctrine/collections": "^1.6",
"doctrine/doctrine-bundle": "^1.12 || ^2.0",
"doctrine/doctrine-migrations-bundle": "^3.0",
"doctrine/doctrine-migrations-bundle": "^3.0.1",
"doctrine/inflector": "^1.4 || ^2.0",
"doctrine/migrations": "^3.0",
"doctrine/orm": "^2.7",
@ -37,7 +37,7 @@
"friendsofphp/proxy-manager-lts": "^1.0",
"friendsofsymfony/oauth-server-bundle": "^1.6 || >2.0.0-alpha.0 ^2.0@dev",
"friendsofsymfony/rest-bundle": "^3.0",
"gedmo/doctrine-extensions": "^2.4.12",
"gedmo/doctrine-extensions": "^2.4.12 || ^3.0",
"jms/serializer-bundle": "^3.5",
"knplabs/gaufrette": "^0.8",
"knplabs/knp-gaufrette-bundle": "^0.7",
@ -53,8 +53,11 @@
"sonata-project/block-bundle": "^4.2",
"stof/doctrine-extensions-bundle": "^1.4",
"swiftmailer/swiftmailer": "^6.2",
"sylius-labs/association-hydrator": "^1.1",
"sylius-labs/association-hydrator": "^1.1.3",
"sylius-labs/doctrine-migrations-extra-bundle": "^0.1.3",
"sylius-labs/polyfill-symfony-event-dispatcher": "^1.0.1",
"sylius-labs/polyfill-symfony-framework-bundle": "^1.0",
"sylius-labs/polyfill-symfony-security": "^1.0",
"sylius/fixtures-bundle": "^1.6.1",
"sylius/grid": "^1.8",
"sylius/grid-bundle": "^1.8",
@ -63,46 +66,47 @@
"sylius/registry": "^1.5",
"sylius/resource": "^1.7",
"sylius/resource-bundle": "^1.7",
"sylius/theme-bundle": "^2.1",
"symfony/asset": "^4.4",
"symfony/config": "^4.4",
"symfony/console": "^4.4",
"symfony/dependency-injection": "^4.4",
"symfony/doctrine-bridge": "^4.4",
"symfony/event-dispatcher": "^4.4",
"symfony/expression-language": "^4.4",
"symfony/filesystem": "^4.4",
"symfony/finder": "^4.4",
"symfony/form": "^4.4",
"symfony/framework-bundle": "^4.4",
"symfony/http-foundation": "^4.4",
"symfony/http-kernel": "^4.4",
"symfony/intl": "^4.4",
"symfony/messenger": "^4.4",
"sylius/theme-bundle": "^2.1.1",
"symfony/asset": "^4.4 || ^5.2",
"symfony/config": "^4.4 || ^5.2",
"symfony/console": "^4.4 || ^5.2",
"symfony/dependency-injection": "^4.4 || ^5.2",
"symfony/doctrine-bridge": "^4.4 || ^5.2",
"symfony/event-dispatcher": "^4.4 || ^5.2",
"symfony/expression-language": "^4.4 || ^5.2",
"symfony/filesystem": "^4.4 || ^5.2",
"symfony/finder": "^4.4 || ^5.2",
"symfony/form": "^4.4 || ^5.2",
"symfony/framework-bundle": "^4.4 || ^5.2",
"symfony/http-foundation": "^4.4 || ^5.2",
"symfony/http-kernel": "^4.4 || ^5.2",
"symfony/intl": "^4.4 || ^5.2",
"symfony/messenger": "^4.4 || ^5.2",
"symfony/monolog-bundle": "^3.5",
"symfony/options-resolver": "^4.4",
"symfony/options-resolver": "^4.4 || ^5.2",
"symfony/polyfill-iconv": "^1.17",
"symfony/polyfill-intl-icu": "^1.17",
"symfony/polyfill-mbstring": "^1.17",
"symfony/polyfill-php80": "^1.17",
"symfony/process": "^4.4",
"symfony/property-access": "^4.4",
"symfony/property-info": "^4.4",
"symfony/proxy-manager-bridge": "^4.4",
"symfony/routing": "^4.4",
"symfony/security-bundle": "^4.4",
"symfony/security-core": "^4.4",
"symfony/security-csrf": "^4.4",
"symfony/security-guard": "^4.4",
"symfony/security-http": "^4.4",
"symfony/serializer": "^4.4",
"symfony/process": "^4.4 || ^5.2",
"symfony/property-access": "^4.4 || ^5.2",
"symfony/property-info": "^4.4 || ^5.2",
"symfony/proxy-manager-bridge": "^4.4 || ^5.2",
"symfony/routing": "^4.4 || ^5.2",
"symfony/security-bundle": "^4.4 || ^5.2",
"symfony/security-core": "^4.4 || ^5.2",
"symfony/security-csrf": "^4.4 || ^5.2",
"symfony/security-guard": "^4.4 || ^5.2",
"symfony/security-http": "^4.4 || ^5.2",
"symfony/serializer": "^4.4 || ^5.2",
"symfony/string": "^5.2",
"symfony/swiftmailer-bundle": "^3.4",
"symfony/templating": "^4.4",
"symfony/templating": "^4.4 || ^5.2",
"symfony/thanks": "^1.2",
"symfony/translation": "^4.4",
"symfony/twig-bundle": "^4.4",
"symfony/validator": "^4.4",
"symfony/yaml": "^4.4",
"symfony/translation": "^4.4 || ^5.2",
"symfony/twig-bundle": "^4.4 || ^5.2",
"symfony/validator": "^4.4 || ^5.2",
"symfony/yaml": "^4.4 || ^5.2",
"twig/intl-extra": "^2.12",
"twig/twig": "^2.12",
"webmozart/assert": "^1.9",
@ -187,11 +191,11 @@
"sspooky13/yaml-standards": "^5.1",
"stripe/stripe-php": "^6.43",
"sylius-labs/coding-standard": "^3.1",
"symfony/browser-kit": "^4.4",
"symfony/debug-bundle": "^4.4",
"symfony/dotenv": "^4.4",
"symfony/browser-kit": "^4.4 || ^5.2",
"symfony/debug-bundle": "^4.4 || ^5.2",
"symfony/dotenv": "^4.4 || ^5.2",
"symfony/flex": "^1.7",
"symfony/web-profiler-bundle": "^4.4",
"symfony/web-profiler-bundle": "^4.4 || ^5.2",
"symplify/package-builder": "^8.0 <8.3",
"vimeo/psalm": "4.4.1"
},

View file

@ -60,4 +60,5 @@ return [
SyliusLabs\DoctrineMigrationsExtraBundle\SyliusLabsDoctrineMigrationsExtraBundle::class => ['all' => true],
Sonata\Doctrine\Bridge\Symfony\SonataDoctrineSymfonyBundle::class => ['all' => true],
Sonata\Twig\Bridge\Symfony\SonataTwigSymfonyBundle::class => ['all' => true],
SyliusLabs\Polyfill\Symfony\Security\Bundle\SyliusLabsPolyfillSymfonySecurityBundle::class => ['all' => true],
];

View file

@ -1,3 +0,0 @@
_errors:
resource: '@TwigBundle/Resources/config/routing/errors.xml'
prefix: /_error

View file

@ -1,5 +1,5 @@
sylius_test_plugin_main:
path: /test/main
controller: FrameworkBundle:Template:template
controller: Symfony\Bundle\FrameworkBundle\Controller\TemplateController::templateAction
defaults:
template: "@SyliusTestPlugin/main.html.twig"

View file

@ -1,5 +1,5 @@
sylius_test_plugin_main:
path: /test/main
controller: FrameworkBundle:Template:template
controller: Symfony\Bundle\FrameworkBundle\Controller\TemplateController::templateAction
defaults:
template: "@SyliusTestPlugin/main.html.twig"

View file

@ -203,7 +203,7 @@ to the ``app/Resources/SyliusShopBundle/config/routing/checkout.yml`` file.
path: /
methods: [GET]
defaults:
_controller: FrameworkBundle:Redirect:redirect
_controller: Symfony\Bundle\FrameworkBundle\Controller\RedirectController:redirectAction
route: sylius_shop_checkout_address
sylius_shop_checkout_address:

View file

@ -19,5 +19,9 @@ parameters:
# Deprecated classes
- 'src/Sylius/Bundle/CoreBundle/Application/Kernel.php'
# Symfony 5.1+ hotfixes
- 'src/Sylius/Bundle/ApiBundle/DependencyInjection/Compiler/ReflectionExtractorHotfixPass.php'
- 'src/Sylius/Bundle/ApiBundle/PropertyInfo/Extractor/ReflectionExtractor.php'
ignoreErrors:
- '/Access to an undefined property Doctrine\\Common\\Collections\\ArrayCollection/'

View file

@ -11,6 +11,7 @@
<file name="src/Sylius/Bundle/CoreBundle/Application/Kernel.php" />
<file name="src/Sylius/Bundle/ApiBundle/ApiPlatform/Bridge/Doctrine/ORM/SubresourceDataProvider.php" />
<file name="src/Sylius/Bundle/ApiBundle/ApiPlatform/Bridge/Symfony/Bundle/Action/SwaggerUiAction.php" />
<file name="src/Sylius/Bundle/ApiBundle/PropertyInfo/Extractor/ReflectionExtractor.php" />
<directory name="src/Sylius/Behat" />
@ -89,33 +90,24 @@
<referencedClass name="Payum\Core\Action\GatewayAwareAction" />
<referencedClass name="Payum\Core\Security\GenericTokenFactoryInterface" />
<referencedClass name="Sylius\Component\Core\Calculator\ProductVariantPriceCalculatorInterface" />
<referencedClass name="Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand" />
<referencedClass name="Symfony\Bundle\FrameworkBundle\Controller\Controller" />
<referencedClass name="Symfony\Bundle\FrameworkBundle\Templating\EngineInterface" />
<referencedClass name="Symfony\Component\Intl\ResourceBundle\CurrencyBundleInterface" />
<referencedClass name="Symfony\Component\Intl\ResourceBundle\LanguageBundleInterface" />
<referencedClass name="Symfony\Component\Intl\ResourceBundle\LocaleBundleInterface" />
<referencedClass name="Symfony\Component\Intl\ResourceBundle\RegionBundleInterface" />
<referencedClass name="Symfony\Component\Security\Core\Role\Role" />
<referencedClass name="Symfony\Bundle\WebServerBundle\WebServerBundle" />
<referencedClass name="Symfony\Bundle\FrameworkBundle\Templating\EngineInterface" /> <!-- deprecated in Symfony 4.3 -->
<referencedClass name="Symfony\Component\Routing\RouteCollectionBuilder" /> <!-- deprecated in Symfony 5.1 -->
<referencedClass name="Symfony\Component\Security\Core\Role\Role" /> <!-- deprecated in Symfony 4.3 -->
<referencedClass name="Symfony\Component\Security\Http\Logout\DefaultLogoutSuccessHandler" /> <!-- deprecated in Symfony 5.1 -->
</errorLevel>
</DeprecatedClass>
<DeprecatedInterface>
<errorLevel type="info">
<referencedClass name="Sylius\Component\Core\Calculator\ProductVariantPriceCalculatorInterface" />
<referencedClass name="Symfony\Component\Security\Core\User\AdvancedUserInterface" />
<referencedClass name="Symfony\Component\Security\Core\User\AdvancedUserInterface" /> <!-- deprecated in Symfony 4.1 -->
<referencedClass name="Symfony\Component\Security\Http\Logout\LogoutSuccessHandlerInterface" /> <!-- deprecated in Symfony 5.1 -->
</errorLevel>
</DeprecatedInterface>
<DeprecatedMethod>
<errorLevel type="info">
<referencedMethod name="Payum\Core\Model\GatewayConfigInterface::setFactoryName" />
<referencedMethod name="Symfony\Component\EventDispatcher\Event::stopPropagation" />
<referencedMethod name="Symfony\Component\HttpKernel\Kernel::getRootDir" />
<referencedMethod name="Symfony\Component\Intl\Intl::getCurrencyBundle" />
<referencedMethod name="Symfony\Component\Intl\Intl::getLanguageBundle" />
<referencedMethod name="Symfony\Component\Intl\Intl::getLocaleBundle" />
<referencedMethod name="Symfony\Component\Intl\Intl::getRegionBundle" />
<referencedMethod name="Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent::getException" />
<referencedMethod name="Symfony\Component\EventDispatcher\Event::stopPropagation" /> <!-- deprecated in Symfony 4.3 -->
<referencedMethod name="Symfony\Component\HttpFoundation\JsonResponse::create" /> <!-- deprecated in Symfony 5.1 -->
</errorLevel>
</DeprecatedMethod>
@ -126,6 +118,18 @@
</errorLevel>
</InternalMethod>
<InvalidDocblock>
<errorLevel type="info">
<file name="vendor/doctrine/orm/lib/Doctrine/ORM/EntityRepository.php" />
</errorLevel>
</InvalidDocblock>
<UndefinedDocblockClass>
<errorLevel type="info">
<referencedClass name="Symfony\Bundle\FrameworkBundle\Templating\EngineInterface" /> <!-- for backwards compatibility with symfony/templating ^4.4 -->
</errorLevel>
</UndefinedDocblockClass>
<MissingReturnType errorLevel="info" />
<PropertyNotSetInConstructor errorLevel="info" />

View file

@ -3,7 +3,7 @@
declare(strict_types=1);
use App\Kernel;
use Symfony\Component\Debug\Debug;
use Symfony\Component\ErrorHandler\Debug;
use Symfony\Component\HttpFoundation\Request;
require dirname(__DIR__) . '/config/bootstrap.php';

View file

@ -91,25 +91,6 @@ class Kernel extends BaseKernel
return parent::getContainerBaseClass();
}
protected function getContainerLoader(ContainerInterface $container): LoaderInterface
{
/** @var ContainerBuilder $container */
Assert::isInstanceOf($container, ContainerBuilder::class);
$locator = new FileLocator($this, $this->getRootDir() . '/Resources');
$resolver = new LoaderResolver([
new XmlFileLoader($container, $locator),
new YamlFileLoader($container, $locator),
new IniFileLoader($container, $locator),
new PhpFileLoader($container, $locator),
new GlobFileLoader($container, $locator),
new DirectoryLoader($container, $locator),
new ClosureLoader($container),
]);
return new DelegatingLoader($resolver);
}
private function isTestEnvironment(): bool
{
return 0 === strpos($this->getEnvironment(), 'test');

View file

@ -1,8 +1,12 @@
vendor/
bin/
/vendor/
/bin/
composer.phar
composer.lock
/composer.phar
/composer.lock
test/app/cache
test/app/logs
/test/app/cache
/test/app/logs
/test/var/cache
/test/var/logs
/.phpunit.result.cache

View file

@ -72,8 +72,8 @@ final class ZoneType extends AbstractResourceType
];
if ($zone->getType() === ZoneInterface::TYPE_ZONE) {
$entryOptions['entry_options']['choice_filter'] = function (ZoneInterface $subZone) use ($zone): bool {
return $zone->getId() !== $subZone->getId();
$entryOptions['entry_options']['choice_filter'] = static function (?ZoneInterface $subZone) use ($zone): bool {
return $subZone !== null && $zone->getId() !== $subZone->getId();
};
}

View file

@ -110,8 +110,8 @@ final class CountryChoiceTypeTest extends TypeTestCase
$this->poland->reveal(),
]);
$this->assertChoicesLabels(['Poland'], ['choice_filter' => function (CountryInterface $country): bool {
return $country->getName() === 'Poland';
$this->assertChoicesLabels(['Poland'], ['choice_filter' => static function (?CountryInterface $country): bool {
return $country !== null && $country->getName() === 'Poland';
}]);
}
@ -120,7 +120,7 @@ final class CountryChoiceTypeTest extends TypeTestCase
$form = $this->factory->create(CountryChoiceType::class, null, $formConfiguration);
$view = $form->createView();
Assert::assertSame($expectedLabels, array_map(function (ChoiceView $choiceView): string {
Assert::assertSame($expectedLabels, array_map(static function (ChoiceView $choiceView): string {
return $choiceView->label;
}, $view->vars['choices']));
}

View file

@ -30,8 +30,8 @@
"stof/doctrine-extensions-bundle": "^1.4",
"sylius/addressing": "^1.6",
"sylius/resource-bundle": "^1.7",
"symfony/framework-bundle": "^4.4",
"symfony/intl": "^4.4"
"symfony/framework-bundle": "^4.4 || ^5.2",
"symfony/intl": "^4.4 || ^5.2"
},
"conflict": {
"twig/twig": "^1.0 || ^3.0"
@ -41,10 +41,10 @@
"phpspec/phpspec": "^7.0",
"phpunit/phpunit": "^8.5",
"polishsymfonycommunity/symfony-mocker-container": "^1.0",
"symfony/browser-kit": "^4.4",
"symfony/dependency-injection": "^4.4",
"symfony/form": "^4.4",
"symfony/validator": "^4.4"
"symfony/browser-kit": "^4.4 || ^5.2",
"symfony/dependency-injection": "^4.4 || ^5.2",
"symfony/form": "^4.4 || ^5.2",
"symfony/validator": "^4.4 || ^5.2"
},
"config": {
"bin-dir": "bin"

View file

@ -15,7 +15,7 @@ namespace Sylius\Bundle\AdminApiBundle\Command;
use FOS\OAuthServerBundle\Model\ClientManagerInterface;
use Sylius\Bundle\AdminApiBundle\Model\Client;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use SyliusLabs\Polyfill\Symfony\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

View file

@ -26,10 +26,11 @@
"php": "^7.3",
"friendsofsymfony/oauth-server-bundle": "^1.6 || >2.0.0-alpha.0 ^2.0@dev",
"sylius-labs/doctrine-migrations-extra-bundle": "^0.1.3",
"sylius-labs/polyfill-symfony-framework-bundle": "^1.0",
"sylius/core-bundle": "^1.6",
"symfony/form": "^4.4",
"symfony/framework-bundle": "^4.4",
"symfony/validator": "^4.4"
"symfony/form": "^4.4 || ^5.2",
"symfony/framework-bundle": "^4.4 || ^5.2",
"symfony/validator": "^4.4 || ^5.2"
},
"require-dev": {
"doctrine/doctrine-bundle": "^1.12 || ^2.0",
@ -38,7 +39,7 @@
"matthiasnoback/symfony-dependency-injection-test": "^4.2",
"phpspec/phpspec": "^7.0",
"phpunit/phpunit": "^8.5",
"symfony/dependency-injection": "^4.4",
"symfony/dependency-injection": "^4.4 || ^5.2",
"twig/twig": "^2.12"
},
"config": {

View file

@ -17,7 +17,7 @@ use FOS\OAuthServerBundle\Model\ClientManager;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Sylius\Bundle\AdminApiBundle\Model\Client;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use SyliusLabs\Polyfill\Symfony\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

View file

@ -47,7 +47,7 @@ final class ResourceDeleteSubscriber implements EventSubscriberInterface
public function onResourceDelete(ExceptionEvent $event): void
{
$exception = $event->getException();
$exception = $event->getThrowable();
if (!$exception instanceof ForeignKeyConstraintViolationException) {
return;
}

View file

@ -49,8 +49,8 @@ final class CustomerShowMenuBuilder
$this->addChildren($menu, $customer);
$this->eventDispatcher->dispatch(
self::EVENT_NAME,
new CustomerShowMenuBuilderEvent($this->factory, $menu, $customer)
new CustomerShowMenuBuilderEvent($this->factory, $menu, $customer),
self::EVENT_NAME
);
return $menu;

View file

@ -44,7 +44,7 @@ final class MainMenuBuilder
$this->addMarketingSubMenu($menu);
$this->addConfigurationSubMenu($menu);
$this->eventDispatcher->dispatch(self::EVENT_NAME, new MenuBuilderEvent($this->factory, $menu));
$this->eventDispatcher->dispatch(new MenuBuilderEvent($this->factory, $menu), self::EVENT_NAME);
return $menu;
}

View file

@ -88,8 +88,8 @@ final class OrderShowMenuBuilder
}
$this->eventDispatcher->dispatch(
self::EVENT_NAME,
new OrderShowMenuBuilderEvent($this->factory, $menu, $order, $stateMachine)
new OrderShowMenuBuilderEvent($this->factory, $menu, $order, $stateMachine),
self::EVENT_NAME
);
return $menu;

View file

@ -83,8 +83,8 @@ final class ProductFormMenuBuilder
}
$this->eventDispatcher->dispatch(
self::EVENT_NAME,
new ProductMenuBuilderEvent($this->factory, $menu, $options['product'])
new ProductMenuBuilderEvent($this->factory, $menu, $options['product']),
self::EVENT_NAME
);
return $menu;

View file

@ -89,8 +89,8 @@ final class ProductUpdateMenuBuilder
$menu->addChild($manageVariantsItem);
$this->eventDispatcher->dispatch(
self::EVENT_NAME,
new ProductMenuBuilderEvent($this->factory, $menu, $product)
new ProductMenuBuilderEvent($this->factory, $menu, $product),
self::EVENT_NAME
);
return $menu;

View file

@ -63,8 +63,8 @@ final class ProductVariantFormMenuBuilder
;
$this->eventDispatcher->dispatch(
self::EVENT_NAME,
new ProductVariantMenuBuilderEvent($this->factory, $menu, $options['product_variant'])
new ProductVariantMenuBuilderEvent($this->factory, $menu, $options['product_variant']),
self::EVENT_NAME
);
return $menu;

View file

@ -46,8 +46,8 @@ final class PromotionUpdateMenuBuilder
$this->addChildren($menu, $promotion);
$this->eventDispatcher->dispatch(
self::EVENT_NAME,
new PromotionMenuBuilderEvent($this->factory, $menu, $promotion)
new PromotionMenuBuilderEvent($this->factory, $menu, $promotion),
self::EVENT_NAME
);
return $menu;

View file

@ -17,7 +17,7 @@ sylius_admin_taxon_index:
path: /taxons/
methods: [GET]
defaults:
_controller: FrameworkBundle:Redirect:redirect
_controller: Symfony\Bundle\FrameworkBundle\Controller\RedirectController:redirectAction
route: sylius_admin_taxon_create
permanent: true

View file

@ -22,8 +22,8 @@
<div class="ui hidden element">
{% if product.simple %}
{{ form_row(form.variant.translations) }}
{{ form_row(form.variantSelectionMethod) }}
{% endif %}
{{ form_row(form.variantSelectionMethod) }}
</div>
</div>
</div>
@ -34,7 +34,7 @@
{% if product.simple %}
<div class="ui one column stackable grid">
<div class="column">
<h4 class="ui dividing header">{{ 'sylius.ui.pricing'|trans }}</h4>
<h4 class="ui dividing header">{{ 'sylius.ui.pricing'|trans }}</h4>
{% include "@SyliusAdmin/Product/_channel_pricing.html.twig" with { product: product, variantForm: form.variant } only %}
</div>
</div>

View file

@ -33,14 +33,14 @@
"php": "^7.3",
"sylius/core-bundle": "^1.6",
"sylius/ui-bundle": "^1.6",
"symfony/framework-bundle": "^4.4",
"symfony/framework-bundle": "^4.4 || ^5.2",
"twig/intl-extra": "^2.12",
"twig/twig": "^2.12"
},
"require-dev": {
"phpspec/phpspec": "^7.0",
"phpunit/phpunit": "^8.5",
"symfony/dependency-injection": "^4.4"
"symfony/dependency-injection": "^4.4 || ^5.2"
},
"config": {
"bin-dir": "bin"

View file

@ -40,7 +40,7 @@ final class ShipmentStateMachineTransitionApplicator implements ShipmentStateMac
{
$this->applyTransition($data, ShipmentTransitions::TRANSITION_SHIP);
$this->eventDispatcher->dispatch('sylius.shipment.post_ship', new GenericEvent($data));
$this->eventDispatcher->dispatch(new GenericEvent($data), 'sylius.shipment.post_ship');
return $data;
}

View file

@ -0,0 +1,35 @@
<?php
declare(strict_types=1);
namespace Sylius\Bundle\ApiBundle\DependencyInjection\Compiler;
use Sylius\Bundle\ApiBundle\PropertyInfo\Extractor\ReflectionExtractor;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
use Symfony\Component\PropertyInfo\PropertyReadInfoExtractorInterface;
/**
* @internal
*
* @see ReflectionExtractor
*/
final class ReflectionExtractorHotfixPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container): void
{
/** @psalm-suppress UndefinedClass */
if (!interface_exists(PropertyReadInfoExtractorInterface::class)) {
// This class was introduced in Symfony 5.1, same Symfony version that introduced the BC break.
return;
}
try {
/** @psalm-suppress MissingDependency */
$container->findDefinition('property_info.reflection_extractor')->setClass(ReflectionExtractor::class);
} catch (ServiceNotFoundException $exception) {
return;
}
}
}

View file

@ -0,0 +1,848 @@
<?php
namespace Sylius\Bundle\ApiBundle\PropertyInfo\Extractor;
use Symfony\Component\PropertyInfo\Extractor\ConstructorArgumentTypeExtractorInterface;
use Symfony\Component\PropertyInfo\PropertyAccessExtractorInterface;
use Symfony\Component\PropertyInfo\PropertyInitializableExtractorInterface;
use Symfony\Component\PropertyInfo\PropertyListExtractorInterface;
use Symfony\Component\PropertyInfo\PropertyReadInfo;
use Symfony\Component\PropertyInfo\PropertyReadInfoExtractorInterface;
use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface;
use Symfony\Component\PropertyInfo\PropertyWriteInfo;
use Symfony\Component\PropertyInfo\PropertyWriteInfoExtractorInterface;
use Symfony\Component\PropertyInfo\Type;
use Symfony\Component\String\Inflector\EnglishInflector;
use Symfony\Component\String\Inflector\InflectorInterface;
/**
* @internal
*
* @see \Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor
* @see https://github.com/symfony/symfony/pull/39896
*
* @todo Remove this class after the referenced PR is merged and released in Symfony
*/
class ReflectionExtractor implements PropertyListExtractorInterface, PropertyTypeExtractorInterface, PropertyAccessExtractorInterface, PropertyInitializableExtractorInterface, PropertyReadInfoExtractorInterface, PropertyWriteInfoExtractorInterface, ConstructorArgumentTypeExtractorInterface
{
/**
* @internal
*/
public static $defaultMutatorPrefixes = ['add', 'remove', 'set'];
/**
* @internal
*/
public static $defaultAccessorPrefixes = ['get', 'is', 'has', 'can'];
/**
* @internal
*/
public static $defaultArrayMutatorPrefixes = ['add', 'remove'];
public const ALLOW_PRIVATE = 1;
public const ALLOW_PROTECTED = 2;
public const ALLOW_PUBLIC = 4;
/** @var int Allow none of the magic methods */
public const DISALLOW_MAGIC_METHODS = 0;
/** @var int Allow magic __get methods */
public const ALLOW_MAGIC_GET = 1 << 0;
/** @var int Allow magic __set methods */
public const ALLOW_MAGIC_SET = 1 << 1;
/** @var int Allow magic __call methods */
public const ALLOW_MAGIC_CALL = 1 << 2;
private const MAP_TYPES = [
'integer' => Type::BUILTIN_TYPE_INT,
'boolean' => Type::BUILTIN_TYPE_BOOL,
'double' => Type::BUILTIN_TYPE_FLOAT,
];
private $mutatorPrefixes;
private $accessorPrefixes;
private $arrayMutatorPrefixes;
private $enableConstructorExtraction;
private $methodReflectionFlags;
private $magicMethodsFlags;
private $propertyReflectionFlags;
private $inflector;
private $arrayMutatorPrefixesFirst;
private $arrayMutatorPrefixesLast;
/**
* @param string[]|null $mutatorPrefixes
* @param string[]|null $accessorPrefixes
* @param string[]|null $arrayMutatorPrefixes
*/
public function __construct(array $mutatorPrefixes = null, array $accessorPrefixes = null, array $arrayMutatorPrefixes = null, bool $enableConstructorExtraction = true, int $accessFlags = self::ALLOW_PUBLIC, InflectorInterface $inflector = null, int $magicMethodsFlags = self::ALLOW_MAGIC_GET | self::ALLOW_MAGIC_SET)
{
$this->mutatorPrefixes = null !== $mutatorPrefixes ? $mutatorPrefixes : self::$defaultMutatorPrefixes;
$this->accessorPrefixes = null !== $accessorPrefixes ? $accessorPrefixes : self::$defaultAccessorPrefixes;
$this->arrayMutatorPrefixes = null !== $arrayMutatorPrefixes ? $arrayMutatorPrefixes : self::$defaultArrayMutatorPrefixes;
$this->enableConstructorExtraction = $enableConstructorExtraction;
$this->methodReflectionFlags = $this->getMethodsFlags($accessFlags);
$this->propertyReflectionFlags = $this->getPropertyFlags($accessFlags);
$this->magicMethodsFlags = $magicMethodsFlags;
$this->inflector = $inflector ?? new EnglishInflector();
$this->arrayMutatorPrefixesFirst = array_merge($this->arrayMutatorPrefixes, array_diff($this->mutatorPrefixes, $this->arrayMutatorPrefixes));
$this->arrayMutatorPrefixesLast = array_reverse($this->arrayMutatorPrefixesFirst);
}
/**
* {@inheritdoc}
*/
public function getProperties(string $class, array $context = []): ?array
{
try {
$reflectionClass = new \ReflectionClass($class);
} catch (\ReflectionException $e) {
return null;
}
$reflectionProperties = $reflectionClass->getProperties();
$properties = [];
foreach ($reflectionProperties as $reflectionProperty) {
if ($reflectionProperty->getModifiers() & $this->propertyReflectionFlags) {
$properties[$reflectionProperty->name] = $reflectionProperty->name;
}
}
foreach ($reflectionClass->getMethods($this->methodReflectionFlags) as $reflectionMethod) {
if ($reflectionMethod->isStatic()) {
continue;
}
$propertyName = $this->getPropertyName($reflectionMethod->name, $reflectionProperties);
if (!$propertyName || isset($properties[$propertyName])) {
continue;
}
if ($reflectionClass->hasProperty($lowerCasedPropertyName = lcfirst($propertyName)) || (!$reflectionClass->hasProperty($propertyName) && !preg_match('/^[A-Z]{2,}/', $propertyName))) {
$propertyName = $lowerCasedPropertyName;
}
$properties[$propertyName] = $propertyName;
}
return $properties ? array_values($properties) : null;
}
/**
* {@inheritdoc}
*/
public function getTypes(string $class, string $property, array $context = []): ?array
{
if ($fromMutator = $this->extractFromMutator($class, $property)) {
return $fromMutator;
}
if ($fromAccessor = $this->extractFromAccessor($class, $property)) {
return $fromAccessor;
}
if (
($context['enable_constructor_extraction'] ?? $this->enableConstructorExtraction) &&
$fromConstructor = $this->extractFromConstructor($class, $property)
) {
return $fromConstructor;
}
if ($fromDefaultValue = $this->extractFromDefaultValue($class, $property)) {
return $fromDefaultValue;
}
if (\PHP_VERSION_ID >= 70400) {
try {
$reflectionProperty = new \ReflectionProperty($class, $property);
$type = $reflectionProperty->getType();
if (null !== $type) {
return $this->extractFromReflectionType($type, $reflectionProperty->getDeclaringClass());
}
} catch (\ReflectionException $e) {
// noop
}
}
return null;
}
/**
* {@inheritdoc}
*/
public function getTypesFromConstructor(string $class, string $property): ?array
{
try {
$reflection = new \ReflectionClass($class);
} catch (\ReflectionException $e) {
return null;
}
if (!$reflectionConstructor = $reflection->getConstructor()) {
return null;
}
if (!$reflectionParameter = $this->getReflectionParameterFromConstructor($property, $reflectionConstructor)) {
return null;
}
if (!$reflectionType = $reflectionParameter->getType()) {
return null;
}
if (!$types = $this->extractFromReflectionType($reflectionType, $reflectionConstructor->getDeclaringClass())) {
return null;
}
return $types;
}
private function getReflectionParameterFromConstructor(string $property, \ReflectionMethod $reflectionConstructor): ?\ReflectionParameter
{
$reflectionParameter = null;
foreach ($reflectionConstructor->getParameters() as $reflectionParameter) {
if ($reflectionParameter->getName() === $property) {
return $reflectionParameter;
}
}
return null;
}
/**
* {@inheritdoc}
*/
public function isReadable(string $class, string $property, array $context = []): ?bool
{
if ($this->isAllowedProperty($class, $property)) {
return true;
}
return null !== $this->getReadInfo($class, $property, $context);
}
/**
* {@inheritdoc}
*/
public function isWritable(string $class, string $property, array $context = []): ?bool
{
if ($this->isAllowedProperty($class, $property)) {
return true;
}
[$reflectionMethod] = $this->getMutatorMethod($class, $property);
return null !== $reflectionMethod;
}
/**
* {@inheritdoc}
*/
public function isInitializable(string $class, string $property, array $context = []): ?bool
{
try {
$reflectionClass = new \ReflectionClass($class);
} catch (\ReflectionException $e) {
return null;
}
if (!$reflectionClass->isInstantiable()) {
return false;
}
if ($constructor = $reflectionClass->getConstructor()) {
foreach ($constructor->getParameters() as $parameter) {
if ($property === $parameter->name) {
return true;
}
}
} elseif ($parentClass = $reflectionClass->getParentClass()) {
return $this->isInitializable($parentClass->getName(), $property);
}
return false;
}
/**
* {@inheritdoc}
*/
public function getReadInfo(string $class, string $property, array $context = []): ?PropertyReadInfo
{
try {
$reflClass = new \ReflectionClass($class);
} catch (\ReflectionException $e) {
return null;
}
$allowGetterSetter = $context['enable_getter_setter_extraction'] ?? false;
$magicMethods = $context['enable_magic_methods_extraction'] ?? $this->magicMethodsFlags;
$allowMagicCall = (bool) ($magicMethods & self::ALLOW_MAGIC_CALL);
$allowMagicGet = (bool) ($magicMethods & self::ALLOW_MAGIC_GET);
if (isset($context['enable_magic_call_extraction'])) {
trigger_deprecation('symfony/property-info', '5.2', 'Using the "enable_magic_call_extraction" context option in "%s()" is deprecated. Use "enable_magic_methods_extraction" instead.', __METHOD__);
$allowMagicCall = $context['enable_magic_call_extraction'] ?? false;
}
$hasProperty = $reflClass->hasProperty($property);
$camelProp = $this->camelize($property);
$getsetter = lcfirst($camelProp); // jQuery style, e.g. read: last(), write: last($item)
foreach ($this->accessorPrefixes as $prefix) {
$methodName = $prefix.$camelProp;
if ($reflClass->hasMethod($methodName) && $reflClass->getMethod($methodName)->getModifiers() & $this->methodReflectionFlags && !$reflClass->getMethod($methodName)->getNumberOfRequiredParameters()) {
$method = $reflClass->getMethod($methodName);
return new PropertyReadInfo(PropertyReadInfo::TYPE_METHOD, $methodName, $this->getReadVisiblityForMethod($method), $method->isStatic(), false);
}
}
if ($allowGetterSetter && $reflClass->hasMethod($getsetter) && ($reflClass->getMethod($getsetter)->getModifiers() & $this->methodReflectionFlags)) {
$method = $reflClass->getMethod($getsetter);
return new PropertyReadInfo(PropertyReadInfo::TYPE_METHOD, $getsetter, $this->getReadVisiblityForMethod($method), $method->isStatic(), false);
}
if ($hasProperty && ($reflClass->getProperty($property)->getModifiers() & $this->propertyReflectionFlags)) {
$reflProperty = $reflClass->getProperty($property);
return new PropertyReadInfo(PropertyReadInfo::TYPE_PROPERTY, $property, $this->getReadVisiblityForProperty($reflProperty), $reflProperty->isStatic(), true);
}
if ($allowMagicGet && $reflClass->hasMethod('__get') && ($reflClass->getMethod('__get')->getModifiers() & $this->methodReflectionFlags)) {
return new PropertyReadInfo(PropertyReadInfo::TYPE_PROPERTY, $property, PropertyReadInfo::VISIBILITY_PUBLIC, false, false);
}
if ($allowMagicCall && $reflClass->hasMethod('__call') && ($reflClass->getMethod('__call')->getModifiers() & $this->methodReflectionFlags)) {
return new PropertyReadInfo(PropertyReadInfo::TYPE_METHOD, 'get'.$camelProp, PropertyReadInfo::VISIBILITY_PUBLIC, false, false);
}
return null;
}
/**
* {@inheritdoc}
*/
public function getWriteInfo(string $class, string $property, array $context = []): ?PropertyWriteInfo
{
try {
$reflClass = new \ReflectionClass($class);
} catch (\ReflectionException $e) {
return null;
}
$allowGetterSetter = $context['enable_getter_setter_extraction'] ?? false;
$magicMethods = $context['enable_magic_methods_extraction'] ?? $this->magicMethodsFlags;
$allowMagicCall = (bool) ($magicMethods & self::ALLOW_MAGIC_CALL);
$allowMagicSet = (bool) ($magicMethods & self::ALLOW_MAGIC_SET);
if (isset($context['enable_magic_call_extraction'])) {
trigger_deprecation('symfony/property-info', '5.2', 'Using the "enable_magic_call_extraction" context option in "%s()" is deprecated. Use "enable_magic_methods_extraction" instead.', __METHOD__);
$allowMagicCall = $context['enable_magic_call_extraction'] ?? false;
}
$allowConstruct = $context['enable_constructor_extraction'] ?? $this->enableConstructorExtraction;
$allowAdderRemover = $context['enable_adder_remover_extraction'] ?? true;
$camelized = $this->camelize($property);
$constructor = $reflClass->getConstructor();
$singulars = $this->inflector->singularize($camelized);
$errors = [];
if (null !== $constructor && $allowConstruct) {
foreach ($constructor->getParameters() as $parameter) {
if ($parameter->getName() === $property) {
return new PropertyWriteInfo(PropertyWriteInfo::TYPE_CONSTRUCTOR, $property);
}
}
}
[$adderAccessName, $removerAccessName, $adderAndRemoverErrors] = $this->findAdderAndRemover($reflClass, $singulars);
if ($allowAdderRemover && null !== $adderAccessName && null !== $removerAccessName) {
$adderMethod = $reflClass->getMethod($adderAccessName);
$removerMethod = $reflClass->getMethod($removerAccessName);
$mutator = new PropertyWriteInfo(PropertyWriteInfo::TYPE_ADDER_AND_REMOVER);
$mutator->setAdderInfo(new PropertyWriteInfo(PropertyWriteInfo::TYPE_METHOD, $adderAccessName, $this->getWriteVisiblityForMethod($adderMethod), $adderMethod->isStatic()));
$mutator->setRemoverInfo(new PropertyWriteInfo(PropertyWriteInfo::TYPE_METHOD, $removerAccessName, $this->getWriteVisiblityForMethod($removerMethod), $removerMethod->isStatic()));
return $mutator;
}
$errors = array_merge($errors, $adderAndRemoverErrors);
foreach ($this->mutatorPrefixes as $mutatorPrefix) {
$methodName = $mutatorPrefix.$camelized;
[$accessible, $methodAccessibleErrors] = $this->isMethodAccessible($reflClass, $methodName, 1);
if (!$accessible) {
$errors = array_merge($errors, $methodAccessibleErrors);
continue;
}
$method = $reflClass->getMethod($methodName);
if (!\in_array($mutatorPrefix, $this->arrayMutatorPrefixes, true)) {
return new PropertyWriteInfo(PropertyWriteInfo::TYPE_METHOD, $methodName, $this->getWriteVisiblityForMethod($method), $method->isStatic());
}
}
$getsetter = lcfirst($camelized);
if ($allowGetterSetter) {
[$accessible, $methodAccessibleErrors] = $this->isMethodAccessible($reflClass, $getsetter, 1);
if ($accessible) {
$method = $reflClass->getMethod($getsetter);
return new PropertyWriteInfo(PropertyWriteInfo::TYPE_METHOD, $getsetter, $this->getWriteVisiblityForMethod($method), $method->isStatic());
}
$errors = array_merge($errors, $methodAccessibleErrors);
}
if ($reflClass->hasProperty($property) && ($reflClass->getProperty($property)->getModifiers() & $this->propertyReflectionFlags)) {
$reflProperty = $reflClass->getProperty($property);
return new PropertyWriteInfo(PropertyWriteInfo::TYPE_PROPERTY, $property, $this->getWriteVisiblityForProperty($reflProperty), $reflProperty->isStatic());
}
if ($allowMagicSet) {
[$accessible, $methodAccessibleErrors] = $this->isMethodAccessible($reflClass, '__set', 2);
if ($accessible) {
return new PropertyWriteInfo(PropertyWriteInfo::TYPE_PROPERTY, $property, PropertyWriteInfo::VISIBILITY_PUBLIC, false);
}
$errors = array_merge($errors, $methodAccessibleErrors);
}
if ($allowMagicCall) {
[$accessible, $methodAccessibleErrors] = $this->isMethodAccessible($reflClass, '__call', 2);
if ($accessible) {
return new PropertyWriteInfo(PropertyWriteInfo::TYPE_METHOD, 'set'.$camelized, PropertyWriteInfo::VISIBILITY_PUBLIC, false);
}
$errors = array_merge($errors, $methodAccessibleErrors);
}
if (!$allowAdderRemover && null !== $adderAccessName && null !== $removerAccessName) {
$errors[] = sprintf(
'The property "%s" in class "%s" can be defined with the methods "%s()" but '.
'the new value must be an array or an instance of \Traversable',
$property,
$reflClass->getName(),
implode('()", "', [$adderAccessName, $removerAccessName])
);
}
$noneProperty = new PropertyWriteInfo();
$noneProperty->setErrors($errors);
return $noneProperty;
}
/**
* @return Type[]|null
*/
private function extractFromMutator(string $class, string $property): ?array
{
[$reflectionMethod, $prefix] = $this->getMutatorMethod($class, $property);
if (null === $reflectionMethod) {
return null;
}
$reflectionParameters = $reflectionMethod->getParameters();
$reflectionParameter = $reflectionParameters[0];
if (!$reflectionType = $reflectionParameter->getType()) {
return null;
}
$type = $this->extractFromReflectionType($reflectionType, $reflectionMethod->getDeclaringClass());
if (1 === \count($type) && \in_array($prefix, $this->arrayMutatorPrefixes)) {
$type = [new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), $type[0])];
}
return $type;
}
/**
* Tries to extract type information from accessors.
*
* @return Type[]|null
*/
private function extractFromAccessor(string $class, string $property): ?array
{
[$reflectionMethod, $prefix] = $this->getAccessorMethod($class, $property);
if (null === $reflectionMethod) {
return null;
}
if ($reflectionType = $reflectionMethod->getReturnType()) {
return $this->extractFromReflectionType($reflectionType, $reflectionMethod->getDeclaringClass());
}
if (\in_array($prefix, ['is', 'can', 'has'])) {
return [new Type(Type::BUILTIN_TYPE_BOOL)];
}
return null;
}
/**
* Tries to extract type information from constructor.
*
* @return Type[]|null
*/
private function extractFromConstructor(string $class, string $property): ?array
{
try {
$reflectionClass = new \ReflectionClass($class);
} catch (\ReflectionException $e) {
return null;
}
$constructor = $reflectionClass->getConstructor();
if (!$constructor) {
return null;
}
foreach ($constructor->getParameters() as $parameter) {
if ($property !== $parameter->name) {
continue;
}
$reflectionType = $parameter->getType();
return $reflectionType ? $this->extractFromReflectionType($reflectionType, $constructor->getDeclaringClass()) : null;
}
if ($parentClass = $reflectionClass->getParentClass()) {
return $this->extractFromConstructor($parentClass->getName(), $property);
}
return null;
}
private function extractFromDefaultValue(string $class, string $property): ?array
{
try {
$reflectionClass = new \ReflectionClass($class);
} catch (\ReflectionException $e) {
return null;
}
$defaultValue = $reflectionClass->getDefaultProperties()[$property] ?? null;
if (null === $defaultValue) {
return null;
}
$type = \gettype($defaultValue);
$type = static::MAP_TYPES[$type] ?? $type;
return [new Type($type, false, null, Type::BUILTIN_TYPE_ARRAY === $type)];
}
private function extractFromReflectionType(\ReflectionType $reflectionType, \ReflectionClass $declaringClass): array
{
$types = [];
$nullable = $reflectionType->allowsNull();
foreach ($reflectionType instanceof \ReflectionUnionType ? $reflectionType->getTypes() : [$reflectionType] as $type) {
$phpTypeOrClass = $reflectionType instanceof \ReflectionNamedType ? $reflectionType->getName() : (string) $type;
if ('null' === $phpTypeOrClass || 'mixed' === $phpTypeOrClass) {
continue;
}
if (Type::BUILTIN_TYPE_ARRAY === $phpTypeOrClass) {
$types[] = new Type(Type::BUILTIN_TYPE_ARRAY, $nullable, null, true);
} elseif ('void' === $phpTypeOrClass) {
$types[] = new Type(Type::BUILTIN_TYPE_NULL, $nullable);
} elseif ($type->isBuiltin()) {
$types[] = new Type($phpTypeOrClass, $nullable);
} else {
$types[] = new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, $this->resolveTypeName($phpTypeOrClass, $declaringClass));
}
}
return $types;
}
private function resolveTypeName(string $name, \ReflectionClass $declaringClass): string
{
if ('self' === $lcName = strtolower($name)) {
return $declaringClass->name;
}
if ('parent' === $lcName && $parent = $declaringClass->getParentClass()) {
return $parent->name;
}
return $name;
}
private function isAllowedProperty(string $class, string $property): bool
{
try {
$reflectionProperty = new \ReflectionProperty($class, $property);
return $reflectionProperty->getModifiers() & $this->propertyReflectionFlags;
} catch (\ReflectionException $e) {
// Return false if the property doesn't exist
}
return false;
}
/**
* Gets the accessor method.
*
* Returns an array with a the instance of \ReflectionMethod as first key
* and the prefix of the method as second or null if not found.
*/
private function getAccessorMethod(string $class, string $property): ?array
{
$ucProperty = ucfirst($property);
foreach ($this->accessorPrefixes as $prefix) {
try {
$reflectionMethod = new \ReflectionMethod($class, $prefix.$ucProperty);
if ($reflectionMethod->isStatic()) {
continue;
}
if (0 === $reflectionMethod->getNumberOfRequiredParameters()) {
return [$reflectionMethod, $prefix];
}
} catch (\ReflectionException $e) {
// Return null if the property doesn't exist
}
}
return null;
}
/**
* Returns an array with a the instance of \ReflectionMethod as first key
* and the prefix of the method as second or null if not found.
*/
private function getMutatorMethod(string $class, string $property): ?array
{
$ucProperty = ucfirst($property);
$ucSingulars = $this->inflector->singularize($ucProperty);
$mutatorPrefixes = \in_array($ucProperty, $ucSingulars, true) ? $this->arrayMutatorPrefixesLast : $this->arrayMutatorPrefixesFirst;
foreach ($mutatorPrefixes as $prefix) {
$names = [$ucProperty];
if (\in_array($prefix, $this->arrayMutatorPrefixes)) {
$names = array_merge($names, $ucSingulars);
}
foreach ($names as $name) {
try {
$reflectionMethod = new \ReflectionMethod($class, $prefix.$name);
if ($reflectionMethod->isStatic()) {
continue;
}
// Parameter can be optional to allow things like: method(array $foo = null)
if ($reflectionMethod->getNumberOfParameters() >= 1) {
return [$reflectionMethod, $prefix];
}
} catch (\ReflectionException $e) {
// Try the next prefix if the method doesn't exist
}
}
}
return null;
}
private function getPropertyName(string $methodName, array $reflectionProperties): ?string
{
$pattern = implode('|', array_merge($this->accessorPrefixes, $this->mutatorPrefixes));
if ('' !== $pattern && preg_match('/^('.$pattern.')(.+)$/i', $methodName, $matches)) {
if (!\in_array($matches[1], $this->arrayMutatorPrefixes)) {
return $matches[2];
}
foreach ($reflectionProperties as $reflectionProperty) {
foreach ($this->inflector->singularize($reflectionProperty->name) as $name) {
if (strtolower($name) === strtolower($matches[2])) {
return $reflectionProperty->name;
}
}
}
return $matches[2];
}
return null;
}
/**
* Searches for add and remove methods.
*
* @param \ReflectionClass $reflClass The reflection class for the given object
* @param array $singulars The singular form of the property name or null
*
* @return array An array containing the adder and remover when found and errors
*/
private function findAdderAndRemover(\ReflectionClass $reflClass, array $singulars): array
{
if (!\is_array($this->arrayMutatorPrefixes) && 2 !== \count($this->arrayMutatorPrefixes)) {
return [null, null, []];
}
[$addPrefix, $removePrefix] = $this->arrayMutatorPrefixes;
$errors = [];
foreach ($singulars as $singular) {
$addMethod = $addPrefix.$singular;
$removeMethod = $removePrefix.$singular;
[$addMethodFound, $addMethodAccessibleErrors] = $this->isMethodAccessible($reflClass, $addMethod, 1);
[$removeMethodFound, $removeMethodAccessibleErrors] = $this->isMethodAccessible($reflClass, $removeMethod, 1);
$errors = array_merge($errors, $addMethodAccessibleErrors, $removeMethodAccessibleErrors);
if ($addMethodFound && $removeMethodFound) {
return [$addMethod, $removeMethod, []];
}
if ($addMethodFound && !$removeMethodFound) {
$errors[] = sprintf('The add method "%s" in class "%s" was found, but the corresponding remove method "%s" was not found', $addMethod, $reflClass->getName(), $removeMethod);
} elseif (!$addMethodFound && $removeMethodFound) {
$errors[] = sprintf('The remove method "%s" in class "%s" was found, but the corresponding add method "%s" was not found', $removeMethod, $reflClass->getName(), $addMethod);
}
}
return [null, null, $errors];
}
/**
* Returns whether a method is public and has the number of required parameters and errors.
*/
private function isMethodAccessible(\ReflectionClass $class, string $methodName, int $parameters): array
{
$errors = [];
if ($class->hasMethod($methodName)) {
$method = $class->getMethod($methodName);
if (\ReflectionMethod::IS_PUBLIC === $this->methodReflectionFlags && !$method->isPublic()) {
$errors[] = sprintf('The method "%s" in class "%s" was found but does not have public access.', $methodName, $class->getName());
} elseif ($method->getNumberOfRequiredParameters() > $parameters || $method->getNumberOfParameters() < $parameters) {
$errors[] = sprintf('The method "%s" in class "%s" requires %d arguments, but should accept only %d.', $methodName, $class->getName(), $method->getNumberOfRequiredParameters(), $parameters);
} else {
return [true, $errors];
}
}
return [false, $errors];
}
/**
* Camelizes a given string.
*/
private function camelize(string $string): string
{
return str_replace(' ', '', ucwords(str_replace('_', ' ', $string)));
}
/**
* Return allowed reflection method flags.
*/
private function getMethodsFlags(int $accessFlags): int
{
$methodFlags = 0;
if ($accessFlags & self::ALLOW_PUBLIC) {
$methodFlags |= \ReflectionMethod::IS_PUBLIC;
}
if ($accessFlags & self::ALLOW_PRIVATE) {
$methodFlags |= \ReflectionMethod::IS_PRIVATE;
}
if ($accessFlags & self::ALLOW_PROTECTED) {
$methodFlags |= \ReflectionMethod::IS_PROTECTED;
}
return $methodFlags;
}
/**
* Return allowed reflection property flags.
*/
private function getPropertyFlags(int $accessFlags): int
{
$propertyFlags = 0;
if ($accessFlags & self::ALLOW_PUBLIC) {
$propertyFlags |= \ReflectionProperty::IS_PUBLIC;
}
if ($accessFlags & self::ALLOW_PRIVATE) {
$propertyFlags |= \ReflectionProperty::IS_PRIVATE;
}
if ($accessFlags & self::ALLOW_PROTECTED) {
$propertyFlags |= \ReflectionProperty::IS_PROTECTED;
}
return $propertyFlags;
}
private function getReadVisiblityForProperty(\ReflectionProperty $reflectionProperty): string
{
if ($reflectionProperty->isPrivate()) {
return PropertyReadInfo::VISIBILITY_PRIVATE;
}
if ($reflectionProperty->isProtected()) {
return PropertyReadInfo::VISIBILITY_PROTECTED;
}
return PropertyReadInfo::VISIBILITY_PUBLIC;
}
private function getReadVisiblityForMethod(\ReflectionMethod $reflectionMethod): string
{
if ($reflectionMethod->isPrivate()) {
return PropertyReadInfo::VISIBILITY_PRIVATE;
}
if ($reflectionMethod->isProtected()) {
return PropertyReadInfo::VISIBILITY_PROTECTED;
}
return PropertyReadInfo::VISIBILITY_PUBLIC;
}
private function getWriteVisiblityForProperty(\ReflectionProperty $reflectionProperty): string
{
if ($reflectionProperty->isPrivate()) {
return PropertyWriteInfo::VISIBILITY_PRIVATE;
}
if ($reflectionProperty->isProtected()) {
return PropertyWriteInfo::VISIBILITY_PROTECTED;
}
return PropertyWriteInfo::VISIBILITY_PUBLIC;
}
private function getWriteVisiblityForMethod(\ReflectionMethod $reflectionMethod): string
{
if ($reflectionMethod->isPrivate()) {
return PropertyWriteInfo::VISIBILITY_PRIVATE;
}
if ($reflectionMethod->isProtected()) {
return PropertyWriteInfo::VISIBILITY_PROTECTED;
}
return PropertyWriteInfo::VISIBILITY_PUBLIC;
}
}

View file

@ -17,7 +17,7 @@
>
<services>
<service id="Sylius\Bundle\ApiBundle\EventHandler\OrderCompletedHandler">
<argument type="service" id="message_bus" />
<argument type="service" id="messenger.default_bus" />
<argument type="service" id="sylius.repository.order" />
<tag name="messenger.message_handler" bus="sylius_event.bus"/>
</service>

View file

@ -14,14 +14,16 @@ declare(strict_types=1);
namespace Sylius\Bundle\ApiBundle;
use Sylius\Bundle\ApiBundle\DependencyInjection\Compiler\CommandDataTransformerPass;
use Sylius\Bundle\ApiBundle\DependencyInjection\Compiler\ReflectionExtractorHotfixPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;
/** @experimental */
final class SyliusApiBundle extends Bundle
{
public function build(ContainerBuilder $builder)
public function build(ContainerBuilder $builder): void
{
$builder->addCompilerPass(new CommandDataTransformerPass());
$builder->addCompilerPass(new ReflectionExtractorHotfixPass());
}
}

View file

@ -26,7 +26,7 @@
"php": "^7.3",
"api-platform/core": "^2.5",
"sylius/core-bundle": "^1.7",
"symfony/messenger": "^4.4"
"symfony/messenger": "^4.4 || ^5.2"
},
"require-dev": {
"matthiasnoback/symfony-config-test": "^4.2",

View file

@ -37,7 +37,7 @@ final class ShipmentStateMachineTransitionApplicatorSpec extends ObjectBehavior
$stateMachineFactory->get($shipment, ShipmentTransitions::GRAPH)->willReturn($stateMachine);
$stateMachine->apply(ShipmentTransitions::TRANSITION_SHIP)->shouldBeCalled();
$eventDispatcher->dispatch('sylius.shipment.post_ship', new GenericEvent($shipment->getWrappedObject()))->shouldBeCalled();
$eventDispatcher->dispatch(new GenericEvent($shipment->getWrappedObject()), 'sylius.shipment.post_ship')->shouldBeCalled();
$this->ship($shipment);
}

View file

@ -21,6 +21,7 @@ use Sylius\Component\Core\Model\ProductTranslationInterface;
use Sylius\Component\Product\Generator\SlugGeneratorInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\ViewEvent;
use Symfony\Component\HttpKernel\HttpKernelInterface;
final class ProductSlugEventSubscriberSpec extends ObjectBehavior
{
@ -33,11 +34,9 @@ final class ProductSlugEventSubscriberSpec extends ObjectBehavior
SlugGeneratorInterface $slugGenerator,
ProductInterface $product,
ProductTranslationInterface $productTranslation,
Request $request,
ViewEvent $event
HttpKernelInterface $kernel,
Request $request
): void {
$event->getControllerResult()->willReturn($product);
$event->getRequest()->willReturn($request);
$request->getMethod()->willReturn(Request::METHOD_POST);
$product->getTranslations()->willReturn(new ArrayCollection([$productTranslation->getWrappedObject()]));
@ -47,20 +46,22 @@ final class ProductSlugEventSubscriberSpec extends ObjectBehavior
$slugGenerator->generate('Audi RS7')->willReturn('audi-rs7');
$productTranslation->setSlug('audi-rs7')->shouldBeCalled();
$event->setControllerResult($product)->shouldBeCalled();
$this->generateSlug($event);
$this->generateSlug(new ViewEvent(
$kernel->getWrappedObject(),
$request->getWrappedObject(),
HttpKernelInterface::MASTER_REQUEST,
$product->getWrappedObject()
));
}
function it_does_nothing_if_the_product_has_slug(
SlugGeneratorInterface $slugGenerator,
ProductInterface $product,
ProductTranslationInterface $productTranslation,
Request $request,
ViewEvent $event
HttpKernelInterface $kernel,
Request $request
): void {
$event->getControllerResult()->willReturn($product);
$event->getRequest()->willReturn($request);
$request->getMethod()->willReturn(Request::METHOD_POST);
$product->getTranslations()->willReturn(new ArrayCollection([$productTranslation->getWrappedObject()]));
@ -70,20 +71,21 @@ final class ProductSlugEventSubscriberSpec extends ObjectBehavior
$slugGenerator->generate(Argument::any())->shouldNotBeCalled();
$productTranslation->setSlug(Argument::any())->shouldNotBeCalled();
$event->setControllerResult($product)->shouldBeCalled();
$this->generateSlug($event);
$this->generateSlug(new ViewEvent(
$kernel->getWrappedObject(),
$request->getWrappedObject(),
HttpKernelInterface::MASTER_REQUEST,
$product->getWrappedObject()
));
}
function it_does_nothing_if_the_product_has_no_name(
SlugGeneratorInterface $slugGenerator,
ProductInterface $product,
ProductTranslationInterface $productTranslation,
Request $request,
ViewEvent $event
HttpKernelInterface $kernel,
Request $request
): void {
$event->getControllerResult()->willReturn($product);
$event->getRequest()->willReturn($request);
$request->getMethod()->willReturn(Request::METHOD_POST);
$product->getTranslations()->willReturn(new ArrayCollection([$productTranslation->getWrappedObject()]));
@ -93,8 +95,11 @@ final class ProductSlugEventSubscriberSpec extends ObjectBehavior
$slugGenerator->generate(Argument::any())->shouldNotBeCalled();
$productTranslation->setSlug(Argument::any())->shouldNotBeCalled();
$event->setControllerResult($product)->shouldBeCalled();
$this->generateSlug($event);
$this->generateSlug(new ViewEvent(
$kernel->getWrappedObject(),
$request->getWrappedObject(),
HttpKernelInterface::MASTER_REQUEST,
$product->getWrappedObject()
));
}
}

View file

@ -53,6 +53,7 @@ class SelectAttributeChoicesCollectionType extends AbstractType
continue;
}
$key = (string) $key;
$newKey = $this->getUniqueKey();
$fixedData[$newKey] = $this->resolveValues($values);

View file

@ -31,15 +31,15 @@
"stof/doctrine-extensions-bundle": "^1.4",
"sylius/attribute": "^1.6",
"sylius/resource-bundle": "^1.7",
"symfony/framework-bundle": "^4.4"
"symfony/framework-bundle": "^4.4 || ^5.2"
},
"require-dev": {
"doctrine/orm": "^2.7",
"phpspec/phpspec": "^7.0",
"phpunit/phpunit": "^8.5",
"symfony/browser-kit": "^4.4",
"symfony/dependency-injection": "^4.4",
"symfony/form": "^4.4"
"symfony/browser-kit": "^4.4 || ^5.2",
"symfony/dependency-injection": "^4.4 || ^5.2",
"symfony/form": "^4.4 || ^5.2"
},
"config": {
"bin-dir": "bin"

View file

@ -4,8 +4,11 @@
/composer.phar
/composer.lock
test/app/cache
test/app/logs
/test/app/cache
/test/app/logs
/test/var/cache
/test/var/logs
/phpspec.yml
/phpunit.xml
/.phpunit.result.cache

View file

@ -28,7 +28,7 @@
"php": "^7.3",
"sylius/channel": "^1.6",
"sylius/resource-bundle": "^1.7",
"symfony/framework-bundle": "^4.4"
"symfony/framework-bundle": "^4.4 || ^5.2"
},
"require-dev": {
"doctrine/orm": "^2.7",
@ -36,9 +36,9 @@
"phpspec/phpspec": "^7.0",
"phpunit/phpunit": "^8.5",
"polishsymfonycommunity/symfony-mocker-container": "^1.0",
"symfony/browser-kit": "^4.4",
"symfony/dependency-injection": "^4.4",
"symfony/form": "^4.4",
"symfony/browser-kit": "^4.4 || ^5.2",
"symfony/dependency-injection": "^4.4 || ^5.2",
"symfony/form": "^4.4 || ^5.2",
"twig/twig": "^2.12"
},
"config": {

View file

@ -30,53 +30,54 @@ final class FakeChannelPersisterSpec extends ObjectBehavior
$this->beConstructedWith($fakeHostnameProvider);
}
function it_applies_only_to_master_requests(ResponseEvent $responseEvent): void
function it_applies_only_to_master_requests(HttpKernelInterface $kernel, Request $request, Response $response): void
{
$responseEvent->getRequestType()->willReturn(HttpKernelInterface::SUB_REQUEST);
$responseEvent->getRequest()->shouldNotBeCalled();
$responseEvent->getResponse()->shouldNotBeCalled();
$this->onKernelResponse($responseEvent);
$this->onKernelResponse(new ResponseEvent(
$kernel->getWrappedObject(),
$request->getWrappedObject(),
HttpKernelInterface::SUB_REQUEST,
$response->getWrappedObject()
));
}
function it_applies_only_for_request_with_fake_channel_code(
FakeChannelCodeProviderInterface $fakeHostnameProvider,
ResponseEvent $responseEvent,
Request $request
HttpKernelInterface $kernel,
Request $request,
Response $response
): void {
$responseEvent->getRequestType()->willReturn(HttpKernelInterface::MASTER_REQUEST);
$responseEvent->getRequest()->willReturn($request);
$fakeHostnameProvider->getCode($request)->willReturn(null);
$responseEvent->getResponse()->shouldNotBeCalled();
$this->onKernelResponse($responseEvent);
$this->onKernelResponse(new ResponseEvent(
$kernel->getWrappedObject(),
$request->getWrappedObject(),
HttpKernelInterface::MASTER_REQUEST,
$response->getWrappedObject()
));
}
function it_persists_fake_channel_codes_in_a_cookie(
FakeChannelCodeProviderInterface $fakeHostnameProvider,
ResponseEvent $responseEvent,
HttpKernelInterface $kernel,
Request $request,
Response $response,
ResponseHeaderBag $responseHeaderBag
): void {
$responseEvent->getRequestType()->willReturn(HttpKernelInterface::MASTER_REQUEST);
$responseEvent->getRequest()->willReturn($request);
$fakeHostnameProvider->getCode($request)->willReturn('fake_channel_code');
$responseEvent->getResponse()->willReturn($response);
$response->headers = $responseHeaderBag;
$responseHeaderBag
->setCookie(Argument::that(function (Cookie $cookie) {
->setCookie(Argument::that(static function (Cookie $cookie): bool {
return $cookie->getName() === '_channel_code' && $cookie->getValue() === 'fake_channel_code';
}))
->shouldBeCalled()
;
$this->onKernelResponse($responseEvent);
$this->onKernelResponse(new ResponseEvent(
$kernel->getWrappedObject(),
$request->getWrappedObject(),
HttpKernelInterface::MASTER_REQUEST,
$response->getWrappedObject()
));
}
}

View file

@ -6,3 +6,4 @@
/phpunit.xml
/phpspec.yml
/.phpunit.result.cache

View file

@ -15,7 +15,7 @@ namespace Sylius\Bundle\CoreBundle\Command;
use Doctrine\ORM\EntityManagerInterface;
use Sylius\Bundle\CoreBundle\Installer\Executor\CommandExecutor;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use SyliusLabs\Polyfill\Symfony\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Input\InputInterface;

View file

@ -13,7 +13,7 @@ declare(strict_types=1);
namespace Sylius\Bundle\CoreBundle\Command;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use SyliusLabs\Polyfill\Symfony\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
@ -32,7 +32,7 @@ class CancelUnpaidOrdersCommand extends ContainerAwareCommand
);
}
protected function execute(InputInterface $input, OutputInterface $output)
protected function execute(InputInterface $input, OutputInterface $output): int
{
$expirationTime = $this->getContainer()->getParameter('sylius_order.order_expiration_period');

View file

@ -31,7 +31,7 @@ EOT
;
}
protected function execute(InputInterface $input, OutputInterface $output): ?int
protected function execute(InputInterface $input, OutputInterface $output): int
{
$output->writeln(sprintf(
'Installing Sylius assets for environment <info>%s</info>.',
@ -55,6 +55,6 @@ EOT
$this->runCommands($commands, $output);
return null;
return 0;
}
}

View file

@ -36,7 +36,7 @@ EOT
;
}
protected function execute(InputInterface $input, OutputInterface $output): ?int
protected function execute(InputInterface $input, OutputInterface $output): int
{
/** @var QuestionHelper $questionHelper */
$questionHelper = $this->getHelper('question');
@ -80,6 +80,6 @@ EOT
$this->runCommands($commands, $output);
$outputStyle->newLine(2);
return null;
return 0;
}
}

View file

@ -40,6 +40,15 @@ final class UserCartRecalculationListener
*/
public function recalculateCartWhileLogin(object $event): void
{
/** @psalm-suppress DocblockTypeContradiction */
if (!$event instanceof InteractiveLoginEvent && !$event instanceof UserEvent) {
throw new \TypeError(sprintf(
'$event needs to be an instance of "%s" or "%s"',
InteractiveLoginEvent::class,
UserEvent::class
));
}
try {
$cart = $this->cartContext->getCart();
} catch (CartNotFoundException $exception) {

View file

@ -29,8 +29,8 @@ final class ChangePaymentMethodType extends AbstractType
$form = $event->getForm();
foreach ($payments as $key => $payment) {
if (!in_array($payment->getState(), [PaymentInterface::STATE_NEW, PaymentInterface::STATE_CART])) {
$form->remove($key);
if (!in_array($payment->getState(), [PaymentInterface::STATE_NEW, PaymentInterface::STATE_CART], true)) {
$form->remove((string) $key);
}
}
});

View file

@ -72,11 +72,6 @@
<tag name="doctrine.event_listener" event="prePersist" lazy="true" />
<tag name="doctrine.event_listener" event="preUpdate" lazy="true" />
</service>
<service id="sylius.translator.listener" class="Symfony\Component\HttpKernel\EventListener\TranslatorListener">
<argument type="service" id="translator" />
<argument type="service" id="request_stack" />
<tag name="kernel.event_listener" event="kernel.request" method="onKernelRequest" priority="2" />
</service>
<service id="sylius.listener.review_create" class="Sylius\Bundle\CoreBundle\EventListener\ReviewCreateListener">
<argument type="service" id="sylius.context.customer" />
<tag name="kernel.event_listener" event="sylius.product_review.pre_create" method="ensureReviewHasAuthor" />

View file

@ -48,6 +48,6 @@ final class UserImpersonator implements UserImpersonatorInterface
$this->session->set($this->sessionTokenParameter, serialize($token));
$this->session->save();
$this->eventDispatcher->dispatch(UserEvents::SECURITY_IMPERSONATE, new UserEvent($user));
$this->eventDispatcher->dispatch(new UserEvent($user), UserEvents::SECURITY_IMPERSONATE);
}
}

View file

@ -78,7 +78,7 @@ final class PaymentMethodFixtureTest extends TestCase
public function payment_method_instructions_configuration_must_by_string(): void
{
$this->assertConfigurationIsValid([['custom' => [['instructions' => 'test']]]], 'custom.*.instructions');
$this->assertConfigurationIsInvalid([['custom' => [['instructions' => ['test']]]]], 'Invalid type for path "payment_method.custom.0.instructions". Expected scalar, but got array');
$this->assertConfigurationIsInvalid([['custom' => [['instructions' => ['test']]]]]);
}
/**
@ -115,7 +115,7 @@ final class PaymentMethodFixtureTest extends TestCase
public function payment_method_gateway_configuration_must_by_array(): void
{
$this->assertConfigurationIsValid([['custom' => [['gatewayConfig' => ['username' => 'USERNAME']]]]], 'custom.*.gatewayConfig');
$this->assertConfigurationIsInvalid([['custom' => [['gatewayConfig' => 'USERNAME']]]], 'Invalid type for path "payment_method.custom.0.gatewayConfig". Expected array, but got string');
$this->assertConfigurationIsInvalid([['custom' => [['gatewayConfig' => 'USERNAME']]]]);
}
/**

View file

@ -16,8 +16,10 @@ namespace Sylius\Bundle\CoreBundle\Tests\Listener;
use PHPUnit\Framework\Assert;
use PHPUnit\Framework\TestCase;
use Sylius\Bundle\CoreBundle\EventListener\CircularDependencyBreakingErrorListener;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\EventListener\ErrorListener;
use Symfony\Component\HttpKernel\HttpKernelInterface;
final class CircularDependencyBreakingExceptionListenerTest extends TestCase
{
@ -28,7 +30,7 @@ final class CircularDependencyBreakingExceptionListenerTest extends TestCase
$decoratedListener = $this->createMock(ErrorListener::class);
$listener = new CircularDependencyBreakingErrorListener($decoratedListener);
$event = $this->createMock(ExceptionEvent::class);
$event = $this->createExceptionEvent();
$secondException = new \Exception('Second');
$firstException = new \Exception('First', 0, $secondException);
@ -62,7 +64,7 @@ final class CircularDependencyBreakingExceptionListenerTest extends TestCase
$decoratedListener = $this->createMock(ErrorListener::class);
$listener = new CircularDependencyBreakingErrorListener($decoratedListener);
$event = $this->createMock(ExceptionEvent::class);
$event = $this->createExceptionEvent();
$fourthException = new \Exception('Fourth');
$thirdException = new \Exception('Third', 0, $fourthException);
@ -102,7 +104,7 @@ final class CircularDependencyBreakingExceptionListenerTest extends TestCase
$decoratedListener = $this->createMock(ErrorListener::class);
$listener = new CircularDependencyBreakingErrorListener($decoratedListener);
$event = $this->createMock(ExceptionEvent::class);
$event = $this->createExceptionEvent();
$secondException = new \Exception('Second');
$firstException = new \Exception('First', 0, $secondException);
@ -134,4 +136,13 @@ final class CircularDependencyBreakingExceptionListenerTest extends TestCase
$property->setAccessible(true);
$property->setValue($exception, $previous);
}
private function createExceptionEvent(): ExceptionEvent
{
$kernel = $this->createMock(HttpKernelInterface::class);
$request = $this->createMock(Request::class);
$exception = new \Exception();
return new ExceptionEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST, $exception);
}
}

View file

@ -173,4 +173,14 @@ final class TestKernel extends BaseKernel
protected function configureRoutes(RoutingConfigurator $routes): void
{
}
public function getCacheDir(): string
{
return sys_get_temp_dir() . '/SyliusCoreBundle/cache/' . $this->getEnvironment();
}
public function getLogDir(): string
{
return sys_get_temp_dir() . '/SyliusCoreBundle/logs';
}
}

View file

@ -38,6 +38,7 @@
"swiftmailer/swiftmailer": "^6.2",
"sylius-labs/association-hydrator": "^1.1",
"sylius-labs/doctrine-migrations-extra-bundle": "^0.1.3",
"sylius-labs/polyfill-symfony-framework-bundle": "^1.0",
"sylius/addressing-bundle": "^1.6",
"sylius/attribute-bundle": "^1.6",
"sylius/channel-bundle": "^1.6",
@ -59,14 +60,14 @@
"sylius/shipping-bundle": "^1.6",
"sylius/taxation-bundle": "^1.6",
"sylius/taxonomy-bundle": "^1.6",
"sylius/theme-bundle": "^2.1",
"sylius/theme-bundle": "^2.1.1",
"sylius/ui-bundle": "^1.6",
"sylius/user-bundle": "^1.6",
"symfony/framework-bundle": "^4.4",
"symfony/intl": "^4.4",
"symfony/messenger": "^4.4",
"symfony/framework-bundle": "^4.4 || ^5.2",
"symfony/intl": "^4.4 || ^5.2",
"symfony/messenger": "^4.4 || ^5.2",
"symfony/swiftmailer-bundle": "^3.4",
"symfony/templating": "^4.4",
"symfony/templating": "^4.4 || ^5.2",
"winzou/state-machine-bundle": "^0.5"
},
"require-dev": {
@ -76,7 +77,7 @@
"matthiasnoback/symfony-dependency-injection-test": "^4.2",
"phpspec/phpspec": "^7.0",
"phpunit/phpunit": "^8.5",
"symfony/dependency-injection": "^4.4"
"symfony/dependency-injection": "^4.4 || ^5.2"
},
"config": {
"bin-dir": "bin"

View file

@ -24,6 +24,7 @@ use Sylius\Component\Order\Context\CartContextInterface;
use Sylius\Component\Order\Context\CartNotFoundException;
use Sylius\Component\Order\Model\OrderInterface as BaseOrderInterface;
use Sylius\Component\Resource\Exception\UnexpectedTypeException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
@ -48,14 +49,17 @@ final class CartBlamerListenerSpec extends ObjectBehavior
function it_throws_exception_when_cart_does_not_implement_core_order_interface_on_interactive_login(
BaseOrderInterface $order,
CartContextInterface $cartContext,
InteractiveLoginEvent $interactiveLoginEvent,
ShopUserInterface $user,
Request $request,
TokenInterface $token
): void {
$cartContext->getCart()->willReturn($order);
$interactiveLoginEvent->getAuthenticationToken()->willReturn($token);
$token->getUser()->willReturn($user);
$this->shouldThrow(UnexpectedTypeException::class)->during('onInteractiveLogin', [$interactiveLoginEvent]);
$this
->shouldThrow(UnexpectedTypeException::class)
->during('onInteractiveLogin', [new InteractiveLoginEvent($request->getWrappedObject(), $token->getWrappedObject())])
;
}
function it_blames_cart_on_user_on_implicit_login(
@ -79,32 +83,34 @@ final class CartBlamerListenerSpec extends ObjectBehavior
ObjectManager $cartManager,
CartContextInterface $cartContext,
OrderInterface $cart,
InteractiveLoginEvent $interactiveLoginEvent,
Request $request,
TokenInterface $token,
ShopUserInterface $user,
CustomerInterface $customer
): void {
$cartContext->getCart()->willReturn($cart);
$interactiveLoginEvent->getAuthenticationToken()->willReturn($token);
$token->getUser()->willReturn($user);
$user->getCustomer()->willReturn($customer);
$cart->setCustomer($customer)->shouldBeCalled();
$cartManager->persist($cart)->shouldBeCalled();
$cartManager->flush()->shouldBeCalled();
$this->onInteractiveLogin($interactiveLoginEvent);
$this->onInteractiveLogin(new InteractiveLoginEvent($request->getWrappedObject(), $token->getWrappedObject()));
}
function it_does_nothing_if_given_user_is_invalid_on_interactive_login(
CartContextInterface $cartContext,
OrderInterface $cart,
InteractiveLoginEvent $interactiveLoginEvent,
Request $request,
TokenInterface $token
): void {
$cartContext->getCart()->willReturn($cart);
$interactiveLoginEvent->getAuthenticationToken()->willReturn($token);
$token->getUser()->willReturn('anon.');
$cart->setCustomer(Argument::any())->shouldNotBeCalled();
$this->onInteractiveLogin($interactiveLoginEvent);
$this->onInteractiveLogin(new InteractiveLoginEvent($request->getWrappedObject(), $token->getWrappedObject()));
}
function it_does_nothing_if_there_is_no_existing_cart_on_implicit_login(
@ -119,13 +125,13 @@ final class CartBlamerListenerSpec extends ObjectBehavior
function it_does_nothing_if_there_is_no_existing_cart_on_interactive_login(
CartContextInterface $cartContext,
InteractiveLoginEvent $interactiveLoginEvent,
Request $request,
TokenInterface $token,
ShopUserInterface $user
): void {
$cartContext->getCart()->willThrow(CartNotFoundException::class);
$interactiveLoginEvent->getAuthenticationToken()->willReturn($token);
$token->getUser()->willReturn($user);
$this->onInteractiveLogin($interactiveLoginEvent);
$this->onInteractiveLogin(new InteractiveLoginEvent($request->getWrappedObject(), $token->getWrappedObject()));
}
}

View file

@ -15,11 +15,14 @@ namespace spec\Sylius\Bundle\CoreBundle\EventListener;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Sylius\Bundle\UserBundle\Event\UserEvent;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Order\Context\CartContextInterface;
use Sylius\Component\Order\Context\CartNotFoundException;
use Sylius\Component\Order\Processor\OrderProcessorInterface;
use Symfony\Contracts\EventDispatcher\Event;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
final class UserCartRecalculationListenerSpec extends ObjectBehavior
{
@ -28,10 +31,23 @@ final class UserCartRecalculationListenerSpec extends ObjectBehavior
$this->beConstructedWith($cartContext, $orderProcessor);
}
function it_recalculates_cart_for_logged_in_user(
function it_recalculates_cart_for_logged_in_user_and_interactive_login_event(
CartContextInterface $cartContext,
OrderProcessorInterface $orderProcessor,
Event $event,
Request $request,
TokenInterface $token,
OrderInterface $order
): void {
$cartContext->getCart()->willReturn($order);
$orderProcessor->process($order)->shouldBeCalled();
$this->recalculateCartWhileLogin(new InteractiveLoginEvent($request->getWrappedObject(), $token->getWrappedObject()));
}
function it_recalculates_cart_for_logged_in_user_and_user_event(
CartContextInterface $cartContext,
OrderProcessorInterface $orderProcessor,
UserEvent $event,
OrderInterface $order
): void {
$cartContext->getCart()->willReturn($order);
@ -40,10 +56,22 @@ final class UserCartRecalculationListenerSpec extends ObjectBehavior
$this->recalculateCartWhileLogin($event);
}
function it_does_nothing_if_cannot_find_cart(
function it_does_nothing_if_cannot_find_cart_for_interactive_login_event(
CartContextInterface $cartContext,
OrderProcessorInterface $orderProcessor,
Event $event
Request $request,
TokenInterface $token
): void {
$cartContext->getCart()->willThrow(CartNotFoundException::class);
$orderProcessor->process(Argument::any())->shouldNotBeCalled();
$this->recalculateCartWhileLogin(new InteractiveLoginEvent($request->getWrappedObject(), $token->getWrappedObject()));
}
function it_does_nothing_if_cannot_find_cart_for_user_event(
CartContextInterface $cartContext,
OrderProcessorInterface $orderProcessor,
UserEvent $event
): void {
$cartContext->getCart()->willThrow(CartNotFoundException::class);
$orderProcessor->process(Argument::any())->shouldNotBeCalled();

View file

@ -64,6 +64,7 @@ final class ExchangeRateType extends AbstractResourceType
{
parent::configureOptions($resolver);
/** @psalm-suppress DeprecatedConstant */
$resolver->setDefault('rounding_mode', NumberToLocalizedStringTransformer::ROUND_HALF_EVEN);
}

View file

@ -28,9 +28,9 @@
"php": "^7.3",
"sylius/currency": "^1.6",
"sylius/resource-bundle": "^1.7",
"symfony/framework-bundle": "^4.4",
"symfony/intl": "^4.4",
"symfony/templating": "^4.4"
"symfony/framework-bundle": "^4.4 || ^5.2",
"symfony/intl": "^4.4 || ^5.2",
"symfony/templating": "^4.4 || ^5.2"
},
"conflict": {
"twig/twig": "^1.0"
@ -40,9 +40,9 @@
"phpspec/phpspec": "^7.0",
"phpunit/phpunit": "^8.5",
"polishsymfonycommunity/symfony-mocker-container": "^1.0",
"symfony/browser-kit": "^4.4",
"symfony/dependency-injection": "^4.4",
"symfony/form": "^4.4",
"symfony/browser-kit": "^4.4 || ^5.2",
"symfony/dependency-injection": "^4.4 || ^5.2",
"symfony/form": "^4.4 || ^5.2",
"twig/twig": "^2.12"
},
"config": {

View file

@ -40,7 +40,7 @@
"egulias/email-validator": "^2.1",
"sylius/customer": "^1.6",
"sylius/resource-bundle": "^1.7",
"symfony/framework-bundle": "^4.4",
"symfony/framework-bundle": "^4.4 || ^5.2",
"webmozart/assert": "^1.8"
},
"conflict": {
@ -50,9 +50,9 @@
"phpspec/phpspec": "^7.0",
"phpunit/phpunit": "^8.5",
"polishsymfonycommunity/symfony-mocker-container": "^1.0",
"symfony/browser-kit": "^4.4",
"symfony/dependency-injection": "^4.4",
"symfony/form": "^4.4"
"symfony/browser-kit": "^4.4 || ^5.2",
"symfony/dependency-injection": "^4.4 || ^5.2",
"symfony/form": "^4.4 || ^5.2"
},
"config": {
"bin-dir": "bin"

View file

@ -29,9 +29,9 @@
"php": "^7.3",
"sylius/inventory": "^1.6",
"sylius/resource-bundle": "^1.7",
"symfony/framework-bundle": "^4.4",
"symfony/templating": "^4.4",
"symfony/validator": "^4.4"
"symfony/framework-bundle": "^4.4 || ^5.2",
"symfony/templating": "^4.4 || ^5.2",
"symfony/validator": "^4.4 || ^5.2"
},
"conflict": {
"twig/twig": "^1.0"
@ -41,8 +41,8 @@
"phpspec/phpspec": "^7.0",
"phpunit/phpunit": "^8.5",
"polishsymfonycommunity/symfony-mocker-container": "^1.0",
"symfony/browser-kit": "^4.4",
"symfony/dependency-injection": "^4.4",
"symfony/browser-kit": "^4.4 || ^5.2",
"symfony/dependency-injection": "^4.4 || ^5.2",
"twig/twig": "^2.12"
},
"config": {

View file

@ -29,8 +29,8 @@
"php": "^7.3",
"sylius/locale": "^1.6",
"sylius/resource-bundle": "^1.7",
"symfony/framework-bundle": "^4.4",
"symfony/templating": "^4.4"
"symfony/framework-bundle": "^4.4 || ^5.2",
"symfony/templating": "^4.4 || ^5.2"
},
"conflict": {
"twig/twig": "^1.0"
@ -41,8 +41,8 @@
"phpspec/phpspec": "^7.0",
"phpunit/phpunit": "^8.5",
"polishsymfonycommunity/symfony-mocker-container": "^1.0",
"symfony/browser-kit": "^4.4",
"symfony/dependency-injection": "^4.4",
"symfony/browser-kit": "^4.4 || ^5.2",
"symfony/dependency-injection": "^4.4 || ^5.2",
"twig/twig": "^2.12"
},
"config": {

View file

@ -27,9 +27,9 @@
"require": {
"php": "^7.3",
"sylius/resource-bundle": "^1.7",
"symfony/framework-bundle": "^4.4",
"symfony/intl": "^4.4",
"symfony/templating": "^4.4",
"symfony/framework-bundle": "^4.4 || ^5.2",
"symfony/intl": "^4.4 || ^5.2",
"symfony/templating": "^4.4 || ^5.2",
"webmozart/assert": "^1.8"
},
"conflict": {
@ -41,9 +41,9 @@
"phpunit/phpunit": "^8.5",
"polishsymfonycommunity/symfony-mocker-container": "^1.0",
"sylius/currency-bundle": "^1.6",
"symfony/browser-kit": "^4.4",
"symfony/dependency-injection": "^4.4",
"symfony/form": "^4.4",
"symfony/browser-kit": "^4.4 || ^5.2",
"symfony/dependency-injection": "^4.4 || ^5.2",
"symfony/form": "^4.4 || ^5.2",
"twig/twig": "^2.12"
},
"config": {

View file

@ -1,8 +1,12 @@
vendor/
bin/
/vendor/
/bin/
composer.phar
composer.lock
/composer.phar
/composer.lock
test/app/cache
test/app/logs
/test/app/cache
/test/app/logs
/test/var/cache
/test/var/logs
/.phpunit.result.cache

View file

@ -13,7 +13,7 @@ declare(strict_types=1);
namespace Sylius\Bundle\OrderBundle\Command;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use SyliusLabs\Polyfill\Symfony\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

View file

@ -100,7 +100,7 @@ class OrderController extends ResourceController
$this->eventDispatcher->dispatchPostEvent(ResourceActions::UPDATE, $configuration, $resource);
$this->getEventDispatcher()->dispatch(SyliusCartEvents::CART_CHANGE, new GenericEvent($resource));
$this->getEventDispatcher()->dispatch(new GenericEvent($resource), SyliusCartEvents::CART_CHANGE);
$this->manager->flush();
if (!$configuration->isHtmlRequest()) {

View file

@ -50,7 +50,7 @@ final class ExpiredCartsRemover implements ExpiredCartsRemoverInterface
{
$expiredCarts = $this->orderRepository->findCartsNotModifiedSince(new \DateTime('-' . $this->expirationPeriod));
$this->eventDispatcher->dispatch(SyliusExpiredCartsEvents::PRE_REMOVE, new GenericEvent($expiredCarts));
$this->eventDispatcher->dispatch(new GenericEvent($expiredCarts), SyliusExpiredCartsEvents::PRE_REMOVE);
foreach ($expiredCarts as $expiredCart) {
$this->orderManager->remove($expiredCart);
@ -58,6 +58,6 @@ final class ExpiredCartsRemover implements ExpiredCartsRemoverInterface
$this->orderManager->flush();
$this->eventDispatcher->dispatch(SyliusExpiredCartsEvents::POST_REMOVE, new GenericEvent($expiredCarts));
$this->eventDispatcher->dispatch(new GenericEvent($expiredCarts), SyliusExpiredCartsEvents::POST_REMOVE);
}
}

View file

@ -29,11 +29,12 @@
"require": {
"php": "^7.3",
"stof/doctrine-extensions-bundle": "^1.4",
"sylius-labs/polyfill-symfony-framework-bundle": "^1.0",
"sylius/money-bundle": "^1.6",
"sylius/order": "^1.6",
"sylius/resource-bundle": "^1.7",
"symfony/framework-bundle": "^4.4",
"symfony/templating": "^4.4"
"symfony/framework-bundle": "^4.4 || ^5.2",
"symfony/templating": "^4.4 || ^5.2"
},
"conflict": {
"twig/twig": "^1.0 || ^3.0"
@ -43,9 +44,9 @@
"matthiasnoback/symfony-dependency-injection-test": "^4.1",
"phpspec/phpspec": "^7.0",
"phpunit/phpunit": "^8.5",
"symfony/browser-kit": "^4.4",
"symfony/form": "^4.4",
"symfony/validator": "^4.4"
"symfony/browser-kit": "^4.4 || ^5.2",
"symfony/form": "^4.4 || ^5.2",
"symfony/validator": "^4.4 || ^5.2"
},
"config": {
"bin-dir": "bin"

View file

@ -47,7 +47,7 @@ final class ExpiredCartsRemoverSpec extends ObjectBehavior
]);
$eventDispatcher
->dispatch(SyliusExpiredCartsEvents::PRE_REMOVE, Argument::any())
->dispatch(Argument::any(), SyliusExpiredCartsEvents::PRE_REMOVE)
->shouldBeCalled()
;
@ -56,7 +56,7 @@ final class ExpiredCartsRemoverSpec extends ObjectBehavior
$orderManager->flush();
$eventDispatcher
->dispatch(SyliusExpiredCartsEvents::POST_REMOVE, Argument::any())
->dispatch(Argument::any(), SyliusExpiredCartsEvents::POST_REMOVE)
->shouldBeCalled()
;

View file

@ -29,7 +29,7 @@
"php": "^7.3",
"sylius/payment": "^1.6",
"sylius/resource-bundle": "^1.7",
"symfony/framework-bundle": "^4.4"
"symfony/framework-bundle": "^4.4 || ^5.2"
},
"conflict": {
"twig/twig": "^3.0"
@ -41,8 +41,8 @@
"phpunit/phpunit": "^8.5",
"polishsymfonycommunity/symfony-mocker-container": "^1.0",
"sylius/locale-bundle": "^1.6",
"symfony/browser-kit": "^4.4",
"symfony/dependency-injection": "^4.4"
"symfony/browser-kit": "^4.4 || ^5.2",
"symfony/dependency-injection": "^4.4 || ^5.2"
},
"config": {
"bin-dir": "bin"

View file

@ -0,0 +1,46 @@
<?php
declare(strict_types=1);
namespace Sylius\Bundle\PayumBundle\DependencyInjection\Compiler;
use Payum\Bundle\PayumBundle\Controller;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
use Symfony\Component\DependencyInjection\Reference;
/**
* @see https://github.com/Payum/PayumBundle/issues/507
*
* @internal
*/
final class InjectContainerIntoControllersPass implements CompilerPassInterface
{
private const SERVICES = [
Controller\AuthorizeController::class,
Controller\CancelController::class,
Controller\CaptureController::class,
Controller\NotifyController::class,
Controller\PayoutController::class,
Controller\RefundController::class,
Controller\SyncController::class,
];
public function process(ContainerBuilder $container): void
{
foreach (self::SERVICES as $service) {
try {
$definition = $container->findDefinition($service);
} catch (ServiceNotFoundException $exception) {
$definition = new Definition($service);
$container->setDefinition($service, $definition);
}
$definition->addMethodCall('setContainer', [new Reference('service_container')]);
$definition->setPublic(true);
}
}
}

View file

@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
namespace Sylius\Bundle\PayumBundle\DependencyInjection\Compiler;
use Sylius\Bundle\PayumBundle\Storage\DoctrineStorage;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
/**
* @internal
*/
final class UseTweakedDoctrineStoragePass implements CompilerPassInterface
{
public function process(ContainerBuilder $container): void
{
$container->setParameter('payum.storage.doctrine.orm.class', DoctrineStorage::class);
}
}

View file

@ -13,11 +13,15 @@ declare(strict_types=1);
namespace Sylius\Bundle\PayumBundle\DependencyInjection;
use Payum\Bundle\PayumBundle\Controller;
use Sylius\Bundle\ResourceBundle\DependencyInjection\Extension\AbstractResourceExtension;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\DependencyInjection\Reference;
final class SyliusPayumExtension extends AbstractResourceExtension implements PrependExtensionInterface
{

View file

@ -0,0 +1,65 @@
<?php
declare(strict_types=1);
namespace Sylius\Bundle\PayumBundle\Storage;
use Doctrine\Persistence\ObjectManager;
use Payum\Core\Model\Identity;
use Payum\Core\Storage\AbstractStorage;
/**
* It's a drop-in replacement for DoctrineStorage that accepts
* Doctrine\Persistence\ObjectManager instead of Doctrine\Common\Persistence\ObjectManager.
*
* @internal
*
* @see \Payum\Core\Bridge\Doctrine\Storage\DoctrineStorage
*/
class DoctrineStorage extends AbstractStorage
{
/**
* @var ObjectManager
*/
protected $objectManager;
public function __construct(ObjectManager $objectManager, $modelClass)
{
parent::__construct($modelClass);
$this->objectManager = $objectManager;
}
public function findBy(array $criteria): array
{
return $this->objectManager->getRepository($this->modelClass)->findBy($criteria);
}
protected function doFind($id): ?object
{
return $this->objectManager->find($this->modelClass, $id);
}
protected function doUpdateModel($model): void
{
$this->objectManager->persist($model);
$this->objectManager->flush();
}
protected function doDeleteModel($model): void
{
$this->objectManager->remove($model);
$this->objectManager->flush();
}
protected function doGetIdentity($model): Identity
{
$modelMetadata = $this->objectManager->getClassMetadata(get_class($model));
$id = $modelMetadata->getIdentifierValues($model);
if (count($id) > 1) {
throw new \LogicException('Storage not support composite primary ids');
}
return new Identity(array_shift($id), $model);
}
}

View file

@ -13,7 +13,9 @@ declare(strict_types=1);
namespace Sylius\Bundle\PayumBundle;
use Sylius\Bundle\PayumBundle\DependencyInjection\Compiler\InjectContainerIntoControllersPass;
use Sylius\Bundle\PayumBundle\DependencyInjection\Compiler\RegisterGatewayConfigTypePass;
use Sylius\Bundle\PayumBundle\DependencyInjection\Compiler\UseTweakedDoctrineStoragePass;
use Sylius\Bundle\ResourceBundle\AbstractResourceBundle;
use Sylius\Bundle\ResourceBundle\SyliusResourceBundle;
use Symfony\Component\DependencyInjection\ContainerBuilder;
@ -31,6 +33,8 @@ final class SyliusPayumBundle extends AbstractResourceBundle
{
parent::build($container);
$container->addCompilerPass(new InjectContainerIntoControllersPass());
$container->addCompilerPass(new RegisterGatewayConfigTypePass());
$container->addCompilerPass(new UseTweakedDoctrineStoragePass());
}
}

View file

@ -40,7 +40,7 @@
},
"require-dev": {
"phpspec/phpspec": "^7.0",
"symfony/dependency-injection": "^4.4"
"symfony/dependency-injection": "^4.4 || ^5.2"
},
"config": {
"bin-dir": "bin"

View file

@ -32,17 +32,17 @@
"sylius/locale-bundle": "^1.6",
"sylius/product": "^1.6",
"sylius/resource-bundle": "^1.7",
"symfony/framework-bundle": "^4.4"
"symfony/framework-bundle": "^4.4 || ^5.2"
},
"require-dev": {
"doctrine/orm": "^2.7",
"mockery/mockery": "^1.4",
"phpspec/phpspec": "^7.0",
"phpunit/phpunit": "^8.5",
"symfony/browser-kit": "^4.4",
"symfony/dependency-injection": "^4.4",
"symfony/form": "^4.4",
"symfony/validator": "^4.4"
"symfony/browser-kit": "^4.4 || ^5.2",
"symfony/dependency-injection": "^4.4 || ^5.2",
"symfony/form": "^4.4 || ^5.2",
"symfony/validator": "^4.4 || ^5.2"
},
"config": {
"bin-dir": "bin"

View file

@ -33,7 +33,7 @@
"sylius/promotion": "^1.6",
"sylius/registry": "^1.5",
"sylius/resource-bundle": "^1.7",
"symfony/framework-bundle": "^4.4"
"symfony/framework-bundle": "^4.4 || ^5.2"
},
"conflict": {
"twig/twig": "^3.0"
@ -44,10 +44,10 @@
"phpspec/phpspec": "^7.0",
"phpunit/phpunit": "^8.5",
"polishsymfonycommunity/symfony-mocker-container": "^1.0",
"symfony/browser-kit": "^4.4",
"symfony/dependency-injection": "^4.4",
"symfony/form": "^4.4",
"symfony/validator": "^4.4"
"symfony/browser-kit": "^4.4 || ^5.2",
"symfony/dependency-injection": "^4.4 || ^5.2",
"symfony/form": "^4.4 || ^5.2",
"symfony/validator": "^4.4 || ^5.2"
},
"config": {
"bin-dir": "bin"

View file

@ -44,7 +44,7 @@
"sylius/resource-bundle": "^1.7",
"sylius/review": "^1.6",
"sylius/user-bundle": "^1.6",
"symfony/framework-bundle": "^4.4"
"symfony/framework-bundle": "^4.4 || ^5.2"
},
"conflict": {
"twig/twig": "^3.0"
@ -53,12 +53,12 @@
"phpspec/phpspec": "^7.0",
"phpunit/phpunit": "^8.5",
"polishsymfonycommunity/symfony-mocker-container": "^1.0",
"symfony/browser-kit": "^4.4",
"symfony/dependency-injection": "^4.4",
"symfony/form": "^4.4",
"symfony/security-bundle": "^4.4",
"symfony/browser-kit": "^4.4 || ^5.2",
"symfony/dependency-injection": "^4.4 || ^5.2",
"symfony/form": "^4.4 || ^5.2",
"symfony/security-bundle": "^4.4 || ^5.2",
"symfony/swiftmailer-bundle": "^3.1",
"symfony/validator": "^4.4"
"symfony/validator": "^4.4 || ^5.2"
},
"config": {
"bin-dir": "bin"

View file

@ -33,7 +33,7 @@
"sylius/money-bundle": "^1.6",
"sylius/resource-bundle": "^1.7",
"sylius/shipping": "^1.6",
"symfony/framework-bundle": "^4.4"
"symfony/framework-bundle": "^4.4 || ^5.2"
},
"conflict": {
"twig/twig": "^3.0"
@ -44,10 +44,10 @@
"phpspec/phpspec": "^7.0",
"phpunit/phpunit": "^8.5",
"polishsymfonycommunity/symfony-mocker-container": "^1.0",
"symfony/browser-kit": "^4.4",
"symfony/dependency-injection": "^4.4",
"symfony/form": "^4.4",
"symfony/validator": "^4.4"
"symfony/browser-kit": "^4.4 || ^5.2",
"symfony/dependency-injection": "^4.4 || ^5.2",
"symfony/form": "^4.4 || ^5.2",
"symfony/validator": "^4.4 || ^5.2"
},
"config": {
"bin-dir": "bin"

View file

@ -111,7 +111,7 @@ final class CustomerEmailUpdaterListener
}
if (!$user->isEnabled() && !$user->isVerified() && null !== $user->getEmailVerificationToken()) {
$this->eventDispatcher->dispatch(UserEvents::REQUEST_VERIFICATION_TOKEN, new GenericEvent($user));
$this->eventDispatcher->dispatch(new GenericEvent($user), UserEvents::REQUEST_VERIFICATION_TOKEN);
/** @var FlashBagInterface $flashBag */
$flashBag = $this->session->getBag('flashes');

View file

@ -91,7 +91,7 @@ final class UserRegistrationListener
$this->userManager->persist($user);
$this->userManager->flush();
$this->eventDispatcher->dispatch(UserEvents::REQUEST_VERIFICATION_TOKEN, new GenericEvent($user));
$this->eventDispatcher->dispatch(new GenericEvent($user), UserEvents::REQUEST_VERIFICATION_TOKEN);
}
private function enableAndLogin(ShopUserInterface $user): void

View file

@ -65,7 +65,7 @@ final class AccountMenuBuilder
->setLabelAttribute('icon', 'cart')
;
$this->eventDispatcher->dispatch(self::EVENT_NAME, new MenuBuilderEvent($this->factory, $menu));
$this->eventDispatcher->dispatch(new MenuBuilderEvent($this->factory, $menu), self::EVENT_NAME);
return $menu;
}

View file

@ -13,7 +13,7 @@ sylius_shop_account_root:
path: /
methods: [GET]
defaults:
_controller: FrameworkBundle:Redirect:redirect
_controller: Symfony\Bundle\FrameworkBundle\Controller\RedirectController:redirectAction
route: sylius_shop_account_dashboard
permanent: true

View file

@ -5,7 +5,7 @@ sylius_shop_checkout_start:
path: /
methods: [GET]
defaults:
_controller: FrameworkBundle:Redirect:redirect
_controller: Symfony\Bundle\FrameworkBundle\Controller\RedirectController:redirectAction
route: sylius_shop_checkout_address
sylius_shop_checkout_address:

View file

@ -29,8 +29,8 @@
"php": "^7.3",
"sylius/core-bundle": "^1.6",
"sylius/ui-bundle": "^1.6",
"symfony/framework-bundle": "^4.4",
"symfony/security-bundle": "^4.4",
"symfony/framework-bundle": "^4.4 || ^5.2",
"symfony/security-bundle": "^4.4 || ^5.2",
"twig/intl-extra": "^2.12",
"twig/twig": "^2.12"
},
@ -40,7 +40,7 @@
"mockery/mockery": "^1.4",
"phpspec/phpspec": "^7.0",
"phpunit/phpunit": "^8.5",
"symfony/dependency-injection": "^4.4"
"symfony/dependency-injection": "^4.4 || ^5.2"
},
"config": {
"bin-dir": "bin"

View file

@ -199,7 +199,7 @@ final class CustomerEmailUpdaterListenerSpec extends ObjectBehavior
$flashBag->add('success', 'sylius.user.verify_email_request')->shouldBeCalled();
$eventDispatcher
->dispatch(UserEvents::REQUEST_VERIFICATION_TOKEN, Argument::type(GenericEvent::class))
->dispatch(Argument::type(GenericEvent::class), UserEvents::REQUEST_VERIFICATION_TOKEN)
->shouldBeCalled()
;
@ -234,7 +234,7 @@ final class CustomerEmailUpdaterListenerSpec extends ObjectBehavior
$flashBag->add(Argument::any())->shouldNotBeCalled();
$eventDispatcher
->dispatch(UserEvents::REQUEST_VERIFICATION_TOKEN, Argument::type(GenericEvent::class))
->dispatch(Argument::type(GenericEvent::class), UserEvents::REQUEST_VERIFICATION_TOKEN)
->shouldNotBeCalled()
;
@ -269,7 +269,7 @@ final class CustomerEmailUpdaterListenerSpec extends ObjectBehavior
$flashBag->add(Argument::any())->shouldNotBeCalled();
$eventDispatcher
->dispatch(UserEvents::REQUEST_VERIFICATION_TOKEN, Argument::type(GenericEvent::class))
->dispatch(Argument::type(GenericEvent::class), UserEvents::REQUEST_VERIFICATION_TOKEN)
->shouldNotBeCalled()
;
@ -304,7 +304,7 @@ final class CustomerEmailUpdaterListenerSpec extends ObjectBehavior
$flashBag->add(Argument::any())->shouldNotBeCalled();
$eventDispatcher
->dispatch(UserEvents::REQUEST_VERIFICATION_TOKEN, Argument::type(GenericEvent::class))
->dispatch(Argument::type(GenericEvent::class), UserEvents::REQUEST_VERIFICATION_TOKEN)
->shouldNotBeCalled()
;
@ -335,7 +335,7 @@ final class CustomerEmailUpdaterListenerSpec extends ObjectBehavior
$flashBag->add(Argument::any())->shouldNotBeCalled();
$eventDispatcher
->dispatch(UserEvents::REQUEST_VERIFICATION_TOKEN, Argument::type(GenericEvent::class))
->dispatch(Argument::type(GenericEvent::class), UserEvents::REQUEST_VERIFICATION_TOKEN)
->shouldNotBeCalled()
;

View file

@ -68,7 +68,7 @@ final class UserRegistrationListenerSpec extends ObjectBehavior
$userManager->flush()->shouldBeCalled();
$eventDispatcher
->dispatch(UserEvents::REQUEST_VERIFICATION_TOKEN, Argument::type(GenericEvent::class))
->dispatch(Argument::type(GenericEvent::class), UserEvents::REQUEST_VERIFICATION_TOKEN)
->shouldBeCalled()
;
@ -103,7 +103,7 @@ final class UserRegistrationListenerSpec extends ObjectBehavior
$user->setEmailVerificationToken(Argument::any())->shouldNotBeCalled();
$eventDispatcher
->dispatch(UserEvents::REQUEST_VERIFICATION_TOKEN, Argument::type(GenericEvent::class))
->dispatch(Argument::type(GenericEvent::class), UserEvents::REQUEST_VERIFICATION_TOKEN)
->shouldNotBeCalled()
;
@ -138,7 +138,7 @@ final class UserRegistrationListenerSpec extends ObjectBehavior
$user->setEmailVerificationToken(Argument::any())->shouldNotBeCalled();
$eventDispatcher
->dispatch(UserEvents::REQUEST_VERIFICATION_TOKEN, Argument::type(GenericEvent::class))
->dispatch(Argument::type(GenericEvent::class), UserEvents::REQUEST_VERIFICATION_TOKEN)
->shouldNotBeCalled()
;

View file

@ -32,7 +32,7 @@
"sylius/registry": "^1.5",
"sylius/resource-bundle": "^1.7",
"sylius/taxation": "^1.6",
"symfony/framework-bundle": "^4.4"
"symfony/framework-bundle": "^4.4 || ^5.2"
},
"conflict": {
"twig/twig": "^3.0"
@ -43,9 +43,9 @@
"phpspec/phpspec": "^7.0",
"phpunit/phpunit": "^8.5",
"polishsymfonycommunity/symfony-mocker-container": "^1.0",
"symfony/browser-kit": "^4.4",
"symfony/dependency-injection": "^4.4",
"symfony/form": "^4.4"
"symfony/browser-kit": "^4.4 || ^5.2",
"symfony/dependency-injection": "^4.4 || ^5.2",
"symfony/form": "^4.4 || ^5.2"
},
"config": {
"bin-dir": "bin"

View file

@ -32,7 +32,7 @@
"stof/doctrine-extensions-bundle": "^1.4",
"sylius/resource-bundle": "^1.7",
"sylius/taxonomy": "^1.6",
"symfony/framework-bundle": "^4.4"
"symfony/framework-bundle": "^4.4 || ^5.2"
},
"conflict": {
"twig/twig": "^3.0"
@ -41,7 +41,7 @@
"doctrine/orm": "^2.7",
"phpspec/phpspec": "^7.0",
"phpunit/phpunit": "^8.5",
"symfony/dependency-injection": "^4.4"
"symfony/dependency-injection": "^4.4 || ^5.2"
},
"config": {
"bin-dir": "bin"

View file

@ -15,9 +15,8 @@ namespace Sylius\Bundle\UiBundle\Menu\Event;
use Knp\Menu\FactoryInterface;
use Knp\Menu\ItemInterface;
use Symfony\Component\EventDispatcher\Event;
use SyliusLabs\Polyfill\Symfony\EventDispatcher\Event;
/** @psalm-suppress DeprecatedClass */
class MenuBuilderEvent extends Event
{
/** @var FactoryInterface */

View file

@ -150,13 +150,13 @@
{% block sylius_promotion_rule_widget %}
<div class="ui segment">
{{ form_widget(form) }}
{{ block('form_widget') }}
</div>
{% endblock %}
{% block sylius_promotion_action_widget %}
<div class="ui segment">
{{ form_widget(form) }}
{{ block('form_widget') }}
</div>
{% endblock %}

View file

@ -33,12 +33,13 @@
"knplabs/knp-menu": "^3.1",
"knplabs/knp-menu-bundle": "^3.0",
"sonata-project/block-bundle": "^3.20|^4.0",
"sylius-labs/polyfill-symfony-event-dispatcher": "^1.0.1",
"sylius/grid-bundle": "^1.8",
"symfony/config": "^4.4",
"symfony/framework-bundle": "^4.4",
"symfony/security": "^4.4",
"symfony/security-bundle": "^4.4",
"symfony/templating": "^4.4",
"symfony/config": "^4.4 || ^5.2",
"symfony/framework-bundle": "^4.4 || ^5.2",
"symfony/security-core": "^4.4 || ^5.2",
"symfony/security-bundle": "^4.4 || ^5.2",
"symfony/templating": "^4.4 || ^5.2",
"zendframework/zend-stdlib": "^3.2"
},
"conflict": {
@ -49,8 +50,8 @@
"matthiasnoback/symfony-dependency-injection-test": "^4.1",
"phpspec/phpspec": "^7.0",
"phpunit/phpunit": "^8.5",
"symfony/dependency-injection": "^4.4",
"symfony/form": "^4.4",
"symfony/dependency-injection": "^4.4 || ^5.2",
"symfony/form": "^4.4 || ^5.2",
"twig/twig": "^2.12"
},
"config": {

View file

@ -25,13 +25,14 @@ use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Twig\Environment;
final class SecurityControllerSpec extends ObjectBehavior
{
function let(
AuthenticationUtils $authenticationUtils,
FormFactoryInterface $formFactory,
EngineInterface $templatingEngine,
Environment $templatingEngine,
AuthorizationCheckerInterface $authorizationChecker,
RouterInterface $router
): void {
@ -45,7 +46,7 @@ final class SecurityControllerSpec extends ObjectBehavior
FormFactoryInterface $formFactory,
Form $form,
FormView $formView,
EngineInterface $templatingEngine,
Environment $templatingEngine,
AuthorizationCheckerInterface $authorizationChecker,
Response $response
): void {

View file

@ -16,7 +16,7 @@ namespace Sylius\Bundle\UserBundle\Command;
use Doctrine\Persistence\ObjectManager;
use Sylius\Component\User\Model\UserInterface;
use Sylius\Component\User\Repository\UserRepositoryInterface;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use SyliusLabs\Polyfill\Symfony\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ChoiceQuestion;

View file

@ -14,7 +14,7 @@ declare(strict_types=1);
namespace Sylius\Bundle\UserBundle\Event;
use Sylius\Component\User\Model\UserInterface;
use Symfony\Contracts\EventDispatcher\Event;
use SyliusLabs\Polyfill\Symfony\EventDispatcher\Event;
class UserEvent extends Event
{

View file

@ -40,10 +40,12 @@
"php": "^7.3",
"doctrine/orm": "^2.7",
"egulias/email-validator": "^2.1",
"sylius-labs/polyfill-symfony-event-dispatcher": "^1.0.1",
"sylius-labs/polyfill-symfony-framework-bundle": "^1.0",
"sylius/mailer-bundle": "^1.4",
"sylius/resource-bundle": "^1.7",
"sylius/user": "^1.6",
"symfony/framework-bundle": "^4.4",
"symfony/framework-bundle": "^4.4 || ^5.2",
"webmozart/assert": "^1.8"
},
"conflict": {
@ -55,8 +57,8 @@
"php-http/guzzle6-adapter": "^2.0",
"phpspec/phpspec": "^7.0",
"phpunit/phpunit": "^8.5",
"symfony/dependency-injection": "^4.4",
"symfony/security-bundle": "^4.4",
"symfony/dependency-injection": "^4.4 || ^5.2",
"symfony/security-bundle": "^4.4 || ^5.2",
"symfony/swiftmailer-bundle": "^3.1"
},
"suggest": {

View file

@ -32,10 +32,9 @@ final class UpdateUserEncoderListenerSpec extends ObjectBehavior
function it_does_nothing_if_user_does_not_implement_user_interface(
ObjectManager $objectManager,
Request $request,
TokenInterface $token
): void {
$event = new InteractiveLoginEvent(new Request(), $token->getWrappedObject());
$user = new \stdClass();
$token->getUser()->willReturn($user);
@ -43,31 +42,29 @@ final class UpdateUserEncoderListenerSpec extends ObjectBehavior
$objectManager->persist($user)->shouldNotBeCalled();
$objectManager->flush()->shouldNotBeCalled();
$this->onSecurityInteractiveLogin($event);
$this->onSecurityInteractiveLogin(new InteractiveLoginEvent($request->getWrappedObject(), $token->getWrappedObject()));
}
function it_does_nothing_if_user_does_not_implement_specified_class_or_interface(
ObjectManager $objectManager,
Request $request,
TokenInterface $token,
User $user
): void {
$event = new InteractiveLoginEvent(new Request(), $token->getWrappedObject());
$token->getUser()->willReturn($user);
$objectManager->persist($user)->shouldNotBeCalled();
$objectManager->flush()->shouldNotBeCalled();
$this->onSecurityInteractiveLogin($event);
$this->onSecurityInteractiveLogin(new InteractiveLoginEvent($request->getWrappedObject(), $token->getWrappedObject()));
}
function it_does_nothing_if_user_uses_the_recommended_encoder(
ObjectManager $objectManager,
Request $request,
TokenInterface $token,
FixtureUser $user
): void {
$event = new InteractiveLoginEvent(new Request(), $token->getWrappedObject());
$token->getUser()->willReturn($user);
$user->getEncoderName()->willReturn('newalgo');
@ -78,7 +75,7 @@ final class UpdateUserEncoderListenerSpec extends ObjectBehavior
$objectManager->persist($user)->shouldNotBeCalled();
$objectManager->flush()->shouldNotBeCalled();
$this->onSecurityInteractiveLogin($event);
$this->onSecurityInteractiveLogin(new InteractiveLoginEvent($request->getWrappedObject(), $token->getWrappedObject()));
}
function it_does_nothing_if_plain_password_could_not_be_resolved(
@ -86,7 +83,7 @@ final class UpdateUserEncoderListenerSpec extends ObjectBehavior
TokenInterface $token,
FixtureUser $user
): void {
$event = new InteractiveLoginEvent(new Request(), $token->getWrappedObject());
$request = new Request();
$token->getUser()->willReturn($user);
@ -98,7 +95,7 @@ final class UpdateUserEncoderListenerSpec extends ObjectBehavior
$objectManager->persist($user)->shouldNotBeCalled();
$objectManager->flush()->shouldNotBeCalled();
$this->onSecurityInteractiveLogin($event);
$this->onSecurityInteractiveLogin(new InteractiveLoginEvent($request, $token->getWrappedObject()));
}
function it_does_nothing_if_resolved_plain_password_is_null(
@ -109,8 +106,6 @@ final class UpdateUserEncoderListenerSpec extends ObjectBehavior
$request = new Request();
$request->request->set('_password', null);
$event = new InteractiveLoginEvent($request, $token->getWrappedObject());
$token->getUser()->willReturn($user);
$user->getEncoderName()->willReturn('oldalgo');
@ -121,7 +116,7 @@ final class UpdateUserEncoderListenerSpec extends ObjectBehavior
$objectManager->persist($user)->shouldNotBeCalled();
$objectManager->flush()->shouldNotBeCalled();
$this->onSecurityInteractiveLogin($event);
$this->onSecurityInteractiveLogin(new InteractiveLoginEvent($request, $token->getWrappedObject()));
}
function it_does_nothing_if_resolved_plain_password_is_empty(
@ -132,8 +127,6 @@ final class UpdateUserEncoderListenerSpec extends ObjectBehavior
$request = new Request();
$request->request->set('_password', '');
$event = new InteractiveLoginEvent($request, $token->getWrappedObject());
$token->getUser()->willReturn($user);
$user->getEncoderName()->willReturn('oldalgo');
@ -144,7 +137,7 @@ final class UpdateUserEncoderListenerSpec extends ObjectBehavior
$objectManager->persist($user)->shouldNotBeCalled();
$objectManager->flush()->shouldNotBeCalled();
$this->onSecurityInteractiveLogin($event);
$this->onSecurityInteractiveLogin(new InteractiveLoginEvent($request, $token->getWrappedObject()));
}
function it_updates_the_encoder_and_plain_password_if_using_old_encoder_and_plain_password_could_be_resolved(
@ -155,8 +148,6 @@ final class UpdateUserEncoderListenerSpec extends ObjectBehavior
$request = new Request();
$request->request->set('_password', 'plainpassword');
$event = new InteractiveLoginEvent($request, $token->getWrappedObject());
$token->getUser()->willReturn($user);
$user->getEncoderName()->willReturn('oldalgo');
@ -167,7 +158,7 @@ final class UpdateUserEncoderListenerSpec extends ObjectBehavior
$objectManager->persist($user)->shouldBeCalled();
$objectManager->flush()->shouldBeCalled();
$this->onSecurityInteractiveLogin($event);
$this->onSecurityInteractiveLogin(new InteractiveLoginEvent($request, $token->getWrappedObject()));
}
function it_updates_the_encoder_and_plain_password_if_using_default_null_encoder_and_plain_password_could_be_resolved(
@ -178,8 +169,6 @@ final class UpdateUserEncoderListenerSpec extends ObjectBehavior
$request = new Request();
$request->request->set('_password', 'plainpassword');
$event = new InteractiveLoginEvent($request, $token->getWrappedObject());
$token->getUser()->willReturn($user);
$user->getEncoderName()->willReturn(null);
@ -190,6 +179,6 @@ final class UpdateUserEncoderListenerSpec extends ObjectBehavior
$objectManager->persist($user)->shouldBeCalled();
$objectManager->flush()->shouldBeCalled();
$this->onSecurityInteractiveLogin($event);
$this->onSecurityInteractiveLogin(new InteractiveLoginEvent($request, $token->getWrappedObject()));
}
}

View file

@ -48,10 +48,10 @@ final class UserLastLoginSubscriberSpec extends ObjectBehavior
function it_updates_user_last_login_on_security_interactive_login(
ObjectManager $userManager,
Request $request,
TokenInterface $token,
UserInterface $user
): void {
$event = new InteractiveLoginEvent(new Request(), $token->getWrappedObject());
$token->getUser()->willReturn($user);
$user->setLastLogin(Argument::type(\DateTimeInterface::class))->shouldBeCalled();
@ -59,7 +59,7 @@ final class UserLastLoginSubscriberSpec extends ObjectBehavior
$userManager->persist($user)->shouldBeCalled();
$userManager->flush()->shouldBeCalled();
$this->onSecurityInteractiveLogin($event);
$this->onSecurityInteractiveLogin(new InteractiveLoginEvent($request->getWrappedObject(), $token->getWrappedObject()));
}
function it_updates_user_last_login_on_implicit_login(
@ -96,12 +96,12 @@ final class UserLastLoginSubscriberSpec extends ObjectBehavior
function it_updates_only_user_specified_in_constructor(
ObjectManager $userManager,
UserEvent $event,
Request $request,
TokenInterface $token,
SymfonyUserInterface $user
): void {
$this->beConstructedWith($userManager, 'FakeBundle\User\Model\User');
$interactiveLoginEvent = new InteractiveLoginEvent(new Request(), $token->getWrappedObject());
$token->getUser()->willReturn($user);
$event->getUser()->willReturn($user);
@ -109,22 +109,25 @@ final class UserLastLoginSubscriberSpec extends ObjectBehavior
$userManager->persist(Argument::any())->shouldNotBeCalled();
$userManager->flush()->shouldNotBeCalled();
$this->onSecurityInteractiveLogin($interactiveLoginEvent);
$this->onSecurityInteractiveLogin(new InteractiveLoginEvent($request->getWrappedObject(), $token->getWrappedObject()));
}
function it_throws_exception_if_subscriber_is_used_for_class_other_than_sylius_user_interface(
ObjectManager $userManager,
Request $request,
TokenInterface $token,
SymfonyUserInterface $user
): void {
$this->beConstructedWith($userManager, SymfonyUserInterface::class);
$interactiveLoginEvent = new InteractiveLoginEvent(new Request(), $token->getWrappedObject());
$token->getUser()->willReturn($user);
$userManager->persist(Argument::any())->shouldNotBeCalled();
$userManager->flush()->shouldNotBeCalled();
$this->shouldThrow(\UnexpectedValueException::class)->during('onSecurityInteractiveLogin', [$interactiveLoginEvent]);
$this
->shouldThrow(\UnexpectedValueException::class)
->during('onSecurityInteractiveLogin', [new InteractiveLoginEvent($request->getWrappedObject(), $token->getWrappedObject())])
;
}
}

Some files were not shown because too many files have changed in this diff Show more