diff --git a/src/Twig/Extension/RenderElementExtension.php b/src/Twig/Extension/RenderElementExtension.php index 595f9a6c310..e9fa3fe5d65 100644 --- a/src/Twig/Extension/RenderElementExtension.php +++ b/src/Twig/Extension/RenderElementExtension.php @@ -268,8 +268,9 @@ public function renderRelationElement($element, FieldDescriptionInterface $field if (null === $propertyPath) { // For BC kept associated_tostring option behavior + // NEXT_MAJOR Remove next line. $method = $fieldDescription->getOption('associated_tostring'); - + // NEXT_MAJOR: Remove the "if" part and leave the "else" part if ($method) { @trigger_error( 'Option "associated_tostring" is deprecated since version 2.3 and will be removed in 4.0. Use "associated_property" instead.', diff --git a/src/Twig/Extension/XEditableExtension.php b/src/Twig/Extension/XEditableExtension.php index 3d5ba13fe8b..9650d3a282a 100644 --- a/src/Twig/Extension/XEditableExtension.php +++ b/src/Twig/Extension/XEditableExtension.php @@ -71,14 +71,6 @@ public function getXEditableType(string $type) return $this->xEditableTypeMapping[$type] ?? false; } - /** - * @param string[] $xEditableTypeMapping - */ - public function setXEditableTypeMapping($xEditableTypeMapping) - { - $this->xEditableTypeMapping = $xEditableTypeMapping; - } - /** * Return xEditable choices based on the field description choices options & catalogue options. * With the following choice options: diff --git a/tests/Twig/Extension/RenderElementExtensionTest.php b/tests/Twig/Extension/RenderElementExtensionTest.php index 5e404c929d3..6e601b8bca9 100644 --- a/tests/Twig/Extension/RenderElementExtensionTest.php +++ b/tests/Twig/Extension/RenderElementExtensionTest.php @@ -33,6 +33,8 @@ use Symfony\Component\DependencyInjection\Container; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\PropertyAccess\PropertyAccess; +use Symfony\Component\PropertyAccess\PropertyAccessor; +use Symfony\Component\PropertyAccess\PropertyAccessorInterface; use Symfony\Component\Routing\Generator\UrlGenerator; use Symfony\Component\Routing\Loader\XmlFileLoader; use Symfony\Component\Routing\RequestContext; @@ -50,6 +52,22 @@ final class RenderElementExtensionTest extends TestCase { use ExpectDeprecationTrait; + private const X_EDITABLE_TYPE_MAPPING = [ + 'choice' => 'select', + 'boolean' => 'select', + 'text' => 'text', + 'textarea' => 'textarea', + 'html' => 'textarea', + 'email' => 'email', + 'string' => 'text', + 'smallint' => 'text', + 'bigint' => 'text', + 'integer' => 'number', + 'decimal' => 'number', + 'currency' => 'number', + 'percent' => 'number', + 'url' => 'url', + ]; /** * @var RenderElementExtension @@ -115,23 +133,6 @@ protected function setUp(): void { date_default_timezone_set('Europe/London'); - $xEditableTypeMapping = [ - 'choice' => 'select', - 'boolean' => 'select', - 'text' => 'text', - 'textarea' => 'textarea', - 'html' => 'textarea', - 'email' => 'email', - 'string' => 'text', - 'smallint' => 'text', - 'bigint' => 'text', - 'integer' => 'number', - 'decimal' => 'number', - 'currency' => 'number', - 'percent' => 'number', - 'url' => 'url', - ]; - $container = new Container(); $this->pool = new Pool($container, '', ''); @@ -174,53 +175,13 @@ protected function setUp(): void 'optimizations' => 0, ]); - //NEXT_MAJOR: Remove follwing block - /** - * @var AuthorizationCheckerInterface - */ - $securityChecker = $this->createStub(AuthorizationCheckerInterface::class); - $this->twigExtension = new SonataAdminExtension( - $this->pool, - $this->logger, - $this->translator, - $this->container, - $propertyAccessor, - $securityChecker - ); - $this->twigExtension->setXEditableTypeMapping($xEditableTypeMapping, 'sonata_deprecation_mute'); - $this->environment->addExtension($this->twigExtension); - // block ends - - //NEXT_MAJOR: Uncomment block below - /* $this->twigExtension = new RenderElementExtension( $propertyAccessor, $this->container, $this->logger, ); - $this->environment->addExtension($this->twigExtension); - // xeditable extension - $xEditableExtension = new XEditableExtension($translator, $xEditableTypeMapping); - $xEditableExtension->setXEditableTypeMapping($xEditableTypeMapping); - $this->environment->addExtension($xEditableExtension); - */ - $this->environment->addExtension(new TranslationExtension($translator)); - $this->environment->addExtension(new FakeTemplateRegistryExtension()); - - // routing extension - $xmlFileLoader = new XmlFileLoader(new FileLocator([sprintf('%s/../../../src/Resources/config/routing', __DIR__)])); - $routeCollection = $xmlFileLoader->load('sonata_admin.xml'); - - $xmlFileLoader = new XmlFileLoader(new FileLocator([sprintf('%s/../../Fixtures/Resources/config/routing', __DIR__)])); - - $testRouteCollection = $xmlFileLoader->load('routing.xml'); - - $routeCollection->addCollection($testRouteCollection); - $requestContext = new RequestContext(); - $urlGenerator = new UrlGenerator($routeCollection, $requestContext); - $this->environment->addExtension(new RoutingExtension($urlGenerator)); - $this->environment->addExtension(new StringExtension()); + $this->registerRequiredTwigExtensions($propertyAccessor); // initialize object $this->object = new \stdClass(); @@ -242,12 +203,6 @@ protected function setUp(): void ->with($this->equalTo($this->object)) ->willReturn(12345); - $this->admin - ->method('trans') - ->willReturnCallback(static function ($id, $parameters = [], $domain = null) use ($translator) { - return $translator->trans($id, $parameters, $domain); - }); - $this->adminBar = $this->createMock(AbstractAdmin::class); $this->adminBar ->method('hasAccess') @@ -277,8 +232,9 @@ protected function setUp(): void } /** + * NEXT_MAJOR: Remove legacy group. + * * @group legacy - * @expectedDeprecation The Sonata\AdminBundle\Admin\AbstractAdmin::getTemplate method is deprecated (since sonata-project/admin-bundle 3.34, will be dropped in 4.0. Use TemplateRegistry services instead). * @dataProvider getRenderListElementTests */ public function testRenderListElement(string $expected, string $type, $value, array $options): void @@ -356,6 +312,9 @@ public function testRenderListElement(string $expected, string $type, $value, ar } }); + // NEXT_MAJOR: Remove next line. + $this->expectDeprecation('The Sonata\AdminBundle\Admin\AbstractAdmin::getTemplate method is deprecated (since sonata-project/admin-bundle 3.34, will be dropped in 4.0. Use TemplateRegistry services instead).'); + $this->assertSame( $this->removeExtraWhitespace($expected), $this->removeExtraWhitespace($this->twigExtension->renderListElement( @@ -367,10 +326,9 @@ public function testRenderListElement(string $expected, string $type, $value, ar } /** - * NEXT_MAJOR: Remove @expectedDeprecation. + * NEXT_MAJOR: Remove legacy group. * * @group legacy - * @expectedDeprecation The Sonata\AdminBundle\Admin\AbstractAdmin::getTemplate method is deprecated (since sonata-project/admin-bundle 3.34, will be dropped in 4.0. Use TemplateRegistry services instead). */ public function testRenderListElementWithAdditionalValuesInArray(): void { @@ -387,6 +345,9 @@ public function testRenderListElementWithAdditionalValuesInArray(): void ->method('getTemplate') ->willReturn('@SonataAdmin/CRUD/list_string.html.twig'); + // NEXT_MAJOR: Remove next line. + $this->expectDeprecation('The Sonata\AdminBundle\Admin\AbstractAdmin::getTemplate method is deprecated (since sonata-project/admin-bundle 3.34, will be dropped in 4.0. Use TemplateRegistry services instead).'); + $this->assertSame( $this->removeExtraWhitespace(' Extra value '), $this->removeExtraWhitespace($this->twigExtension->renderListElement( @@ -398,10 +359,9 @@ public function testRenderListElementWithAdditionalValuesInArray(): void } /** - * NEXT_MAJOR: Remove @expectedDeprecation. + * NEXT_MAJOR: Remove legacy group. * * @group legacy - * @expectedDeprecation Accessing a non existing value is deprecated since sonata-project/admin-bundle 3.67 and will throw an exception in 4.0. */ public function testRenderListElementWithNoValueException(): void { @@ -420,6 +380,9 @@ public function testRenderListElementWithNoValueException(): void throw new NoValueException(); }); + // NEXT_MAJOR: Remove next line. + $this->expectDeprecation('Accessing a non existing value for the field "fd_name" is deprecated since sonata-project/admin-bundle 3.67 and will throw an exception in 4.0.'); + $this->assertSame( $this->removeExtraWhitespace(' '), $this->removeExtraWhitespace($this->twigExtension->renderListElement( @@ -431,6 +394,8 @@ public function testRenderListElementWithNoValueException(): void } /** + * NEXT_MAJOR: Remove this method. + * * @dataProvider getDeprecatedRenderListElementTests * @group legacy */ @@ -883,6 +848,8 @@ public function testRenderRelationElementToString(): void } /** + * NEXT_MAJOR: Remove this test. + * * @group legacy */ public function testDeprecatedRelationElementToString(): void @@ -902,44 +869,44 @@ public function testDeprecatedRelationElementToString(): void ); } - /** - * @group legacy - */ public function testRenderRelationElementCustomToString(): void { - $this->fieldDescription->expects($this->exactly(2)) + $this->fieldDescription->expects($this->once()) ->method('getOption') ->willReturnCallback(static function ($value, $default = null) { if ('associated_property' === $value) { - return $default; - } - - if ('associated_tostring' === $value) { return 'customToString'; } }); - $element = $this->getMockBuilder(\stdClass::class) - ->setMethods(['customToString']) - ->getMock(); - $element - ->method('customToString') - ->willReturn('fooBar'); + $element = new class() { + public function customToString(): string + { + return 'fooBar'; + } + }; $this->assertSame('fooBar', $this->twigExtension->renderRelationElement($element, $this->fieldDescription)); } /** + * NEXT_MAJOR: Remove legacy group. + * * @group legacy */ public function testRenderRelationElementMethodNotExist(): void { + // NEXT_MAJOR: change $this->exactly(2) for $this->once() $this->fieldDescription->expects($this->exactly(2)) ->method('getOption') ->willReturnCallback(static function ($value, $default = null) { + if ('associated_property' === $value) { + return null; + } + // NEXT_MAJOR: Remove next block. if ('associated_tostring' === $value) { - return 'nonExistedMethod'; + return null; } }); @@ -950,6 +917,35 @@ public function testRenderRelationElementMethodNotExist(): void $this->twigExtension->renderRelationElement($element, $this->fieldDescription); } + /** + * NEXT_MAJOR: Remove this method. + * + * @group legacy + */ + public function testRenderRelationElementMethodWithDeprecatedAssociatedToString(): void + { + $this->fieldDescription->expects($this->exactly(2)) + ->method('getOption') + ->willReturnCallback(static function ($value, $default = null) { + if ('associated_property' === $value) { + return null; + } + + if ('associated_tostring' === $value) { + return 'customToString'; + } + }); + + $element = new class() { + public function customToString(): string + { + return 'fooBar'; + } + }; + + $this->assertSame('fooBar', $this->twigExtension->renderRelationElement($element, $this->fieldDescription)); + } + public function testRenderRelationElementWithPropertyPath(): void { $this->fieldDescription->expects($this->once()) @@ -989,7 +985,7 @@ public function testRenderRelationElementWithClosure(): void ); } - public function getRenderListElementTests() + public function getRenderListElementTests(): array { return [ [ @@ -1964,7 +1960,8 @@ class="x-editable" ]; } - public function getDeprecatedRenderListElementTests() + // NEXT_MAJOR: Remove this method. + public function getDeprecatedRenderListElementTests(): array { return [ [ @@ -1980,7 +1977,7 @@ public function getDeprecatedRenderListElementTests() ]; } - public function getRenderViewElementTests() + public function getRenderViewElementTests(): array { return [ ['Data Example', 'string', 'Example', ['safe' => false]], @@ -2535,4 +2532,56 @@ private function removeExtraWhitespace(string $string): string $string )); } + + private function registerRequiredTwigExtensions(PropertyAccessorInterface $propertyAccessor): void + { + //NEXT_MAJOR: Remove next line. + $this->registerSonataAdminExtension($propertyAccessor); + + $this->environment->addExtension($this->twigExtension); + $this->environment->addExtension(new XEditableExtension($this->translator, self::X_EDITABLE_TYPE_MAPPING)); + $this->environment->addExtension(new TranslationExtension($this->translator)); + $this->environment->addExtension(new FakeTemplateRegistryExtension()); + $this->environment->addExtension(new StringExtension()); + + $this->registerRoutingExtension(); + } + + /** + * NEXT_MAJOR: Remove this method. + */ + private function registerSonataAdminExtension(PropertyAccessor $propertyAccessor): void + { + $securityChecker = $this->createStub(AuthorizationCheckerInterface::class); + + $sonataAdminExtension = new SonataAdminExtension( + $this->pool, + $this->logger, + $this->translator, + $this->container, + $propertyAccessor, + $securityChecker + ); + $sonataAdminExtension->setXEditableTypeMapping(self::X_EDITABLE_TYPE_MAPPING, 'sonata_deprecation_mute'); + $this->environment->addExtension($sonataAdminExtension); + } + + private function registerRoutingExtension(): void + { + $xmlFileLoader = new XmlFileLoader(new FileLocator([ + sprintf('%s/../../../src/Resources/config/routing', __DIR__), + ])); + $routeCollection = $xmlFileLoader->load('sonata_admin.xml'); + + $xmlFileLoader = new XmlFileLoader(new FileLocator([ + sprintf('%s/../../Fixtures/Resources/config/routing', __DIR__), + ])); + + $testRouteCollection = $xmlFileLoader->load('routing.xml'); + + $routeCollection->addCollection($testRouteCollection); + $requestContext = new RequestContext(); + $urlGenerator = new UrlGenerator($routeCollection, $requestContext); + $this->environment->addExtension(new RoutingExtension($urlGenerator)); + } } diff --git a/tests/Twig/Extension/SonataAdminExtensionTest.php b/tests/Twig/Extension/SonataAdminExtensionTest.php index d0e24c1d388..c175b993575 100644 --- a/tests/Twig/Extension/SonataAdminExtensionTest.php +++ b/tests/Twig/Extension/SonataAdminExtensionTest.php @@ -478,7 +478,7 @@ public function testRenderListElementWithNoValueException(): void { $this->expectDeprecation('The Sonata\AdminBundle\Twig\Extension\SonataAdminExtension::renderListElement method is deprecated in favor of RenderElementExtension::renderListElement since version 3.x and will be removed in 4.0.'); - $this->expectDeprecation('Accessing a non existing value is deprecated since sonata-project/admin-bundle 3.67 and will throw an exception in 4.0.'); + $this->expectDeprecation('Accessing a non existing value for the field "fd_name" is deprecated since sonata-project/admin-bundle 3.67 and will throw an exception in 4.0.'); // NEXT_MAJOR: Remove this line $this->admin