diff --git a/UPGRADE-3.x.md b/UPGRADE-3.x.md index ac9402ef40..ce6e5f0ff3 100644 --- a/UPGRADE-3.x.md +++ b/UPGRADE-3.x.md @@ -1,6 +1,14 @@ UPGRADE 3.x =========== +## Deprecated `sonata_truncate` Twig filter + +This filter has been deprecated in favor of the [`u` filter](https://twig.symfony.com/doc/2.x/filters/u.html): + +## Deprecated `SonataAdminBundle\Twig\Extension\UnicodeString` + +Use `Symfony\Component\String\UnicodeString` instead. + UPGRADE FROM 3.67 to 3.68 ========================= diff --git a/composer.json b/composer.json index edf84d08b3..4e27adc805 100644 --- a/composer.json +++ b/composer.json @@ -49,11 +49,11 @@ "symfony/security-bundle": "^4.3", "symfony/security-core": "^4.3", "symfony/security-csrf": "^4.3", + "symfony/string": "^5.1", "symfony/translation": "^4.3", "symfony/twig-bridge": "^4.3", "symfony/twig-bundle": "^4.3", "symfony/validator": "^4.3", - "twig/extensions": "^1.5", "twig/extra-bundle": "^3.0", "twig/string-extra": "^3.0", "twig/twig": "^2.12.1" diff --git a/docs/cookbook/recipe_customizing_a_mosaic_list.rst b/docs/cookbook/recipe_customizing_a_mosaic_list.rst index ada101d645..a4e2667a70 100644 --- a/docs/cookbook/recipe_customizing_a_mosaic_list.rst +++ b/docs/cookbook/recipe_customizing_a_mosaic_list.rst @@ -18,7 +18,7 @@ It is possible to configure the default view by creating a dedicated template. please use the following configuration: .. code-block:: yaml - + # config/packages/sonata_admin.yaml sonata_admin: @@ -89,11 +89,11 @@ The ``list_outer_rows_mosaic.html.twig`` is the name of one mosaic's tile. You s {% block sonata_mosaic_description %} {% if admin.hasAccess('edit', object) and admin.hasRoute('edit') %} - {{ meta.title|truncate(40) }} + {{ meta.title|u.truncate(40) }} {% elseif admin.hasAccess('show', object) and admin.hasRoute('show') %} - {{ meta.title|truncate(40) }} + {{ meta.title|u.truncate(40) }} {% else %} - {{ meta.title|truncate(40) }} + {{ meta.title|u.truncate(40) }} {% endif %} {% endblock %} diff --git a/src/Resources/views/CRUD/base_edit.html.twig b/src/Resources/views/CRUD/base_edit.html.twig index a03d4cbb5f..d1cf4a7771 100644 --- a/src/Resources/views/CRUD/base_edit.html.twig +++ b/src/Resources/views/CRUD/base_edit.html.twig @@ -14,18 +14,18 @@ file that was distributed with this source code. {% block title %} {# NEXT_MAJOR: remove default filter #} {% if objectId|default(admin.id(object)) is not null %} - {{ 'title_edit'|trans({'%name%': admin.toString(object)|truncate(15) }, 'SonataAdminBundle') }} + {{ 'title_edit'|trans({'%name%': admin.toString(object)|u.truncate(15) }, 'SonataAdminBundle') }} {% else %} - {{ 'title_create'|trans({}, 'SonataAdminBundle')|truncate(15) }} + {{ 'title_create'|trans({}, 'SonataAdminBundle')|u.truncate(15) }} {% endif %} {% endblock %} {% block navbar_title %} {# NEXT_MAJOR: remove default filter #} {% if objectId|default(admin.id(object)) is not null %} - {{ 'title_edit'|trans({'%name%': admin.toString(object)|truncate(100) }, 'SonataAdminBundle') }} + {{ 'title_edit'|trans({'%name%': admin.toString(object)|u.truncate(100) }, 'SonataAdminBundle') }} {% else %} - {{ 'title_create'|trans({}, 'SonataAdminBundle')|truncate(100) }} + {{ 'title_create'|trans({}, 'SonataAdminBundle')|u.truncate(100) }} {% endif %} {% endblock %} diff --git a/src/Resources/views/CRUD/base_list.html.twig b/src/Resources/views/CRUD/base_list.html.twig index c18b3d0a40..b891286df4 100644 --- a/src/Resources/views/CRUD/base_list.html.twig +++ b/src/Resources/views/CRUD/base_list.html.twig @@ -23,11 +23,11 @@ file that was distributed with this source code. {%- endblock -%} {% block title %} - {{ admin.isChild and admin.parent.subject ? 'title_edit'|trans({'%name%': admin.parent.toString(admin.parent.subject)|truncate(15) }, 'SonataAdminBundle') : '' }} + {{ admin.isChild and admin.parent.subject ? 'title_edit'|trans({'%name%': admin.parent.toString(admin.parent.subject)|u.truncate(15) }, 'SonataAdminBundle') : '' }} {% endblock %} {% block navbar_title %} - {{ admin.isChild and admin.parent.subject ? 'title_edit'|trans({'%name%': admin.parent.toString(admin.parent.subject)|truncate(100) }, 'SonataAdminBundle') : '' }} + {{ admin.isChild and admin.parent.subject ? 'title_edit'|trans({'%name%': admin.parent.toString(admin.parent.subject)|u.truncate(100) }, 'SonataAdminBundle') : '' }} {% endblock %} {% block list_table %} diff --git a/src/Resources/views/CRUD/base_show.html.twig b/src/Resources/views/CRUD/base_show.html.twig index 6d77916a11..b9d4b8fd91 100644 --- a/src/Resources/views/CRUD/base_show.html.twig +++ b/src/Resources/views/CRUD/base_show.html.twig @@ -12,11 +12,11 @@ file that was distributed with this source code. {% extends base_template %} {% block title %} - {{ 'title_show'|trans({'%name%': admin.toString(object)|truncate(15) }, 'SonataAdminBundle') }} + {{ 'title_show'|trans({'%name%': admin.toString(object)|u.truncate(15) }, 'SonataAdminBundle') }} {% endblock %} {% block navbar_title %} - {{ 'title_show'|trans({'%name%': admin.toString(object)|truncate(100) }, 'SonataAdminBundle') }} + {{ 'title_show'|trans({'%name%': admin.toString(object)|u.truncate(100) }, 'SonataAdminBundle') }} {% endblock %} {%- block actions -%} diff --git a/src/Resources/views/CRUD/list_html.html.twig b/src/Resources/views/CRUD/list_html.html.twig index f002a0e9b9..15aae68d20 100644 --- a/src/Resources/views/CRUD/list_html.html.twig +++ b/src/Resources/views/CRUD/list_html.html.twig @@ -15,7 +15,7 @@ {% deprecated 'The "truncate.separator" option is deprecated since sonata-project/admin-bundle 3.65, to be removed in 4.0. Use "truncate.ellipsis" instead.' %} {% endif %} {% set ellipsis = truncate.ellipsis is defined ? truncate.ellipsis : (truncate.separator is defined ? truncate.separator : '...') %} - {{ value|striptags|sonata_truncate(length, cut == false, ellipsis)|raw }} + {{ value|striptags|u.truncate(length, ellipsis, cut)|raw }} {%- else -%} {%- if field_description.options.strip is defined -%} {% set value = value|striptags %} diff --git a/src/Resources/views/CRUD/list_outer_rows_mosaic.html.twig b/src/Resources/views/CRUD/list_outer_rows_mosaic.html.twig index 3ffb83af31..d7a3405986 100644 --- a/src/Resources/views/CRUD/list_outer_rows_mosaic.html.twig +++ b/src/Resources/views/CRUD/list_outer_rows_mosaic.html.twig @@ -62,7 +62,7 @@ This template can be customized to match your needs. You should only extends the {% endif %} {% block sonata_mosaic_description %} - {{ meta.title|truncate(40) }} + {{ meta.title|u.truncate(40) }} {% endblock %} diff --git a/src/Resources/views/CRUD/show_html.html.twig b/src/Resources/views/CRUD/show_html.html.twig index 748f4bb3ab..1adf6810b6 100644 --- a/src/Resources/views/CRUD/show_html.html.twig +++ b/src/Resources/views/CRUD/show_html.html.twig @@ -15,7 +15,7 @@ {% deprecated 'The "truncate.separator" option is deprecated since sonata-project/admin-bundle 3.65, to be removed in 4.0. Use "truncate.ellipsis" instead.' %} {% endif %} {% set ellipsis = truncate.ellipsis is defined ? truncate.ellipsis : (truncate.separator is defined ? truncate.separator : '...') %} - {{ value|striptags|sonata_truncate(length, cut == false, ellipsis)|raw }} + {{ value|striptags|u.truncate(length, ellipsis, cut)|raw }} {%- else -%} {%- if field_description.options.strip is defined -%} {% set value = value|striptags %} diff --git a/src/Resources/views/standard_layout.html.twig b/src/Resources/views/standard_layout.html.twig index b8bb7ba511..01b3896d07 100644 --- a/src/Resources/views/standard_layout.html.twig +++ b/src/Resources/views/standard_layout.html.twig @@ -173,15 +173,15 @@ file that was distributed with this source code. {% if menu.extra('safe_label', true) %} {{- label|raw -}} {% else %} - {{- label|truncate(100) -}} + {{- label|u.truncate(100) -}} {% endif %} {% else %} - {{ label|truncate(100) }} + {{ label|u.truncate(100) }} {% endif %} {% else %} -
  • {{ label|truncate(100) }}
  • +
  • {{ label|u.truncate(100) }}
  • {% endif %} {% endfor %} {% endif %} diff --git a/src/Twig/Extension/StringExtension.php b/src/Twig/Extension/StringExtension.php index dd4e9a07fc..54c3fe95d7 100644 --- a/src/Twig/Extension/StringExtension.php +++ b/src/Twig/Extension/StringExtension.php @@ -13,12 +13,15 @@ namespace Sonata\AdminBundle\Twig\Extension; -use Symfony\Component\String\UnicodeString as DecoratedUnicodeString; +use Symfony\Component\String\UnicodeString as SymfonyUnicodeString; +use Twig\Environment; use Twig\Extension\AbstractExtension; use Twig\Extensions\TextExtension; use Twig\TwigFilter; /** + * NEXT_MAJOR: Remove this class. + * * Decorates `Twig\Extra\String\StringExtension` in order to provide the `$cut` * argument for `Symfony\Component\String\UnicodeString::truncate()`. * This class must be removed when the component ships this feature. @@ -46,22 +49,34 @@ public function __construct(?TextExtension $legacyExtension = null) */ public function getFilters(): array { + return [ + new TwigFilter('sonata_truncate', [$this, 'deprecatedTruncate'], ['needs_environment' => true]), + ]; + } + + /** + * @return SymfonyUnicodeString|string + */ + public function deprecatedTruncate(Environment $env, ?string $text, int $length = 30, bool $preserve = false, string $ellipsis = '...') + { + @trigger_error( + 'The "sonata_truncate" twig filter is deprecated' + .' since sonata-project/admin-bundle 3.x and will be removed in 4.0. Use "u.truncate" instead.', + E_USER_DEPRECATED + ); + if (null !== $this->legacyExtension) { - return [ - new TwigFilter('sonata_truncate', 'twig_truncate_filter', ['needs_environment' => true]), - ]; + return twig_truncate_filter($env, $text, $length, $preserve, $ellipsis); } - return [ - new TwigFilter('sonata_truncate', [$this, 'legacyTruncteWithUnicodeString']), - ]; + return $this->legacyTruncteWithUnicodeString($text, $length, $preserve, $ellipsis); } /** * NEXT_MAJOR: Fix the arguments in order to respect the signature at `UnicodeString::truncate()`. */ - public function legacyTruncteWithUnicodeString(?string $text, int $length = 30, bool $preserve = false, string $ellipsis = '...'): DecoratedUnicodeString + public function legacyTruncteWithUnicodeString(?string $text, int $length = 30, bool $preserve = false, string $ellipsis = '...'): SymfonyUnicodeString { - return (new UnicodeString($text ?? ''))->truncate($length, $ellipsis, $preserve); + return (new SymfonyUnicodeString($text ?? ''))->truncate($length, $ellipsis, $preserve); } } diff --git a/src/Twig/Extension/UnicodeString.php b/src/Twig/Extension/UnicodeString.php index 63cee9c0ea..ef53178576 100644 --- a/src/Twig/Extension/UnicodeString.php +++ b/src/Twig/Extension/UnicodeString.php @@ -23,6 +23,9 @@ * * @see https://github.com/symfony/symfony/pull/35649 * + * NEXT_MAJOR: Remove this class + * @deprecated since sonata-project/admin-bundle 3.x, use Symfony\Component\String\UnicodeString instead. + * * @throws ExceptionInterface * * @author Javier Spagnoletti diff --git a/tests/Twig/Extension/SonataAdminExtensionTest.php b/tests/Twig/Extension/SonataAdminExtensionTest.php index 2a79163ada..73da831c01 100644 --- a/tests/Twig/Extension/SonataAdminExtensionTest.php +++ b/tests/Twig/Extension/SonataAdminExtensionTest.php @@ -25,7 +25,6 @@ use Sonata\AdminBundle\Tests\Fixtures\Entity\FooToString; use Sonata\AdminBundle\Tests\Fixtures\StubFilesystemLoader; use Sonata\AdminBundle\Twig\Extension\SonataAdminExtension; -use Sonata\AdminBundle\Twig\Extension\StringExtension; use Symfony\Bridge\Twig\AppVariable; use Symfony\Bridge\Twig\Extension\RoutingExtension; use Symfony\Bridge\Twig\Extension\TranslationExtension; @@ -42,7 +41,7 @@ use Symfony\Contracts\Translation\TranslatorInterface; use Twig\Environment; use Twig\Error\LoaderError; -use Twig\Extensions\TextExtension; +use Twig\Extra\String\StringExtension; /** * Test for SonataAdminExtension. @@ -204,7 +203,6 @@ protected function setUp(): void $requestContext = new RequestContext(); $urlGenerator = new UrlGenerator($routeCollection, $requestContext); $this->environment->addExtension(new RoutingExtension($urlGenerator)); - $this->environment->addExtension(new TextExtension()); $this->environment->addExtension(new StringExtension()); // initialize object @@ -2203,7 +2201,7 @@ public function testDeprecatedTextExtension(string $expected, string $type, $val ]); $environment->addExtension($this->twigExtension); $environment->addExtension(new TranslationExtension($this->translator)); - $environment->addExtension(new StringExtension(new TextExtension())); + $environment->addExtension(new StringExtension()); $this->admin ->method('getTemplate') @@ -2250,7 +2248,7 @@ public function getDeprecatedTextExtensionItems(): iterable ]; yield 'custom_length' => [ - 'Data Creating a Template for[...] ', + 'Data Creating a Template[...] ', 'html', '

    Creating a Template for the Field and form

    ', [