Skip to content

Commit

Permalink
[Task]: Replace SensioFrameworkExtraBundle with PHP 8 attribute (pimc…
Browse files Browse the repository at this point in the history
…ore#14062)

* Replace SensioFrameworkExtraBundle with PHP 8 attribute - resolves pimcore#13958

Co-authored-by: JiaJia Ji <[email protected]>
Co-authored-by: Sebastian Blank <[email protected]>
  • Loading branch information
3 people authored Feb 7, 2023
1 parent ac85677 commit 38d5e89
Show file tree
Hide file tree
Showing 19 changed files with 164 additions and 237 deletions.
2 changes: 1 addition & 1 deletion .github/ci/scripts/symfony-require-dev.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

set -eu

composer require --no-update symfony/asset:${SYMFONY_VERSION} symfony/cache:${SYMFONY_VERSION} symfony/doctrine-messenger:${SYMFONY_VERSION} symfony/config:${SYMFONY_VERSION} symfony/console:${SYMFONY_VERSION} symfony/dependency-injection:${SYMFONY_VERSION} symfony/debug-bundle:${SYMFONY_VERSION} symfony/dom-crawler:${SYMFONY_VERSION} symfony/error-handler:${SYMFONY_VERSION} symfony/event-dispatcher:${SYMFONY_VERSION} symfony/expression-language:${SYMFONY_VERSION} symfony/filesystem:${SYMFONY_VERSION} symfony/finder:${SYMFONY_VERSION} symfony/form:${SYMFONY_VERSION} symfony/framework-bundle:${SYMFONY_VERSION} symfony/http-foundation:${SYMFONY_VERSION} symfony/http-kernel:${SYMFONY_VERSION} symfony/lock:${SYMFONY_VERSION} symfony/mailer:${SYMFONY_VERSION} symfony/messenger:${SYMFONY_VERSION} symfony/mime:${SYMFONY_VERSION} symfony/options-resolver:${SYMFONY_VERSION} symfony/password-hasher:${SYMFONY_VERSION} symfony/process:${SYMFONY_VERSION} symfony/property-access:${SYMFONY_VERSION} symfony/rate-limiter:${SYMFONY_VERSION} symfony/routing:${SYMFONY_VERSION} symfony/security-bundle:${SYMFONY_VERSION} symfony/security-core:${SYMFONY_VERSION} symfony/security-http:${SYMFONY_VERSION} symfony/serializer:${SYMFONY_VERSION} symfony/stopwatch:${SYMFONY_VERSION} symfony/templating:${SYMFONY_VERSION} symfony/translation:${SYMFONY_VERSION} symfony/twig-bridge:${SYMFONY_VERSION} symfony/twig-bundle:${SYMFONY_VERSION} symfony/uid:${SYMFONY_VERSION} symfony/validator:${SYMFONY_VERSION} symfony/var-dumper:${SYMFONY_VERSION} symfony/web-link:${SYMFONY_VERSION} symfony/web-profiler-bundle:${SYMFONY_VERSION} symfony/workflow:${SYMFONY_VERSION} symfony/yaml:${SYMFONY_VERSION}
composer require --no-update symfony/asset:${SYMFONY_VERSION} symfony/cache:${SYMFONY_VERSION} symfony/doctrine-messenger:${SYMFONY_VERSION} symfony/config:${SYMFONY_VERSION} symfony/console:${SYMFONY_VERSION} symfony/dependency-injection:${SYMFONY_VERSION} symfony/debug-bundle:${SYMFONY_VERSION} symfony/dom-crawler:${SYMFONY_VERSION} symfony/error-handler:${SYMFONY_VERSION} symfony/event-dispatcher:${SYMFONY_VERSION} symfony/expression-language:${SYMFONY_VERSION} symfony/filesystem:${SYMFONY_VERSION} symfony/finder:${SYMFONY_VERSION} symfony/form:${SYMFONY_VERSION} symfony/framework-bundle:${SYMFONY_VERSION} symfony/http-foundation:${SYMFONY_VERSION} symfony/http-kernel:${SYMFONY_VERSION} symfony/lock:${SYMFONY_VERSION} symfony/mailer:${SYMFONY_VERSION} symfony/messenger:${SYMFONY_VERSION} symfony/mime:${SYMFONY_VERSION} symfony/options-resolver:${SYMFONY_VERSION} symfony/password-hasher:${SYMFONY_VERSION} symfony/process:${SYMFONY_VERSION} symfony/property-access:${SYMFONY_VERSION} symfony/rate-limiter:${SYMFONY_VERSION} symfony/routing:${SYMFONY_VERSION} symfony/security-bundle:${SYMFONY_VERSION} symfony/security-core:${SYMFONY_VERSION} symfony/security-http:${SYMFONY_VERSION} symfony/serializer:${SYMFONY_VERSION} symfony/stopwatch:${SYMFONY_VERSION} symfony/templating:${SYMFONY_VERSION} symfony/translation:${SYMFONY_VERSION} symfony/doctrine-bridge:${SYMFONY_VERSION} symfony/twig-bridge:${SYMFONY_VERSION} symfony/twig-bundle:${SYMFONY_VERSION} symfony/uid:${SYMFONY_VERSION} symfony/validator:${SYMFONY_VERSION} symfony/var-dumper:${SYMFONY_VERSION} symfony/web-link:${SYMFONY_VERSION} symfony/web-profiler-bundle:${SYMFONY_VERSION} symfony/workflow:${SYMFONY_VERSION} symfony/yaml:${SYMFONY_VERSION}
2 changes: 1 addition & 1 deletion .github/workflows/codeception.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ jobs:
strategy:
matrix:
include:
- { php-version: 8.1, database: "mariadb:10.6", dependencies: highest, experimental: true, storage: local, symfony: "6.2.x-dev", composer-options: "" }
- { php-version: 8.1, database: "mariadb:10.6", dependencies: highest, experimental: true, storage: local, symfony: "6.3.x-dev", composer-options: "" }
- { php-version: 8.1, database: "mariadb:10.7", dependencies: highest, experimental: false, storage: local, symfony: "", composer-options: "" }
- { php-version: 8.1, database: "mariadb:10.3", dependencies: lowest, experimental: false, storage: local, symfony: "", composer-options: "" }
- { php-version: 8.1, database: "mysql:8.0", dependencies: lowest, experimental: false, storage: local, symfony: "", composer-options: "" }
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/static-analysis.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ jobs:
include:
- { php-version: "8.1", dependencies: "lowest", experimental: false, symfony: "", composer-options: "" }
- { php-version: "8.1", dependencies: "highest", experimental: false, symfony: "", composer-options: "" }
- { php-version: "8.1", dependencies: "highest", experimental: true, symfony: "6.2.x-dev", composer-options: "" }
- { php-version: "8.1", dependencies: "highest", experimental: true, symfony: "6.3.x-dev", composer-options: "" }

steps:
- name: "Checkout code"
Expand Down
4 changes: 0 additions & 4 deletions bundles/CoreBundle/config/pimcore/default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,3 @@ presta_sitemap:
lastmod: ~
priority: ~
changefreq: ~

sensio_framework_extra:
router:
annotations: false
2 changes: 1 addition & 1 deletion bundles/CoreBundle/config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ services:
public: true
class: Pimcore\Model\DataObject\QuantityValue\DefaultConverter

Pimcore\Bundle\CoreBundle\Request\ParamConverter\DataObjectParamResolver:
Pimcore\Bundle\CoreBundle\Request\ParamResolver\DataObjectParamResolver:
tags:
- { name: controller.argument_value_resolver, priority: 101}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,15 @@
use Pimcore\Bundle\CoreBundle\EventListener\Traits\PimcoreContextAwareTrait;
use Pimcore\Http\Request\Resolver\PimcoreContextResolver;
use Pimcore\Http\Request\Resolver\TemplateResolver;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Bridge\Twig\Attribute\Template;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\HttpKernel\Event\ControllerArgumentsEvent;
use Symfony\Component\HttpKernel\Event\ViewEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Twig\Environment;

/**
* If a contentTemplate attribute was set on the request (done by router when building a document route), extract the
Expand All @@ -34,7 +39,7 @@ class ContentTemplateListener implements EventSubscriberInterface
{
use PimcoreContextAwareTrait;

public function __construct(protected TemplateResolver $templateResolver)
public function __construct(protected TemplateResolver $templateResolver, protected Environment $twig)
{
}

Expand Down Expand Up @@ -63,10 +68,9 @@ public function onKernelView(ViewEvent $event): void
return;
}

$template = $request->attributes->get('_template');
$attribute = $event->controllerArgumentsEvent?->getAttributes()[Template::class][0] ?? null;

// no @Template present -> nothing to do
if (null === $template || !($template instanceof Template)) {
if (!$attribute instanceof Template) {
return;
}

Expand All @@ -76,6 +80,37 @@ public function onKernelView(ViewEvent $event): void
return;
}

$template->setTemplate($resolvedTemplate);
$parameters = $this->resolveParameters($event->controllerArgumentsEvent, $attribute->vars);
$status = 200;

foreach ($parameters as $k => $v) {
if (!$v instanceof FormInterface) {
continue;
}
if ($v->isSubmitted() && !$v->isValid()) {
$status = 422;
}
$parameters[$k] = $v->createView();
}

$event->setResponse($attribute->stream
? new StreamedResponse(fn () => $this->twig->display($resolvedTemplate, $parameters), $status)
: new Response($this->twig->render($resolvedTemplate, $parameters), $status)
);
}

private function resolveParameters(ControllerArgumentsEvent $event, ?array $vars): array
{
if ([] === $vars) {
return [];
}

$parameters = $event->getNamedArguments();

if (null !== $vars) {
$parameters = array_intersect_key($parameters, array_flip($vars));
}

return $parameters;
}
}
23 changes: 16 additions & 7 deletions bundles/CoreBundle/src/EventListener/ResponseHeaderListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use Pimcore\Controller\Attribute\ResponseHeader;
use Pimcore\Http\Request\Resolver\ResponseHeaderResolver;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ControllerArgumentsEvent;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;

Expand All @@ -38,6 +39,7 @@ public function __construct(private ResponseHeaderResolver $responseHeaderResolv
public static function getSubscribedEvents(): array
{
return [
KernelEvents::CONTROLLER_ARGUMENTS => ['onKernelControllerArguments', 10],
KernelEvents::RESPONSE => ['onKernelResponse', 32],
];
}
Expand All @@ -52,14 +54,21 @@ public function onKernelResponse(ResponseEvent $event): void

$response = $event->getResponse();
foreach ($headers as $header) {
if (!$header instanceof ResponseHeader) {
trigger_deprecation(
'pimcore/pimcore',
'10.6',
'Usage of @ResponseHeader annotation is deprecated. please use #[ResponseHeader] attribute instead.'
);
if ($header instanceof ResponseHeader) {
$response->headers->set($header->getKey(), $header->getValues(), $header->getReplace());
}
$response->headers->set($header->getKey(), $header->getValues(), $header->getReplace());
}
}

public function onKernelControllerArguments(ControllerArgumentsEvent $event): void
{
$request = $event->getRequest();
if (!\is_array($attributes = $event->getAttributes()[ResponseHeader::class] ?? null)) {
return;
}

$responseHeaders = array_merge($this->responseHeaderResolver->getResponseHeaders($request), $attributes);

$request->attributes->set($this->responseHeaderResolver::ATTRIBUTE_RESPONSE_HEADER, $responseHeaders);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,21 @@
* @license http://www.pimcore.org/license GPLv3 and PCL
*/

namespace Pimcore\Bundle\CoreBundle\Request\ParamConverter;
namespace Pimcore\Bundle\CoreBundle\Request\ParamResolver;

use Pimcore\Model\DataObject\AbstractObject;
use Pimcore\Model\DataObject\Concrete;
use Pimcore\Request\Attribute\DataObjectParam;
use Pimcore\Tool;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface;
use Symfony\Component\HttpKernel\Controller\ValueResolverInterface;
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

/**
* @internal
*/
class DataObjectParamResolver implements ArgumentValueResolverInterface
class DataObjectParamResolver implements ValueResolverInterface
{
/**
* {@inheritdoc}
Expand All @@ -40,19 +39,6 @@ public function resolve(Request $request, ArgumentMetadata $argument): iterable
{
$options = $argument->getAttributes(DataObjectParam::class, ArgumentMetadata::IS_INSTANCEOF);

if (!isset($options[0])) {
$converters = $request->attributes->get('_converters');
$converter = $converters[0] ?? false;
if ($converter instanceof ParamConverter) {
trigger_deprecation(
'pimcore/pimcore',
'10.6',
'Usage of @ParamConverter annotation is deprecated. please use #[DataObjectParam] argument attribute instead.'
);
$options[0] = new DataObjectParam($converter->getClass(), $converter->getOptions()['unpublished'] ?? null, $converter->getOptions());
}
}

$class = $options[0]->class ?? $argument->getType();
if (null === $class || !is_subclass_of($class, AbstractObject::class)) {
return [];
Expand All @@ -67,7 +53,6 @@ public function resolve(Request $request, ArgumentMetadata $argument): iterable

if (!$value && $argument->isNullable()) {
$request->attributes->set($param, null);

return [];
}

Expand All @@ -87,13 +72,4 @@ public function resolve(Request $request, ArgumentMetadata $argument): iterable

return [$object];
}

public function supports(Request $request, ArgumentMetadata $argument)
{
if (null === $argument->getType()) {
return false;
}

return is_subclass_of($argument->getType(), AbstractObject::class);
}
}
90 changes: 45 additions & 45 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
"doctrine/doctrine-bundle": "^2.6.3",
"doctrine/doctrine-migrations-bundle": "^3.2.2",
"doctrine/inflector": "^2.0.2",
"symfony/doctrine-messenger": "^6.1",
"symfony/doctrine-messenger": "^6.2",
"egulias/email-validator": "^3.0.0",
"endroid/qr-code": "^4",
"friendsofsymfony/jsrouting-bundle": "^3.2.1",
Expand All @@ -76,53 +76,53 @@
"matomo/device-detector": "^6.0",
"presta/sitemap-bundle": "^3.3",
"sabre/dav": "^4.1.2",
"sensio/framework-extra-bundle": "^6.2",
"sensiolabs/ansi-to-html": "^1.1",
"symfony-cmf/routing-bundle": "^3.0",
"symfony/contracts": "^3.2",
"symfony/monolog-bundle": "^3.8",
"symfony/asset": "^6.1",
"symfony/cache": "^6.1",
"symfony/config": "^6.1",
"symfony/console": "^6.1",
"symfony/dependency-injection": "^6.1",
"symfony/debug-bundle": "^6.1",
"symfony/dom-crawler": "^6.1",
"symfony/error-handler": "^6.1",
"symfony/event-dispatcher": "^6.1",
"symfony/expression-language": "^6.1",
"symfony/filesystem": "^6.1",
"symfony/finder": "^6.1",
"symfony/form": "^6.1",
"symfony/framework-bundle": "^6.1",
"symfony/http-foundation": "^6.1",
"symfony/http-kernel": "^6.1",
"symfony/lock": "^6.1",
"symfony/mailer": "^6.1",
"symfony/messenger": "^6.1",
"symfony/mime": "^6.1",
"symfony/options-resolver": "^6.1",
"symfony/password-hasher": "^6.1",
"symfony/process": "^6.1",
"symfony/property-access": "^6.1",
"symfony/rate-limiter": "^6.1",
"symfony/routing": "^6.1",
"symfony/security-bundle": "^6.1",
"symfony/security-core": "^6.1",
"symfony/security-http": "^6.1",
"symfony/serializer": "^6.1",
"symfony/stopwatch": "^6.1",
"symfony/templating": "^6.1",
"symfony/translation": "^6.1",
"symfony/twig-bridge": "^6.1",
"symfony/twig-bundle": "^6.1",
"symfony/uid": "^6.1",
"symfony/validator": "^6.1",
"symfony/var-dumper": "^6.1",
"symfony/web-link": "^6.1",
"symfony/web-profiler-bundle": "^6.1",
"symfony/workflow": "^6.1",
"symfony/yaml": "^6.1",
"symfony/asset": "^6.2",
"symfony/cache": "^6.2",
"symfony/config": "^6.2",
"symfony/console": "^6.2",
"symfony/dependency-injection": "^6.2",
"symfony/debug-bundle": "^6.2",
"symfony/dom-crawler": "^6.2",
"symfony/error-handler": "^6.2",
"symfony/event-dispatcher": "^6.2",
"symfony/expression-language": "^6.2",
"symfony/filesystem": "^6.2",
"symfony/finder": "^6.2",
"symfony/form": "^6.2",
"symfony/framework-bundle": "^6.2",
"symfony/http-foundation": "^6.2",
"symfony/http-kernel": "^6.2",
"symfony/lock": "^6.2",
"symfony/mailer": "^6.2",
"symfony/messenger": "^6.2",
"symfony/mime": "^6.2",
"symfony/options-resolver": "^6.2",
"symfony/password-hasher": "^6.2",
"symfony/process": "^6.2",
"symfony/property-access": "^6.2",
"symfony/rate-limiter": "^6.2",
"symfony/routing": "^6.2",
"symfony/security-bundle": "^6.2",
"symfony/security-core": "^6.2",
"symfony/security-http": "^6.2",
"symfony/serializer": "^6.2",
"symfony/stopwatch": "^6.2",
"symfony/templating": "^6.2",
"symfony/translation": "^6.2",
"symfony/doctrine-bridge": "^6.2",
"symfony/twig-bridge": "^6.2",
"symfony/twig-bundle": "^6.2",
"symfony/uid": "^6.2",
"symfony/validator": "^6.2",
"symfony/var-dumper": "^6.2",
"symfony/web-link": "^6.2",
"symfony/web-profiler-bundle": "^6.2",
"symfony/workflow": "^6.2",
"symfony/yaml": "^6.2",
"tijsverkoyen/css-to-inline-styles": "^2.2.3",
"twig/extra-bundle": "^3.4.0",
"twig/twig": "^3.3.9",
Expand Down Expand Up @@ -158,7 +158,7 @@
"composer/composer": "*",
"chrome-php/chrome": "^1.4.0",
"webmozarts/console-parallelization": "^2.1",
"symfony/dotenv": "^6.1"
"symfony/dotenv": "^6.2"
},
"suggest": {
"ext-sockets": "*",
Expand Down
8 changes: 2 additions & 6 deletions doc/Development_Documentation/02_MVC/00_Controller.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,8 @@ In controllers, for every action there exists a separate method ending with the
The `DefaultController` comes with Pimcore. When you create an empty page in Pimcore it will call
the `defaultAction` in the `DefaultController` which uses the view `/templates/default/default.html.twig`.

You can render templates just the [standard Symfony way](https://symfony.com/doc/current/templates.html#rendering-a-template-in-emails), either by using:
- the render helper eg. `$this->render('foo.html.twig')`
- the `@Template()` [annotation](https://symfony.com/bundles/SensioFrameworkExtraBundle/current/annotations/view.html), altough this is deprecated and will not be supported in Pimcore 11.
- the `#Template[]` [attribute](https://symfony.com/doc/current/templates.html#rendering-a-template-in-controllers).
You can render templates just the [standard Symfony way](https://symfony.com/doc/current/templates.html#rendering-a-template-in-emails), by either using `$this->render('foo.html.twig')` or using the `#Template[]` [attribute](https://symfony.com/doc/current/templates.html#rendering-a-template-in-controllers).


### Examples

Expand Down Expand Up @@ -55,8 +53,6 @@ class DefaultController extends FrontendController
* The frontend controller also provides methods to add response headers or via attributes without having
* access to the final response object (as it is automatically created when rendering the view).
*
* @Template
* @ResponseHeader("X-Foo", values={"123456", "98765"})
*/
#[Template('/default/header.html.twig')]
#[ResponseHeader(key: "X-Foo", values: ["123456", "98765"])]
Expand Down
2 changes: 1 addition & 1 deletion doc/Development_Documentation/02_MVC/02_Template/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class MyController extends FrontendController
*/
#[Template('content/default.html.twig', vars: ['param1' => 'value1'])]
public function attributeAction()
{
{
}

public function directRenderAction()
Expand Down
Loading

0 comments on commit 38d5e89

Please sign in to comment.