diff --git a/.travis.yml b/.travis.yml index 1b05b97..21847e8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,7 @@ branches: only: - master - 1.x + - 0.x language: php diff --git a/composer.json b/composer.json index 656bf96..1a6f969 100644 --- a/composer.json +++ b/composer.json @@ -29,7 +29,7 @@ "twig/twig": "^2.0 || ^3.0" }, "conflict": { - "sonata-project/core-bundle": ">=3.13" + "sonata-project/core-bundle": "<3.19" }, "require-dev": { "jms/serializer-bundle": "^3.3", @@ -48,7 +48,7 @@ }, "extra": { "branch-alias": { - "dev-master": "1.x-dev" + "dev-master": "0.x-dev" } }, "autoload": { diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 581300e..f1632ae 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -7,10 +7,10 @@ parameters: # - tests excludes_analyse: - - src/Test/AbstractWidgetTestCase.php - tests/bootstrap.php autoload_files: - vendor/autoload.php ignoreErrors: + - '#Class Symfony\\Component\\Translation\\TranslatorInterface not found.#' diff --git a/src/Bridge/Symfony/Bundle/SonataTwigBundle.php b/src/Bridge/Symfony/Bundle/SonataTwigBundle.php deleted file mode 100644 index 5432777..0000000 --- a/src/Bridge/Symfony/Bundle/SonataTwigBundle.php +++ /dev/null @@ -1,33 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Sonata\Twig\Bridge\Symfony\Bundle; - -use Sonata\Twig\Bridge\Symfony\DependencyInjection\Compiler\StatusRendererCompilerPass; -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\HttpKernel\Bundle\Bundle; - -/** - * NEXT_MAJOR: remove this class. - * - * @deprecated since version 1.x, to be removed in 2.0. Use Sonata\Twig\Bridge\Symfony\SonataTwigBundle instead. - * - * @author Thomas Rabaix - */ -final class SonataTwigBundle extends Bundle -{ - public function build(ContainerBuilder $container): void - { - $container->addCompilerPass(new StatusRendererCompilerPass()); - } -} diff --git a/src/Bridge/Symfony/DependencyInjection/SonataTwigExtension.php b/src/Bridge/Symfony/DependencyInjection/SonataTwigExtension.php index a0aa264..fcb1e0f 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. */ - public function registerFlashTypes(ContainerBuilder $container, array $config): void + private function registerFlashTypes(ContainerBuilder $container, array $config): void { $mergedConfig = array_merge_recursive($config['flashmessage'], [ 'success' => ['types' => [ diff --git a/src/Extension/DeprecatedTemplateExtension.php b/src/Extension/DeprecatedTemplateExtension.php index d2b95d2..cfbaf88 100644 --- a/src/Extension/DeprecatedTemplateExtension.php +++ b/src/Extension/DeprecatedTemplateExtension.php @@ -18,13 +18,15 @@ /** * @author Marko Kunic + * + * @final since sonata-project/twig-extensions 0.x */ -final class DeprecatedTemplateExtension extends AbstractExtension +class DeprecatedTemplateExtension extends AbstractExtension { /** - * {@inheritdoc} + * @return array */ - public function getTokenParsers(): array + public function getTokenParsers() { return [ new DeprecatedTemplateTokenParser(), diff --git a/src/Extension/FlashMessageExtension.php b/src/Extension/FlashMessageExtension.php index 1acf561..4fdce35 100644 --- a/src/Extension/FlashMessageExtension.php +++ b/src/Extension/FlashMessageExtension.php @@ -21,10 +21,15 @@ * * @author Vincent Composieux * @author Titouan Galopin + * + * @final since sonata-project/twig-extensions 0.x */ -final class FlashMessageExtension extends AbstractExtension +class FlashMessageExtension extends AbstractExtension { - public function getFunctions(): array + /** + * @return TwigFunction[] + */ + public function getFunctions() { return [ new TwigFunction('sonata_flashmessages_get', [FlashMessageRuntime::class, 'getFlashMessages']), @@ -32,7 +37,10 @@ public function getFunctions(): array ]; } - public function getName(): string + /** + * @return string + */ + public function getName() { return 'sonata_twig_flashmessage'; } diff --git a/src/Extension/FlashMessageRuntime.php b/src/Extension/FlashMessageRuntime.php index b6a8fc6..f63d2bd 100644 --- a/src/Extension/FlashMessageRuntime.php +++ b/src/Extension/FlashMessageRuntime.php @@ -20,8 +20,10 @@ * * @author Vincent Composieux * @author Titouan Galopin + * + * @final since sonata-project/twig-extensions 0.x */ -final class FlashMessageRuntime +class FlashMessageRuntime { /** * @var FlashManager @@ -36,17 +38,22 @@ public function __construct(FlashManager $flashManager) /** * Returns flash messages handled by Sonata flash manager. * - * @param string $type Type of flash message + * @param string $type Type of flash message + * @param string|null $deprecatedDomain Translation domain to use + * + * @return array */ - public function getFlashMessages(string $type): array + public function getFlashMessages($type, $deprecatedDomain = null) { - return $this->flashManager->get($type); + return $this->flashManager->get($type, $deprecatedDomain); } /** * Returns flash messages types handled by Sonata flash manager. + * + * @return array */ - public function getFlashMessagesTypes(): array + public function getFlashMessagesTypes() { return $this->flashManager->getHandledTypes(); } diff --git a/src/Extension/FormTypeExtension.php b/src/Extension/FormTypeExtension.php index c0e6e39..97ae360 100644 --- a/src/Extension/FormTypeExtension.php +++ b/src/Extension/FormTypeExtension.php @@ -16,27 +16,69 @@ use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; -final class FormTypeExtension extends AbstractExtension implements GlobalsInterface -{ +if (class_exists('Twig_Extension_GlobalsInterface')) { /** - * @var bool + * @final since sonata-project/twig-extensions 0.x */ - private $wrapFieldsWithAddons; - - public function __construct($formType) + class FormTypeExtension extends AbstractExtension implements GlobalsInterface { - $this->wrapFieldsWithAddons = (true === $formType || 'standard' === $formType); - } + /** + * @var bool + */ + private $wrapFieldsWithAddons; - public function getGlobals(): array - { - return [ - 'wrap_fields_with_addons' => $this->wrapFieldsWithAddons, - ]; - } + public function __construct($formType) + { + $this->wrapFieldsWithAddons = (true === $formType || 'standard' === $formType); + } + + /** + * @return array + */ + public function getGlobals() + { + return [ + 'wrap_fields_with_addons' => $this->wrapFieldsWithAddons, + ]; + } - public function getName(): string + /** + * @return string + */ + public function getName() + { + return 'sonata_twig_wrapping'; + } + } +} else { + /** + * @final since sonata-project/twig-extensions 0.x + */ + class FormTypeExtension extends AbstractExtension implements GlobalsInterface { - return 'sonata_twig_wrapping'; + /** + * @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'; + } } } diff --git a/src/Extension/StatusExtension.php b/src/Extension/StatusExtension.php index 45ead0d..d52bb8a 100644 --- a/src/Extension/StatusExtension.php +++ b/src/Extension/StatusExtension.php @@ -19,8 +19,10 @@ /** * @author Hugo Briand * @author Titouan Galopin + * + * @final since sonata-project/twig-extensions 0.x */ -final class StatusExtension extends AbstractExtension +class StatusExtension extends AbstractExtension { public function getFilters(): array { diff --git a/src/Extension/StatusRuntime.php b/src/Extension/StatusRuntime.php index 9e256c0..7b9e3fa 100644 --- a/src/Extension/StatusRuntime.php +++ b/src/Extension/StatusRuntime.php @@ -18,8 +18,10 @@ /** * @author Hugo Briand * @author Titouan Galopin + * + * @final since sonata-project/twig-extensions 0.x */ -final class StatusRuntime +class StatusRuntime { /** * @var StatusClassRendererInterface[] @@ -29,15 +31,19 @@ final class StatusRuntime /** * Adds a renderer to the status services list. */ - public function addStatusService(StatusClassRendererInterface $renderer): void + public function addStatusService(StatusClassRendererInterface $renderer) { $this->statusServices[] = $renderer; } /** - * @param mixed $statusType + * @param object $object + * @param mixed|null $statusType + * @param string $default + * + * @return string */ - public function statusClass(object $object, $statusType = null, string $default = ''): string + public function statusClass($object, $statusType = null, $default = '') { foreach ($this->statusServices as $statusService) { \assert($statusService instanceof StatusClassRendererInterface); diff --git a/src/Extension/TemplateExtension.php b/src/Extension/TemplateExtension.php index 2cbdfea..49abdc6 100644 --- a/src/Extension/TemplateExtension.php +++ b/src/Extension/TemplateExtension.php @@ -15,10 +15,15 @@ use Sonata\Doctrine\Adapter\AdapterInterface; use Sonata\Twig\TokenParser\TemplateBoxTokenParser; +use Symfony\Component\Translation\TranslatorInterface as LegacyTranslatorInterface; +use Symfony\Contracts\Translation\TranslatorInterface; use Twig\Extension\AbstractExtension; use Twig\TwigFilter; -final class TemplateExtension extends AbstractExtension +/** + * @final since sonata-project/twig-extensions 0.x + */ +class TemplateExtension extends AbstractExtension { /** * @var bool @@ -31,38 +36,125 @@ final class TemplateExtension extends AbstractExtension protected $modelAdapter; /** - * @param bool $debug Is Symfony debug enabled? - * @param AdapterInterface $modelAdapter A Sonata model adapter + * 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 + */ + protected $translator; + + /** + * @param bool $debug Is Symfony debug enabled? + * @param LegacyTranslatorInterface|TranslatorInterface|AdapterInterface|null $deprecatedTranslatorOrModelAdapter */ - public function __construct(bool $debug, AdapterInterface $modelAdapter) + public function __construct($debug, $deprecatedTranslatorOrModelAdapter = null, ?AdapterInterface $deprecatedModelAdapter = null) { $this->debug = $debug; - $this->modelAdapter = $modelAdapter; + + if ( + !$deprecatedTranslatorOrModelAdapter instanceof LegacyTranslatorInterface && + !$deprecatedTranslatorOrModelAdapter instanceof TranslatorInterface && + !$deprecatedTranslatorOrModelAdapter instanceof AdapterInterface && + null !== $deprecatedTranslatorOrModelAdapter + ) { + throw new \InvalidArgumentException(sprintf( + 'Argument 2 should be an instance of %s or %s or %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) + )); + } + + 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 + ); + } } - public function getFilters(): array + /** + * @return TwigFilter[] + */ + public function getFilters() { return [ + new TwigFilter('sonata_slugify', [$this, 'slugify'], ['deprecated' => true, 'alternative' => 'slugify']), new TwigFilter('sonata_urlsafeid', [$this, 'getUrlsafeIdentifier']), ]; } - public function getTokenParsers(): array + /** + * @return array + */ + public function getTokenParsers() { return [ - new TemplateBoxTokenParser($this->debug), + new TemplateBoxTokenParser($this->debug, $this->translator), ]; } + /** + * Slugify a text. + * + * @deprecated Twig filter "sonata_slugify" is deprecated since sonata-project/twig-extensions 0.x, to be removed in 1.0. Use "slugify" instead. + * + * @param string $text + * + * @return string|null + */ + public function slugify($text) + { + // replace non letter or digits by - + $text = preg_replace('~[^\\pL\d]+~u', '-', $text); + + // trim + $text = trim($text, '-'); + + // transliterate + if (\function_exists('iconv')) { + $text = iconv('UTF-8', 'ASCII//TRANSLIT', $text); + } + + // lowercase + $text = strtolower($text); + + // remove unwanted characters + $text = preg_replace('~[^-\w]+~', '', $text); + + return $text; + } + /** * @param object $model + * + * @return string */ - public function getUrlsafeIdentifier($model): ?string + public function getUrlsafeIdentifier($model) { return $this->modelAdapter->getUrlsafeIdentifier($model); } - public function getName(): string + /** + * @return string + */ + public function getName() { return 'sonata_twig_template'; } diff --git a/src/FlashMessage/FlashManager.php b/src/FlashMessage/FlashManager.php index e212f53..1a87b17 100644 --- a/src/FlashMessage/FlashManager.php +++ b/src/FlashMessage/FlashManager.php @@ -15,44 +15,95 @@ use Sonata\Twig\Status\StatusClassRendererInterface; use Symfony\Component\HttpFoundation\Session\SessionInterface; +use Symfony\Component\Translation\TranslatorInterface as LegacyTranslatorInterface; +use Symfony\Contracts\Translation\TranslatorInterface; /** * @author Vincent Composieux + * + * @final since sonata-project/twig-extensions 0.x */ -final class FlashManager implements StatusClassRendererInterface +class FlashManager implements StatusClassRendererInterface { /** * @var SessionInterface */ - private $session; + protected $session; + + /** + * 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 + */ + protected $translator; /** * @var array */ - private $types; + protected $types; /** * @var array */ - private $cssClasses; + protected $cssClasses; /** - * @param array $types Sonata types array (defined in configuration) - * @param array $cssClasses Css classes associated with $types + * @param LegacyTranslatorInterface|TranslatorInterface|array|null $deprecatedTranslatorOrTypes + * @param array $deprecatedTypesOrCssClass Sonata types array (defined in configuration) + * @param array|null $deprecatedCssClasses Css classes associated with $types */ - public function __construct(SessionInterface $session, array $types, array $cssClasses) - { + public function __construct( + SessionInterface $session, + $deprecatedTranslatorOrTypes, + array $deprecatedTypesOrCssClass, + ?array $deprecatedCssClasses = null + ) { $this->session = $session; - $this->types = $types; - $this->cssClasses = $cssClasses; + + 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' + )); + } + } } - public function handlesObject($object, ?string $statusName = null): bool + /** + * @param mixed $object + * @param string|null $statusName + * + * @return bool + */ + public function handlesObject($object, $statusName = null) { return \is_string($object) && \array_key_exists($object, $this->cssClasses); } - public function getStatusClass($object, ?string $statusName = null, string $default = ''): string + /** + * @param mixed $object + * @param string|null $statusName + * @param string $default + * + * @return string + */ + public function getStatusClass($object, $statusName = null, $default = '') { return \array_key_exists($object, $this->cssClasses) ? $this->cssClasses[$object] @@ -61,46 +112,70 @@ public function getStatusClass($object, ?string $statusName = null, string $defa /** * Returns Sonata flash message types. + * + * @return array */ - public function getTypes(): array + public function getTypes() { return $this->types; } /** * Returns Symfony session service. + * + * @return SessionInterface */ - public function getSession(): SessionInterface + public function getSession() { return $this->session; } + /** + * Returns Symfony translator service. + * + * @return TranslatorInterface + */ + public function getTranslator() + { + return $this->translator; + } + /** * Returns flash bag messages for correct type after renaming with Sonata type. + * + * @param string $type Type of flash message + * @param string $deprecatedDomain Translation domain to use + * + * @return array */ - public function get(string $type): array + public function get($type, $deprecatedDomain = null) { - $this->handle(); + $this->handle($deprecatedDomain); return $this->getSession()->getFlashBag()->get($type); } /** * Gets handled message types. + * + * @return array */ - public function getHandledTypes(): array + public function getHandledTypes() { return array_keys($this->getTypes()); } /** * Handles flash bag types renaming. + * + * @param string $deprecatedDomain */ - private function handle(): void + protected function handle($deprecatedDomain = null) { foreach ($this->getTypes() as $type => $values) { foreach ($values as $value => $options) { - $this->rename($type, $value); + $domainType = $deprecatedDomain ?: ($options['domain'] ?? null); + $this->rename($type, $value, $domainType); } } } @@ -108,14 +183,18 @@ private function handle(): void /** * Process flash message type rename. * - * @param string $type Sonata flash message type - * @param string $value Original flash message type + * @param string $type Sonata flash message type + * @param string $value Original flash message type + * @param string|null $deprecatedDomain Translation domain to use */ - private function rename(string $type, string $value): void + protected function rename($type, $value, $deprecatedDomain = null) { $flashBag = $this->getSession()->getFlashBag(); foreach ($flashBag->get($value) as $message) { + if (null !== $this->getTranslator() && null !== $deprecatedDomain) { + $message = $this->getTranslator()->trans($message, [], $deprecatedDomain); + } $flashBag->add($type, $message); } } diff --git a/src/Node/DeprecatedTemplateNode.php b/src/Node/DeprecatedTemplateNode.php index cd93dea..5eb7118 100644 --- a/src/Node/DeprecatedTemplateNode.php +++ b/src/Node/DeprecatedTemplateNode.php @@ -19,15 +19,17 @@ /** * @author Marko Kunic + * + * @final since sonata-project/twig-extensions 0.x */ -final class DeprecatedTemplateNode extends Node +class DeprecatedTemplateNode extends Node { public function __construct(AbstractExpression $newTemplate, $line, $tag = null) { parent::__construct(['newTemplate' => $newTemplate], [], $line, $tag); } - public function compile(Compiler $compiler): void + public function compile(Compiler $compiler) { @trigger_error(sprintf( 'The "%s" template is deprecated. Use "%s" instead.', diff --git a/src/Node/TemplateBoxNode.php b/src/Node/TemplateBoxNode.php index af71c37..78af492 100644 --- a/src/Node/TemplateBoxNode.php +++ b/src/Node/TemplateBoxNode.php @@ -13,11 +13,16 @@ namespace Sonata\Twig\Node; +use Symfony\Component\Translation\TranslatorInterface as LegacyTranslatorInterface; +use Symfony\Contracts\Translation\TranslatorInterface; use Twig\Compiler; use Twig\Node\Expression\AbstractExpression; use Twig\Node\Node; -final class TemplateBoxNode extends Node +/** + * @final since sonata-project/twig-extensions 0.x + */ +class TemplateBoxNode extends Node { /** * @var int @@ -25,19 +30,56 @@ final class TemplateBoxNode extends Node protected $enabled; /** - * @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 + * 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 */ - public function __construct(AbstractExpression $message, bool $enabled, ?int $lineno, ?string $tag = null) - { - $this->enabled = $enabled; + protected $translator; - parent::__construct(['message' => $message], [], $lineno, $tag); + /** + * @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 + */ + public function __construct( + AbstractExpression $message, + $deprecatedTranslationBundleOrEnabled, + $deprecatedEnabledOrLineno, + $deprecatedTranslatorOrTag, + $deprecatedLineno = null, + $deprecatedTag = 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 + ); + } } - public function compile(Compiler $compiler): void + public function compile(Compiler $compiler) { $compiler ->addDebugInfo($this); @@ -50,14 +92,75 @@ public function compile(Compiler $compiler): void $value = $this->getNode('message')->getAttribute('value'); - $message = <<translator) { + $translationBundle = null; + + if ($this->hasNode('translationBundle')) { + $translationBundle = $this->getNode('translationBundle'); + } + + 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()}.
+" +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/Status/StatusClassRendererInterface.php b/src/Status/StatusClassRendererInterface.php index f023a24..fb9b2bd 100644 --- a/src/Status/StatusClassRendererInterface.php +++ b/src/Status/StatusClassRendererInterface.php @@ -20,11 +20,22 @@ interface StatusClassRendererInterface { /** * Tells if class may handle $object for status class rendering. + * + * @param mixed $object + * @param string|null $statusName + * + * @return bool */ - public function handlesObject(object $object, ?string $statusName = null): bool; + public function handlesObject($object, $statusName = null); /** * Returns the status CSS class for $object. + * + * @param mixed $object + * @param string|null $statusName + * @param string $default + * + * @return string */ - public function getStatusClass(object $object, ?string $statusName = null, string $default = ''): string; + public function getStatusClass($object, $statusName = null, $default = ''); } diff --git a/src/TokenParser/DeprecatedTemplateTokenParser.php b/src/TokenParser/DeprecatedTemplateTokenParser.php index f8cdd98..6dc69d5 100644 --- a/src/TokenParser/DeprecatedTemplateTokenParser.php +++ b/src/TokenParser/DeprecatedTemplateTokenParser.php @@ -19,10 +19,17 @@ /** * @author Marko Kunic + * + * @final since sonata-project/twig-extensions 0.x */ -final class DeprecatedTemplateTokenParser extends AbstractTokenParser +class DeprecatedTemplateTokenParser extends AbstractTokenParser { - public function parse(Token $token): DeprecatedTemplateNode + /** + * @throws \Twig\Error\SyntaxError + * + * @return DeprecatedTemplateNode + */ + public function parse(Token $token) { if (!$this->parser->getStream()->test(Token::STRING_TYPE)) { throw new \InvalidArgumentException('New template name is mandatory.'); @@ -35,7 +42,10 @@ public function parse(Token $token): DeprecatedTemplateNode return new DeprecatedTemplateNode($newTemplate, $token->getLine(), $this->getTag()); } - public function getTag(): string + /** + * @return string + */ + public function getTag() { return 'sonata_template_deprecate'; } diff --git a/src/TokenParser/TemplateBoxTokenParser.php b/src/TokenParser/TemplateBoxTokenParser.php index 21ed2b3..da07efd 100644 --- a/src/TokenParser/TemplateBoxTokenParser.php +++ b/src/TokenParser/TemplateBoxTokenParser.php @@ -14,26 +14,54 @@ namespace Sonata\Twig\TokenParser; use Sonata\Twig\Node\TemplateBoxNode; +use Symfony\Component\Translation\TranslatorInterface as LegacyTranslatorInterface; +use Symfony\Contracts\Translation\TranslatorInterface; use Twig\Node\Expression\ConstantExpression; use Twig\Token; use Twig\TokenParser\AbstractTokenParser; -final class TemplateBoxTokenParser extends AbstractTokenParser +/** + * @final since sonata-project/twig-extensions 0.x + */ +class TemplateBoxTokenParser extends AbstractTokenParser { /** * @var bool */ protected $enabled; + /** + * 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 + */ + protected $translator; + /** * @param bool $enabled Is Symfony debug enabled? */ - public function __construct(bool $enabled) + public function __construct($enabled, $deprecatedTranslator = null) { $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 + ); + } } - public function parse(Token $token): TemplateBoxNode + /** + * @throws \Twig\Error\SyntaxError, + * + * @return TemplateBoxNode + */ + public function parse(Token $token) { if ($this->parser->getStream()->test(Token::STRING_TYPE)) { $message = $this->parser->getExpressionParser()->parseExpression(); @@ -43,10 +71,23 @@ public function parse(Token $token): TemplateBoxNode $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()); + } + return new TemplateBoxNode($message, $this->enabled, $token->getLine(), $this->getTag()); } - public function getTag(): string + /** + * @return string + */ + public function getTag() { return 'sonata_template_box'; }