Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Twig] Split SonataAdminExtension #6676

Merged
merged 9 commits into from
Jan 11, 2021
26 changes: 26 additions & 0 deletions UPGRADE-3.x.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,32 @@
UPGRADE 3.x
===========

UPGRADE FROM 3.xx to 3.xx
=========================

### Sonata\AdminBundle\Twig\Extension\SonataAdminExtension

- Deprecated `SonataAdminExtension::MOMENT_UNSUPPORTED_LOCALES` constant.
- Deprecated `SonataAdminExtension::setXEditableTypeMapping()` method.
- Deprecated `SonataAdminExtension::getXEditableType()` method.
- Deprecated `SonataAdminExtension::getXEditableChoices()` method.
- Deprecated `SonataAdminExtension::getCanonicalizedLocaleForMoment()` method in favor of
`CanonicalizerExtension::getCanonicalizedLocaleForMoment()`.
- Deprecated `SonataAdminExtension::getCanonicalizedLocaleForSelect2()` method in favor of
`CanonicalizerExtension::getCanonicalizedLocaleForSelect2()`.
- Deprecated `SonataAdminExtension::isGrantedAffirmative()` method in favor of
`SecurityExtension::isGrantedAffirmative()`.
- Deprecated `SonataAdminExtension::renderListElement()` method in favor of
`RenderElementExtension::renderListElement()`.
- Deprecated `SonataAdminExtension::renderViewElement()` method in favor of
`RenderElementExtension::renderViewElement()`.
- Deprecated `SonataAdminExtension::renderViewElementCompare()` method in favor of
`RenderElementExtension::renderViewElementCompare()`.
- Deprecated `SonataAdminExtension::renderRelationElement()` method in favor of
`RenderElementExtension::renderRelationElement()`.
- Deprecated `SonataAdminExtension::getTemplate()` method.
- Deprecated `SonataAdminExtension::getTemplateRegistry()` method.

UPGRADE FROM 3.85 to 3.86
=========================

Expand Down
4 changes: 3 additions & 1 deletion src/Action/SetObjectFieldValueAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -206,10 +206,12 @@ public function __invoke(Request $request): JsonResponse

// render the widget
// todo : fix this, the twig environment variable is not set inside the extension ...
// NEXT_MAJOR: Modify lines below to use RenderElementExtension instead of SonataAdminExtension
$extension = $this->twig->getExtension(SonataAdminExtension::class);
\assert($extension instanceof SonataAdminExtension);

$content = $extension->renderListElement($this->twig, $rootObject, $fieldDescription);
// NEXT_MAJOR: Remove the last two arguments
$content = $extension->renderListElement($this->twig, $rootObject, $fieldDescription, [], 'sonata_deprecation_mute');

return new JsonResponse($content, Response::HTTP_OK);
}
Expand Down
36 changes: 36 additions & 0 deletions src/Resources/config/twig.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,14 @@
* file that was distributed with this source code.
*/

use Sonata\AdminBundle\Twig\Extension\CanonicalizeExtension;
use Sonata\AdminBundle\Twig\Extension\GroupExtension;
use Sonata\AdminBundle\Twig\Extension\PaginationExtension;
use Sonata\AdminBundle\Twig\Extension\RenderElementExtension;
use Sonata\AdminBundle\Twig\Extension\SecurityExtension;
use Sonata\AdminBundle\Twig\Extension\SonataAdminExtension;
use Sonata\AdminBundle\Twig\Extension\TemplateRegistryExtension;
use Sonata\AdminBundle\Twig\Extension\XEditableExtension;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Symfony\Component\DependencyInjection\Loader\Configurator\ReferenceConfigurator;

Expand Down Expand Up @@ -49,14 +53,19 @@
->tag('twig.extension')
->args([
new ReferenceConfigurator('sonata.admin.pool'),
// NEXT_MAJOR: Remove next line.
(new ReferenceConfigurator('logger'))->nullOnInvalid(),
// NEXT_MAJOR: Remove next line.
new ReferenceConfigurator('translator'),
new ReferenceConfigurator('service_container'),
new ReferenceConfigurator('property_accessor'),
// NEXT_MAJOR: Remove next line.
new ReferenceConfigurator('security.authorization_checker'),
])
// NEXT_MAJOR: Remove next call.
->call('setXEditableTypeMapping', [
franmomu marked this conversation as resolved.
Show resolved Hide resolved
'%sonata.admin.twig.extension.x_editable_type_mapping%',
'sonata_deprecation_mute',
])

->set('sonata.templates.twig.extension', TemplateRegistryExtension::class)
Expand All @@ -75,5 +84,32 @@
// NEXT_MAJOR: Remove this service.
->set('sonata.pagination.twig.extension', PaginationExtension::class)
->tag('twig.extension')

->set('sonata.security.twig.extension', SecurityExtension::class)
->tag('twig.extension')
->args([
new ReferenceConfigurator('security.authorization_checker'),
])

->set('sonata.canonicalize.twig.extension', CanonicalizeExtension::class)
->tag('twig.extension')
->args([
new ReferenceConfigurator('request_stack'),
])

->set('sonata.xeditable.twig.extension', XEditableExtension::class)
->tag('twig.extension')
->args([
new ReferenceConfigurator('translator'),
'%sonata.admin.twig.extension.x_editable_type_mapping%',
])

->set('sonata.render_element.twig.extension', RenderElementExtension::class)
->tag('twig.extension')
->args([
new ReferenceConfigurator('property_accessor'),
new ReferenceConfigurator('service_container'),
(new ReferenceConfigurator('logger'))->nullOnInvalid(),
])
;
};
108 changes: 108 additions & 0 deletions src/Twig/Extension/CanonicalizeExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
<?php

declare(strict_types=1);

/*
* This file is part of the Sonata Project package.
*
* (c) Thomas Rabaix <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Sonata\AdminBundle\Twig\Extension;

use Symfony\Component\HttpFoundation\RequestStack;
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;

final class CanonicalizeExtension extends AbstractExtension
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new classes contain only dead code that will never be executed in the current stable release. Either do this change on the next major branch or try to bridge this code in the old extensions

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea was to bridge the code, this is how it is looking like:

final public function getCanonicalizedLocaleForMoment(array $context)
{
if ('sonata_deprecation_mute' !== (\func_get_args()[1] ?? null)) {
@trigger_error(sprintf(
'The %s method is deprecated in favor of CanonicalizeExtension::getCanonicalizedLocaleForMoment since version 3.x and will be removed in 4.0.',
__METHOD__
), E_USER_DEPRECATED);
}
if (null === $this->canonicalizeExtension) {
$requestStack = new RequestStack();
$requestStack->push($context['app']->getRequest());
$this->canonicalizeExtension = new CanonicalizeExtension($requestStack);
}
return $this->canonicalizeExtension->getCanonicalizedLocaleForMoment();
}

{
// @todo: there are more locales which are not supported by moment and they need to be translated/normalized/canonicalized here
private const MOMENT_UNSUPPORTED_LOCALES = [
'de' => ['de', 'de-at'],
'es' => ['es', 'es-do'],
'nl' => ['nl', 'nl-be'],
'fr' => ['fr', 'fr-ca', 'fr-ch'],
];

/**
* @var RequestStack
*/
private $requestStack;

/**
* @internal This class should only be used through Twig
*/
public function __construct(RequestStack $requestStack)
franmomu marked this conversation as resolved.
Show resolved Hide resolved
{
$this->requestStack = $requestStack;
}

/**
* @return TwigFunction[]
*/
public function getFunctions(): array
{
return [
//NEXT_MAJOR: Uncomment lines below
//new TwigFunction('canonicalize_locale_for_moment', [$this, 'getCanonicalizedLocaleForMoment']),
//new TwigFunction('canonicalize_locale_for_select2', [$this, 'getCanonicalizedLocaleForSelect2']),
];
}

/*
* Returns a canonicalized locale for "moment" NPM library,
* or `null` if the locale's language is "en", which doesn't require localization.
*/
public function getCanonicalizedLocaleForMoment(): ?string
{
$locale = strtolower(str_replace('_', '-', $this->requestStack->getCurrentRequest()->getLocale()));

// "en" language doesn't require localization.
if (('en' === $lang = substr($locale, 0, 2)) && !\in_array($locale, ['en-au', 'en-ca', 'en-gb', 'en-ie', 'en-nz'], true)) {
return null;
}

foreach (self::MOMENT_UNSUPPORTED_LOCALES as $language => $locales) {
if ($language === $lang && !\in_array($locale, $locales, true)) {
$locale = $language;
}
}

return $locale;
}

/**
* Returns a canonicalized locale for "select2" NPM library,
* or `null` if the locale's language is "en", which doesn't require localization.
*/
public function getCanonicalizedLocaleForSelect2(): ?string
{
$locale = str_replace('_', '-', $this->requestStack->getCurrentRequest()->getLocale());

// "en" language doesn't require localization.
if ('en' === $lang = substr($locale, 0, 2)) {
return null;
}

switch ($locale) {
case 'pt':
$locale = 'pt-PT';
break;
case 'ug':
$locale = 'ug-CN';
break;
case 'zh':
$locale = 'zh-CN';
break;
default:
if (!\in_array($locale, ['pt-BR', 'pt-PT', 'ug-CN', 'zh-CN', 'zh-TW'], true)) {
$locale = $lang;
}
}

return $locale;
}
}
Loading