From 7b5c5f8c8e8b6bb8b09f4f98f76801cfd6a5cf1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wojciech=20B=C5=82oszyk?= Date: Fri, 22 May 2020 20:44:18 +0200 Subject: [PATCH] Stable version --- composer.json | 28 ++-- phpstan.neon.dist | 1 - .../SonataTwigExtension.php | 6 +- src/Bridge/Symfony/Resources/config/flash.xml | 5 +- src/Bridge/Symfony/Resources/config/twig.xml | 1 + .../translations/SonataTwigBundle.de.xliff | 4 + .../translations/SonataTwigBundle.en.xliff | 4 + .../translations/SonataTwigBundle.fr.xliff | 12 ++ .../translations/SonataTwigBundle.pl.xliff | 12 ++ src/Bridge/Symfony/SonataTwigBundle.php | 3 + src/Extension/FlashMessageExtension.php | 21 +++ src/Extension/FormTypeExtension.php | 76 +++------- src/Extension/StatusExtension.php | 4 +- src/Extension/TemplateExtension.php | 50 ++----- src/FlashMessage/FlashManager.php | 52 +++---- src/Node/TemplateBoxNode.php | 136 ++++++------------ src/TokenParser/TemplateBoxTokenParser.php | 45 +++--- tests/Extension/TemplateExtensionTest.php | 30 +++- .../Bundle/Serializer/FooSerializer.php | 2 +- tests/FlashMessage/FlashManagerTest.php | 55 +++++-- tests/Node/DeprecatedTemplateNodeTest.php | 3 - tests/Node/TemplateBoxNodeTest.php | 46 +++++- .../TemplateBoxTokenParserTest.php | 39 ++--- 23 files changed, 329 insertions(+), 306 deletions(-) diff --git a/composer.json b/composer.json index 1a6f969..9f13188 100644 --- a/composer.json +++ b/composer.json @@ -23,25 +23,25 @@ "require": { "php": "^7.2", "sonata-project/doctrine-extensions": "^1.5", - "symfony/config": "^3.4 || ^4.0 || ^5.0", - "symfony/translation": "^3.4 || ^4.0 || ^5.0", - "symfony/twig-bridge": "^3.4 || ^4.3 || ^5.0", - "twig/twig": "^2.0 || ^3.0" + "symfony/config": "^4.3", + "symfony/translation": "^4.3", + "symfony/twig-bridge": "^4.3", + "twig/twig": "^2.12.1" }, "conflict": { - "sonata-project/core-bundle": "<3.19" + "sonata-project/core-bundle": "<3.20" }, "require-dev": { - "jms/serializer-bundle": "^3.3", - "matthiasnoback/symfony-config-test": "^4.0", - "matthiasnoback/symfony-dependency-injection-test": "^4.0", - "symfony/browser-kit": "^3.4 || ^4.3 || ^5.0", - "symfony/dependency-injection": "^3.4 || ^4.0 || ^5.0", - "symfony/framework-bundle": "^3.4.36 || ^4.3 || ^5.0", - "symfony/http-foundation": "^3.4 || ^4.0 || ^5.0", - "symfony/http-kernel": "^3.4 || ^4.0 || ^5.0", + "jms/serializer-bundle": "^2.4 || ^3.0", + "matthiasnoback/symfony-config-test": "^4.2", + "matthiasnoback/symfony-dependency-injection-test": "^4.1", + "symfony/browser-kit": "^4.3", + "symfony/dependency-injection": "^4.3", + "symfony/framework-bundle": "^4.3", + "symfony/http-foundation": "^4.3", + "symfony/http-kernel": "^4.3", "symfony/phpunit-bridge": "^5.0", - "symfony/twig-bundle": "^3.4 || ^4.3 || ^5.0" + "symfony/twig-bundle": "^4.3" }, "config": { "sort-packages": true diff --git a/phpstan.neon.dist b/phpstan.neon.dist index f1632ae..d3bca39 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -13,4 +13,3 @@ parameters: - vendor/autoload.php ignoreErrors: - - '#Class Symfony\\Component\\Translation\\TranslatorInterface not found.#' diff --git a/src/Bridge/Symfony/DependencyInjection/SonataTwigExtension.php b/src/Bridge/Symfony/DependencyInjection/SonataTwigExtension.php index fcb1e0f..29e1f8e 100644 --- a/src/Bridge/Symfony/DependencyInjection/SonataTwigExtension.php +++ b/src/Bridge/Symfony/DependencyInjection/SonataTwigExtension.php @@ -41,7 +41,7 @@ public function load(array $configs, ContainerBuilder $container): void /** * Registers flash message types defined in configuration to flash manager. */ - private function registerFlashTypes(ContainerBuilder $container, array $config): void + public function registerFlashTypes(ContainerBuilder $container, array $config) { $mergedConfig = array_merge_recursive($config['flashmessage'], [ 'success' => ['types' => [ @@ -71,8 +71,8 @@ private function registerFlashTypes(ContainerBuilder $container, array $config): $identifier = 'sonata.twig.flashmessage.manager'; $definition = $container->getDefinition($identifier); - $definition->replaceArgument(1, $types); - $definition->replaceArgument(2, $cssClasses); + $definition->replaceArgument(2, $types); + $definition->replaceArgument(3, $cssClasses); $container->setDefinition($identifier, $definition); } diff --git a/src/Bridge/Symfony/Resources/config/flash.xml b/src/Bridge/Symfony/Resources/config/flash.xml index fd48867..4b195fa 100644 --- a/src/Bridge/Symfony/Resources/config/flash.xml +++ b/src/Bridge/Symfony/Resources/config/flash.xml @@ -8,8 +8,9 @@ - - + + + diff --git a/src/Bridge/Symfony/Resources/config/twig.xml b/src/Bridge/Symfony/Resources/config/twig.xml index fc3aaec..3b41bd7 100644 --- a/src/Bridge/Symfony/Resources/config/twig.xml +++ b/src/Bridge/Symfony/Resources/config/twig.xml @@ -17,6 +17,7 @@ %kernel.debug% + diff --git a/src/Bridge/Symfony/Resources/translations/SonataTwigBundle.de.xliff b/src/Bridge/Symfony/Resources/translations/SonataTwigBundle.de.xliff index 196455f..e3f93a7 100644 --- a/src/Bridge/Symfony/Resources/translations/SonataTwigBundle.de.xliff +++ b/src/Bridge/Symfony/Resources/translations/SonataTwigBundle.de.xliff @@ -2,6 +2,10 @@ + + sonata_core_template_box_file_found_in + sonata_core_template_box_file_found_in + message_close Schließen diff --git a/src/Bridge/Symfony/Resources/translations/SonataTwigBundle.en.xliff b/src/Bridge/Symfony/Resources/translations/SonataTwigBundle.en.xliff index aeea4d3..c96540a 100644 --- a/src/Bridge/Symfony/Resources/translations/SonataTwigBundle.en.xliff +++ b/src/Bridge/Symfony/Resources/translations/SonataTwigBundle.en.xliff @@ -2,6 +2,10 @@ + + sonata_core_template_box_file_found_in + This file can be found in + message_close Close diff --git a/src/Bridge/Symfony/Resources/translations/SonataTwigBundle.fr.xliff b/src/Bridge/Symfony/Resources/translations/SonataTwigBundle.fr.xliff index 0831a10..88864d5 100644 --- a/src/Bridge/Symfony/Resources/translations/SonataTwigBundle.fr.xliff +++ b/src/Bridge/Symfony/Resources/translations/SonataTwigBundle.fr.xliff @@ -2,10 +2,22 @@ + + sonata_core_template_box_file_found_in + Ce fichier est localisé à l'emplacement + message_close Fermer + + more + more + + + less + less + diff --git a/src/Bridge/Symfony/Resources/translations/SonataTwigBundle.pl.xliff b/src/Bridge/Symfony/Resources/translations/SonataTwigBundle.pl.xliff index 21b6c53..aec64e0 100644 --- a/src/Bridge/Symfony/Resources/translations/SonataTwigBundle.pl.xliff +++ b/src/Bridge/Symfony/Resources/translations/SonataTwigBundle.pl.xliff @@ -2,10 +2,22 @@ + + sonata_core_template_box_file_found_in + Plik szablony znajdziesz w + message_close Zamknij + + more + więcej + + + less + mniej + diff --git a/src/Bridge/Symfony/SonataTwigBundle.php b/src/Bridge/Symfony/SonataTwigBundle.php index c3ad90e..20e04b0 100644 --- a/src/Bridge/Symfony/SonataTwigBundle.php +++ b/src/Bridge/Symfony/SonataTwigBundle.php @@ -17,6 +17,9 @@ use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\Bundle\Bundle; +/** + * @author Thomas Rabaix + */ final class SonataTwigBundle extends Bundle { public function build(ContainerBuilder $container): void diff --git a/src/Extension/FlashMessageExtension.php b/src/Extension/FlashMessageExtension.php index 4fdce35..b02e239 100644 --- a/src/Extension/FlashMessageExtension.php +++ b/src/Extension/FlashMessageExtension.php @@ -13,6 +13,7 @@ namespace Sonata\Twig\Extension; +use Sonata\Twig\FlashMessage\FlashManager; use Twig\Extension\AbstractExtension; use Twig\TwigFunction; @@ -26,6 +27,26 @@ */ class FlashMessageExtension extends AbstractExtension { + /** + * @deprecated since sonata-project/twig-extensions 0.x, to be removed in 1.0. + * + * @var FlashManager + */ + protected $flashManager; + + public function __construct(?FlashManager $flashManager = null) + { + $this->flashManager = $flashManager; + + if ($this->flashManager) { + @trigger_error( + 'Argument "flashManager" in FlashMessageExtension is deprecated since sonata-project/twig-extensions 0.x'. + ' and will be removed in 1.0.', + E_USER_DEPRECATED + ); + } + } + /** * @return TwigFunction[] */ diff --git a/src/Extension/FormTypeExtension.php b/src/Extension/FormTypeExtension.php index 97ae360..8833402 100644 --- a/src/Extension/FormTypeExtension.php +++ b/src/Extension/FormTypeExtension.php @@ -16,69 +16,33 @@ use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; -if (class_exists('Twig_Extension_GlobalsInterface')) { +/** + * @final since sonata-project/twig-extensions 0.x + */ +class FormTypeExtension extends AbstractExtension implements GlobalsInterface +{ /** - * @final since sonata-project/twig-extensions 0.x + * @var bool */ - class FormTypeExtension extends AbstractExtension implements GlobalsInterface - { - /** - * @var bool - */ - private $wrapFieldsWithAddons; - - public function __construct($formType) - { - $this->wrapFieldsWithAddons = (true === $formType || 'standard' === $formType); - } + private $wrapFieldsWithAddons; - /** - * @return array - */ - public function getGlobals() - { - return [ - 'wrap_fields_with_addons' => $this->wrapFieldsWithAddons, - ]; - } + public function __construct($formType) + { + $this->wrapFieldsWithAddons = (true === $formType || 'standard' === $formType); + } - /** - * @return string - */ - public function getName() - { - return 'sonata_twig_wrapping'; - } + public function getGlobals(): array + { + return [ + 'wrap_fields_with_addons' => $this->wrapFieldsWithAddons, + ]; } -} else { + /** - * @final since sonata-project/twig-extensions 0.x + * @return string */ - class FormTypeExtension extends AbstractExtension implements GlobalsInterface + public function getName() { - /** - * @var bool - */ - private $wrapFieldsWithAddons; - - public function __construct($formType) - { - $this->wrapFieldsWithAddons = (true === $formType || 'standard' === $formType); - } - - public function getGlobals(): array - { - return [ - 'wrap_fields_with_addons' => $this->wrapFieldsWithAddons, - ]; - } - - /** - * @return string - */ - public function getName() - { - return 'sonata_twig_wrapping'; - } + return 'sonata_twig_wrapping'; } } diff --git a/src/Extension/StatusExtension.php b/src/Extension/StatusExtension.php index d52bb8a..84562d0 100644 --- a/src/Extension/StatusExtension.php +++ b/src/Extension/StatusExtension.php @@ -24,14 +24,14 @@ */ class StatusExtension extends AbstractExtension { - public function getFilters(): array + public function getFilters() { return [ new TwigFilter('sonata_status_class', [StatusRuntime::class, 'statusClass']), ]; } - public function getName(): string + public function getName() { return 'sonata_twig_status'; } diff --git a/src/Extension/TemplateExtension.php b/src/Extension/TemplateExtension.php index 49abdc6..63181f1 100644 --- a/src/Extension/TemplateExtension.php +++ b/src/Extension/TemplateExtension.php @@ -38,60 +38,34 @@ class TemplateExtension extends AbstractExtension /** * NEXT_MAJOR: remove this property. * - * @var LegacyTranslatorInterface|TranslatorInterface|null - * * @deprecated translator property is deprecated since sonata-project/twig-extensions 0.x, to be removed in 1.0 + * + * @var LegacyTranslatorInterface|TranslatorInterface */ protected $translator; /** - * @param bool $debug Is Symfony debug enabled? - * @param LegacyTranslatorInterface|TranslatorInterface|AdapterInterface|null $deprecatedTranslatorOrModelAdapter + * @param bool $debug Is Symfony debug enabled? + * @param LegacyTranslatorInterface|TranslatorInterface $translator */ - public function __construct($debug, $deprecatedTranslatorOrModelAdapter = null, ?AdapterInterface $deprecatedModelAdapter = null) + public function __construct($debug, $translator, AdapterInterface $modelAdapter) { - $this->debug = $debug; - if ( - !$deprecatedTranslatorOrModelAdapter instanceof LegacyTranslatorInterface && - !$deprecatedTranslatorOrModelAdapter instanceof TranslatorInterface && - !$deprecatedTranslatorOrModelAdapter instanceof AdapterInterface && - null !== $deprecatedTranslatorOrModelAdapter + !$translator instanceof LegacyTranslatorInterface && + !$translator instanceof TranslatorInterface ) { throw new \InvalidArgumentException(sprintf( - 'Argument 2 should be an instance of %s or %s or %s or %s', + 'Argument 2 should be an instance of %s or %s', LegacyTranslatorInterface::class, - TranslatorInterface::class, - 'null', - AdapterInterface::class - )); - } - - if (!$deprecatedTranslatorOrModelAdapter instanceof AdapterInterface && !$deprecatedModelAdapter instanceof AdapterInterface) { - throw new \InvalidArgumentException(sprintf( - 'Argument 3 should be an instance of %s, %s given.', - AdapterInterface::class, - \get_class($deprecatedModelAdapter) + TranslatorInterface::class )); } - if ($deprecatedTranslatorOrModelAdapter instanceof AdapterInterface) { - $this->modelAdapter = $deprecatedTranslatorOrModelAdapter; - } else { - $this->translator = $deprecatedTranslatorOrModelAdapter; - $this->modelAdapter = $deprecatedModelAdapter; - - @trigger_error( - 'The translator dependency in '.__CLASS__.' is deprecated since 0.x and will be removed in 1.0. '. - 'Please prepare your dependencies for this change.', - E_USER_DEPRECATED - ); - } + $this->debug = $debug; + $this->translator = $translator; + $this->modelAdapter = $modelAdapter; } - /** - * @return TwigFilter[] - */ public function getFilters() { return [ diff --git a/src/FlashMessage/FlashManager.php b/src/FlashMessage/FlashManager.php index 1a87b17..b3768fd 100644 --- a/src/FlashMessage/FlashManager.php +++ b/src/FlashMessage/FlashManager.php @@ -33,7 +33,7 @@ class FlashManager implements StatusClassRendererInterface /** * NEXT_MAJOR: remove this property. * - * @var LegacyTranslatorInterface|TranslatorInterface|null + * @var LegacyTranslatorInterface|TranslatorInterface * * @deprecated translator property is deprecated since sonata-project/twig-extensions 0.x, to be removed in 1.0 */ @@ -50,39 +50,31 @@ class FlashManager implements StatusClassRendererInterface protected $cssClasses; /** - * @param LegacyTranslatorInterface|TranslatorInterface|array|null $deprecatedTranslatorOrTypes - * @param array $deprecatedTypesOrCssClass Sonata types array (defined in configuration) - * @param array|null $deprecatedCssClasses Css classes associated with $types + * @param LegacyTranslatorInterface|TranslatorInterface $translator + * @param array $types Sonata core types array (defined in configuration) + * @param array $cssClasses Css classes associated with $types */ public function __construct( SessionInterface $session, - $deprecatedTranslatorOrTypes, - array $deprecatedTypesOrCssClass, - ?array $deprecatedCssClasses = null + $translator, + array $types, + array $cssClasses ) { - $this->session = $session; - - if (\is_array($deprecatedTranslatorOrTypes)) { - $this->types = $deprecatedTranslatorOrTypes; - $this->cssClasses = $deprecatedTypesOrCssClass; - } else { - $this->translator = $deprecatedTranslatorOrTypes; - $this->types = $deprecatedTypesOrCssClass; - $this->cssClasses = $deprecatedCssClasses; - - @trigger_error( - 'The translator dependency in '.__CLASS__.' is deprecated since 0.x and will be removed in 1.0. '. - 'Please prepare your dependencies for this change.', - E_USER_DEPRECATED - ); - - if (null === $deprecatedCssClasses) { - throw new \InvalidArgumentException(sprintf( - 'Argument 4 should be an instance of %s', - 'array' - )); - } + if ( + !$translator instanceof LegacyTranslatorInterface && + !$translator instanceof TranslatorInterface + ) { + throw new \InvalidArgumentException(sprintf( + 'Argument 2 should be an instance of %s or %s', + LegacyTranslatorInterface::class, + TranslatorInterface::class + )); } + + $this->session = $session; + $this->translator = $translator; + $this->types = $types; + $this->cssClasses = $cssClasses; } /** @@ -133,7 +125,7 @@ public function getSession() /** * Returns Symfony translator service. * - * @return TranslatorInterface + * @return LegacyTranslatorInterface|TranslatorInterface */ public function getTranslator() { diff --git a/src/Node/TemplateBoxNode.php b/src/Node/TemplateBoxNode.php index 78af492..c6e4417 100644 --- a/src/Node/TemplateBoxNode.php +++ b/src/Node/TemplateBoxNode.php @@ -32,51 +32,48 @@ class TemplateBoxNode extends Node /** * NEXT_MAJOR: remove this property. * - * @var LegacyTranslatorInterface|TranslatorInterface|null - * * @deprecated translator property is deprecated since sonata-project/twig-extensions 0.x, to be removed in 1.0 + * + * @var LegacyTranslatorInterface|TranslatorInterface */ protected $translator; /** - * @param AbstractExpression $message Node message to display - * @param AbstractExpression|bool $deprecatedTranslationBundleOrEnabled Node translation bundle to use for display - * @param int $deprecatedEnabledOrLineno Is Symfony debug enabled? - * @param LegacyTranslatorInterface|TranslatorInterface|string|null $deprecatedTranslatorOrTag - * @param int|string|null $deprecatedLineno Symfony template line number - * @param string|null $deprecatedTag Symfony tag name + * @param AbstractExpression $message Node message to display + * @param AbstractExpression $translationBundle Node translation bundle to use for display + * @param int $enabled Is Symfony debug enabled? + * @param string|null $lineno Symfony template line number + * @param null $tag Symfony tag name */ public function __construct( AbstractExpression $message, - $deprecatedTranslationBundleOrEnabled, - $deprecatedEnabledOrLineno, - $deprecatedTranslatorOrTag, - $deprecatedLineno = null, - $deprecatedTag = null + ?AbstractExpression $translationBundle = null, + $enabled, + $translator, + $lineno, + $tag = null ) { - if ($deprecatedTranslatorOrTag instanceof LegacyTranslatorInterface || $deprecatedTranslatorOrTag instanceof TranslatorInterface) { - $this->deprecatedConstructor( - $message, - $deprecatedTranslationBundleOrEnabled, - $deprecatedEnabledOrLineno, - $deprecatedTranslatorOrTag, - $deprecatedLineno, - $deprecatedTag - ); - - @trigger_error( - 'The translator dependency in '.__CLASS__.' is deprecated since 0.x and will be removed in 1.0. '. - 'Please prepare your dependencies for this change.', - E_USER_DEPRECATED - ); - } else { - $this->constructor( - $message, - $deprecatedTranslationBundleOrEnabled, - $deprecatedEnabledOrLineno, - $deprecatedTranslatorOrTag - ); + if ( + !$translator instanceof LegacyTranslatorInterface && + !$translator instanceof TranslatorInterface + ) { + throw new \InvalidArgumentException(sprintf( + 'Argument 2 should be an instance of %s or %s', + LegacyTranslatorInterface::class, + TranslatorInterface::class + )); } + + $this->enabled = $enabled; + $this->translator = $translator; + + $nodes = ['message' => $message]; + + if ($translationBundle) { + $nodes['translationBundle'] = $translationBundle; + } + + parent::__construct($nodes, [], $lineno, $tag); } public function compile(Compiler $compiler) @@ -92,75 +89,24 @@ public function compile(Compiler $compiler) $value = $this->getNode('message')->getAttribute('value'); - if (null !== $this->translator) { - $translationBundle = null; + $translationBundle = null; - if ($this->hasNode('translationBundle')) { - $translationBundle = $this->getNode('translationBundle'); - } + if ($this->hasNode('translationBundle')) { + $translationBundle = $this->getNode('translationBundle'); + } - if ($translationBundle) { - $translationBundle = $translationBundle->getAttribute('value'); - } + if ($translationBundle) { + $translationBundle = $translationBundle->getAttribute('value'); + } - $message = << {$this->translator->trans($value, [], $translationBundle)} -
{$this->translator->trans('sonata_core_template_box_file_found_in', [], 'SonataCoreBundle')} {\$this->getTemplateName()}.
+
{$this->translator->trans('sonata_core_template_box_file_found_in', [], 'SonataTwigBundle')} {\$this->getTemplateName()}.
" CODE; - } else { - $message = << - {$value} -
This file can be found in {\$this->getTemplateName()}.
-" -CODE; - } $compiler ->write("echo $message;"); } - - /** - * @deprecated since sonata-project/twig-extensions 0.x, to be removed with 1.0 - * - * @param AbstractExpression $message Node message to display - * @param AbstractExpression|null $translationBundle Node translation bundle to use for display - * @param int $enabled Is Symfony debug enabled? - * @param string|null $lineno Symfony template line number - * @param string|null $tag Symfony tag name - */ - private function deprecatedConstructor( - AbstractExpression $message, - ?AbstractExpression $translationBundle = null, - $enabled, - TranslatorInterface $translator, - $lineno, - ?string $tag = null - ) { - $this->enabled = $enabled; - $this->translator = $translator; - - $nodes = ['message' => $message]; - - if ($translationBundle) { - $nodes['translationBundle'] = $translationBundle; - } - - parent::__construct($nodes, [], $lineno, $tag); - } - - /** - * @param AbstractExpression $message Node message to display - * @param bool $enabled Is Symfony debug enabled? - * @param int $lineno Symfony template line number - * @param ?string $tag Symfony tag name - */ - private function constructor(AbstractExpression $message, bool $enabled, ?int $lineno, ?string $tag = null) - { - $this->enabled = $enabled; - - parent::__construct(['message' => $message], [], $lineno, $tag); - } } diff --git a/src/TokenParser/TemplateBoxTokenParser.php b/src/TokenParser/TemplateBoxTokenParser.php index da07efd..6ab3073 100644 --- a/src/TokenParser/TemplateBoxTokenParser.php +++ b/src/TokenParser/TemplateBoxTokenParser.php @@ -33,27 +33,28 @@ class TemplateBoxTokenParser extends AbstractTokenParser /** * NEXT_MAJOR: remove this property. * - * @var LegacyTranslatorInterface|TranslatorInterface|null - * - * @deprecated translator property is deprecated since sonata-project/twig-extensions 0.x, to be removed in 1.0 + * @var LegacyTranslatorInterface|TranslatorInterface */ protected $translator; /** * @param bool $enabled Is Symfony debug enabled? */ - public function __construct($enabled, $deprecatedTranslator = null) + public function __construct($enabled, $translator) { - $this->enabled = $enabled; - $this->translator = $deprecatedTranslator; - - if (null !== $deprecatedTranslator) { - @trigger_error( - 'The translator dependency in '.__CLASS__.' is deprecated since 0.x and will be removed in 1.0. '. - 'Please prepare your dependencies for this change.', - E_USER_DEPRECATED - ); + if ( + !$translator instanceof LegacyTranslatorInterface && + !$translator instanceof TranslatorInterface + ) { + throw new \InvalidArgumentException(sprintf( + 'Argument 2 should be an instance of %s or %s', + LegacyTranslatorInterface::class, + TranslatorInterface::class + )); } + + $this->enabled = $enabled; + $this->translator = $translator; } /** @@ -69,19 +70,15 @@ public function parse(Token $token) $message = new ConstantExpression('Template information', $token->getLine()); } - $this->parser->getStream()->expect(Token::BLOCK_END_TYPE); - - if (null !== $this->translator) { - if ($this->parser->getStream()->test(Token::STRING_TYPE)) { - $translationBundle = $this->parser->getExpressionParser()->parseExpression(); - } else { - $translationBundle = null; - } - - return new TemplateBoxNode($message, $translationBundle, $this->enabled, $this->translator, $token->getLine(), $this->getTag()); + if ($this->parser->getStream()->test(Token::STRING_TYPE)) { + $translationBundle = $this->parser->getExpressionParser()->parseExpression(); + } else { + $translationBundle = null; } - return new TemplateBoxNode($message, $this->enabled, $token->getLine(), $this->getTag()); + $this->parser->getStream()->expect(Token::BLOCK_END_TYPE); + + return new TemplateBoxNode($message, $translationBundle, $this->enabled, $this->translator, $token->getLine(), $this->getTag()); } /** diff --git a/tests/Extension/TemplateExtensionTest.php b/tests/Extension/TemplateExtensionTest.php index c3f6a86..d42dea8 100644 --- a/tests/Extension/TemplateExtensionTest.php +++ b/tests/Extension/TemplateExtensionTest.php @@ -16,15 +16,41 @@ use PHPUnit\Framework\TestCase; use Sonata\Doctrine\Adapter\AdapterInterface; use Sonata\Twig\Extension\TemplateExtension; +use Symfony\Component\Translation\TranslatorInterface; class TemplateExtensionTest extends TestCase { - public function testSafeUrl(): void + /** + * @group legacy + */ + public function testSlugify() { + setlocale(LC_ALL, 'en_US.utf8'); + setlocale(LC_CTYPE, 'en_US.utf8'); + + $translator = $this->createMock(TranslatorInterface::class); + + $adapter = $this->createMock(AdapterInterface::class); + $adapter->expects($this->never())->method('getUrlsafeIdentifier'); + + $extension = new TemplateExtension(true, $translator, $adapter); + + $this->assertSame($extension->slugify('test'), 'test'); + $this->assertSame($extension->slugify('S§!@@#$#$alut'), 's-alut'); + $this->assertSame($extension->slugify('Symfony2'), 'symfony2'); + $this->assertSame($extension->slugify('test'), 'test'); + $this->assertSame($extension->slugify('c\'est bientôt l\'été'), 'c-est-bientot-l-ete'); + $this->assertSame($extension->slugify(urldecode('%2Fc\'est+bientôt+l\'été')), 'c-est-bientot-l-ete'); + } + + public function testSafeUrl() + { + $translator = $this->createMock(TranslatorInterface::class); + $adapter = $this->createMock(AdapterInterface::class); $adapter->expects($this->once())->method('getUrlsafeIdentifier')->willReturn('safe-parameter'); - $extension = new TemplateExtension(true, $adapter); + $extension = new TemplateExtension(true, $translator, $adapter); $this->assertSame('safe-parameter', $extension->getUrlsafeIdentifier(new \stdClass())); } diff --git a/tests/Fixtures/Bundle/Serializer/FooSerializer.php b/tests/Fixtures/Bundle/Serializer/FooSerializer.php index e562c77..0155736 100644 --- a/tests/Fixtures/Bundle/Serializer/FooSerializer.php +++ b/tests/Fixtures/Bundle/Serializer/FooSerializer.php @@ -14,7 +14,7 @@ namespace Sonata\Twig\Tests\Fixtures\Bundle\Serializer; use Sonata\Doctrine\Model\ManagerInterface; -use Sonata\Serializer\BaseSerializerHandler; +use Sonata\Form\Serializer\BaseSerializerHandler; /** * @author Ahmet Akbana diff --git a/tests/FlashMessage/FlashManagerTest.php b/tests/FlashMessage/FlashManagerTest.php index c96fa20..4519123 100644 --- a/tests/FlashMessage/FlashManagerTest.php +++ b/tests/FlashMessage/FlashManagerTest.php @@ -20,6 +20,8 @@ use Symfony\Component\HttpFoundation\Session\Session; use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage; +use Symfony\Component\Translation\Loader\ArrayLoader; +use Symfony\Component\Translation\Translator; /** * @author Vincent Composieux @@ -33,6 +35,11 @@ class FlashManagerTest extends TestCase */ protected $session; + /** + * @var TranslatorInterface + */ + protected $translator; + /** * @var FlashManager */ @@ -44,18 +51,19 @@ class FlashManagerTest extends TestCase protected function setUp(): void { $this->session = $this->getSession(); + $this->translator = $this->getTranslator(); $this->flashManager = $this->getFlashManager([ 'success' => [ - 'my_bundle_success' => [], - 'my_second_bundle_success' => [], + 'my_bundle_success' => ['domain' => 'MySuccessBundle'], + 'my_second_bundle_success' => ['domain' => 'SonataTwigBundle'], ], 'warning' => [ - 'my_bundle_warning' => [], - 'my_second_bundle_warning' => [], + 'my_bundle_warning' => ['domain' => 'MyWarningBundle'], + 'my_second_bundle_warning' => ['domain' => 'SonataTwigBundle'], ], 'error' => [ - 'my_bundle_error' => [], - 'my_second_bundle_error' => [], + 'my_bundle_error' => ['domain' => 'MyErrorBundle'], + 'my_second_bundle_error' => ['domain' => 'SonataTwigBundle'], ], ]); } @@ -94,16 +102,16 @@ public function testGetTypes(): void $this->assertCount(3, $types); $this->assertSame([ 'success' => [ - 'my_bundle_success' => [], - 'my_second_bundle_success' => [], + 'my_bundle_success' => ['domain' => 'MySuccessBundle'], + 'my_second_bundle_success' => ['domain' => 'SonataTwigBundle'], ], 'warning' => [ - 'my_bundle_warning' => [], - 'my_second_bundle_warning' => [], + 'my_bundle_warning' => ['domain' => 'MyWarningBundle'], + 'my_second_bundle_warning' => ['domain' => 'SonataTwigBundle'], ], 'error' => [ - 'my_bundle_error' => [], - 'my_second_bundle_error' => [], + 'my_bundle_error' => ['domain' => 'MyErrorBundle'], + 'my_second_bundle_error' => ['domain' => 'SonataTwigBundle'], ], ], $types); } @@ -175,9 +183,16 @@ public function testHandlingNonRegisteredTypes(): void */ public function testFlashMessageWithCustomDomain(): void { + // Given + $translator = $this->flashManager->getTranslator(); + $translator->addLoader('array', new ArrayLoader()); + $translator->addResource('array', [ + 'my_bundle_success_message' => 'My bundle success message!', + ], 'en', 'MyCustomDomain'); + // When $this->session->getFlashBag()->set('my_bundle_success', 'my_bundle_success_message'); - $messages = $this->flashManager->get('success'); + $messages = $this->flashManager->get('success', 'MyCustomDomain'); $this->session->getFlashBag()->set('my_bundle_success', 'my_bundle_success_message'); $messagesWithoutDomain = $this->flashManager->get('success'); @@ -187,7 +202,7 @@ public function testFlashMessageWithCustomDomain(): void $this->assertCount(1, $messagesWithoutDomain); foreach ($messages as $message) { - $this->assertSame($message, 'my_bundle_success_message'); + $this->assertSame($message, 'My bundle success message!'); } foreach ($messagesWithoutDomain as $message) { @@ -205,6 +220,16 @@ protected function getSession() return new Session(new MockArraySessionStorage(), new AttributeBag(), new FlashBag()); } + /** + * Returns a Symfony translator service. + * + * @return \Symfony\Component\Translation\Translator + */ + protected function getTranslator() + { + return new Translator('en'); + } + /** * Returns Sonata flash manager. * @@ -214,6 +239,6 @@ protected function getFlashManager(array $types) { $classes = ['error' => 'danger']; - return new FlashManager($this->session, $types, $classes); + return new FlashManager($this->session, $this->translator, $types, $classes); } } diff --git a/tests/Node/DeprecatedTemplateNodeTest.php b/tests/Node/DeprecatedTemplateNodeTest.php index 6f9873e..3ca430b 100644 --- a/tests/Node/DeprecatedTemplateNodeTest.php +++ b/tests/Node/DeprecatedTemplateNodeTest.php @@ -39,9 +39,6 @@ public function testCompile($node, $source, $environment = null, $isPattern = fa parent::testCompile($node, $source, $environment, $isPattern); } - /** - * {@inheritdoc} - */ public function getTests() { return [ diff --git a/tests/Node/TemplateBoxNodeTest.php b/tests/Node/TemplateBoxNodeTest.php index 99cb2bc..069ea40 100644 --- a/tests/Node/TemplateBoxNodeTest.php +++ b/tests/Node/TemplateBoxNodeTest.php @@ -14,6 +14,9 @@ namespace Sonata\Twig\Tests\Node; use Sonata\Twig\Node\TemplateBoxNode; +use Symfony\Component\Translation\Formatter\MessageFormatterInterface; +use Symfony\Component\Translation\Loader\ArrayLoader; +use Symfony\Component\Translation\Translator; use Twig\Node\Expression\ConstantExpression; use Twig\Test\NodeTestCase; @@ -21,9 +24,13 @@ class TemplateBoxNodeTest extends NodeTestCase { public function testConstructor(): void { + $translator = $this->getTranslator('en'); + $body = new TemplateBoxNode( new ConstantExpression('This is the default message', 1), + new ConstantExpression('SonataTwigBundle', 1), true, + $translator, 1, 'sonata_template_box' ); @@ -40,21 +47,26 @@ public function testCompile($node, $source, $environment = null, $isPattern = fa parent::testCompile($node, $source, $environment, $isPattern); } - /** - * {@inheritdoc} - */ public function getTests() { + $translator = $this->getTranslator('en'); + $nodeEn = new TemplateBoxNode( new ConstantExpression('This is the default message', 1), + new ConstantExpression('SonataTwigBundle', 1), true, + $translator, 1, 'sonata_template_box' ); + $translator = $this->getTranslator('fr'); + $nodeFr = new TemplateBoxNode( new ConstantExpression('Ceci est le message par défaut', 1), + new ConstantExpression('SonataTwigBundle', 1), true, + $translator, 1, 'sonata_template_box' ); @@ -72,10 +84,36 @@ public function getTests() // line 1 echo "
Ceci est le message par défaut -
This file can be found in {$this->getTemplateName()}.
+
Ce fichier peut être trouvé à l'emplacement {$this->getTemplateName()}.
"; EOF ], ]; } + + /** + * Returns a Translator instance. + * + * @param string $locale + * + * @return Translator + */ + public function getTranslator($locale) + { + // NEXT_MAJOR: remove second argument when dropping sf < 3.4. + $translator = new Translator( + $locale, + interface_exists(MessageFormatterInterface::class) ? + null : + new IdentityTranslator() + ); + $translator->addLoader('array', new ArrayLoader()); + + $translator->addResource('array', ['sonata_template_box_media_gallery_block' => 'This is the default message'], 'en', 'SonataTwigBundle'); + $translator->addResource('array', ['sonata_template_box_media_gallery_block' => 'Ceci est le message par défaut'], 'fr', 'SonataTwigBundle'); + $translator->addResource('array', ['sonata_core_template_box_file_found_in' => 'This file can be found in'], 'en', 'SonataTwigBundle'); + $translator->addResource('array', ['sonata_core_template_box_file_found_in' => "Ce fichier peut être trouvé à l'emplacement"], 'fr', 'SonataTwigBundle'); + + return $translator; + } } diff --git a/tests/TokenParser/TemplateBoxTokenParserTest.php b/tests/TokenParser/TemplateBoxTokenParserTest.php index 1706a3f..d9b76bf 100644 --- a/tests/TokenParser/TemplateBoxTokenParserTest.php +++ b/tests/TokenParser/TemplateBoxTokenParserTest.php @@ -11,17 +11,12 @@ * file that was distributed with this source code. */ -namespace Sonata\Twig\Tests\TokenParser; +namespace Sonata\Twig\Tests\Twig\TokenParser; use PHPUnit\Framework\TestCase; use Sonata\Twig\Node\TemplateBoxNode; use Sonata\Twig\TokenParser\TemplateBoxTokenParser; -use Twig\Environment; -use Twig\Error\SyntaxError; -use Twig\Loader\ArrayLoader; -use Twig\Node\Expression\ConstantExpression; -use Twig\Parser; -use Twig\Source; +use Symfony\Component\Translation\TranslatorInterface; class TemplateBoxTokenParserTest extends TestCase { @@ -29,18 +24,22 @@ class TemplateBoxTokenParserTest extends TestCase * @dataProvider getTestsForRender * * @param bool $enabled - * @param string $source + * @param \Twig_Source $source * @param TemplateBoxNode $expected * - * @throws SyntaxError + * @throws \Twig_Error_Syntax */ public function testCompile($enabled, $source, $expected): void { - $env = new Environment(new ArrayLoader([]), ['cache' => false, 'autoescape' => false, 'optimizations' => 0]); - $env->addTokenParser(new TemplateBoxTokenParser($enabled)); - $source = new Source($source, 'test'); + $translator = $this->createMock(TranslatorInterface::class); + + $env = new \Twig_Environment(new \Twig_Loader_Array([]), ['cache' => false, 'autoescape' => false, 'optimizations' => 0]); + $env->addTokenParser(new TemplateBoxTokenParser($enabled, $translator)); + if (class_exists('\Twig_Source')) { + $source = new \Twig_Source($source, 'test'); + } $stream = $env->tokenize($source); - $parser = new Parser($env); + $parser = new \Twig_Parser($env); // "0" is passed as string due an issue with the allowed node name types. // @see https://github.com/twigphp/Twig/issues/3294 @@ -55,13 +54,17 @@ public function testCompile($enabled, $source, $expected): void public function getTestsForRender() { + $translator = $this->createMock(TranslatorInterface::class); + return [ [ true, '{% sonata_template_box %}', new TemplateBoxNode( - new ConstantExpression('Template information', 1), + new \Twig_Node_Expression_Constant('Template information', 1), + null, true, + $translator, 1, 'sonata_template_box' ), @@ -70,8 +73,10 @@ public function getTestsForRender() true, '{% sonata_template_box "This is the basket delivery address step page" %}', new TemplateBoxNode( - new ConstantExpression('This is the basket delivery address step page', 1), + new \Twig_Node_Expression_Constant('This is the basket delivery address step page', 1), + null, true, + $translator, 1, 'sonata_template_box' ), @@ -80,8 +85,10 @@ public function getTestsForRender() false, '{% sonata_template_box "This is the basket delivery address step page" %}', new TemplateBoxNode( - new ConstantExpression('This is the basket delivery address step page', 1), + new \Twig_Node_Expression_Constant('This is the basket delivery address step page', 1), + null, false, + $translator, 1, 'sonata_template_box' ),