Skip to content

Commit

Permalink
Merge branch 'PrestaShop:develop' into 35591-b9-migrated-attribute-pa…
Browse files Browse the repository at this point in the history
…ges-bug-9
  • Loading branch information
mattgoud authored Apr 24, 2024
2 parents 67b87c7 + 465e6c2 commit 35ae4cf
Show file tree
Hide file tree
Showing 22 changed files with 342 additions and 73 deletions.
66 changes: 62 additions & 4 deletions app/config/admin/services.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
# Dedicated services for Admin app
parameters:
# All admin context listeners should be executed before the router listener, this way even if no symfony route is found they context are initialized
# We set priorities lower than the RouterListener (32) so that the LegacyRouterChecker class is called first.
# The correct behaviour of Context Listeners on legacy routes depends on LegacyRouterChecker.
employee_listener_priority: 31
language_listener_priority: 30
default_listener_priority: 29
# All admin context listeners should be executed before the router listener, this way even if no symfony route is found the contexts are initialized correctly
# and can be used in admin legacy pages as well (router listener priority is 32)
employee_listener_priority: 35
language_listener_priority: 34
default_listener_priority: 33
legacy_employee_listener_priority: 35
legacy_language_listener_priority: 34
legacy_default_listener_priority: 33

services:
_defaults:
Expand Down Expand Up @@ -75,26 +80,79 @@ services:

# Employee context must have a higher priority because Shop and Language depend on it
PrestaShopBundle\EventListener\Admin\Context\EmployeeContextListener:
arguments:
$isSymfonyLayout: true
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest, priority: '%employee_listener_priority%' }

PrestaShopBundle\EventListener\Admin\Context\EmployeeContextListener.legacy:
class: PrestaShopBundle\EventListener\Admin\Context\EmployeeContextListener
arguments:
$isSymfonyLayout: false
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest, priority: '%legacy_employee_listener_priority%' }

PrestaShopBundle\EventListener\Admin\Context\DefaultLanguageContextListener:
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest, priority: '%legacy_language_listener_priority%' }

# Language depends on Employee so its priority is lower, however it has higher priority than Currency and Country because they depend on Language
PrestaShopBundle\EventListener\Admin\Context\LanguageContextListener:
arguments:
$isSymfonyLayout: true
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest, priority: '%language_listener_priority%' }

PrestaShopBundle\EventListener\Admin\Context\LanguageContextListener.legacy:
class: PrestaShopBundle\EventListener\Admin\Context\LanguageContextListener
arguments:
$isSymfonyLayout: false
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest, priority: '%legacy_language_listener_priority%' }

PrestaShopBundle\EventListener\Admin\Context\DefaultShopContextListener:
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest, priority: '%legacy_default_listener_priority%' }

PrestaShopBundle\EventListener\Admin\Context\ShopContextListener:
arguments:
$isSymfonyLayout: true
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest, priority: '%default_listener_priority%' }

PrestaShopBundle\EventListener\Admin\Context\ShopContextListener.legacy:
class: PrestaShopBundle\EventListener\Admin\Context\ShopContextListener
arguments:
$isSymfonyLayout: false
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest, priority: '%legacy_default_listener_priority%' }

PrestaShopBundle\EventListener\Admin\Context\CurrencyContextListener:
arguments:
$isSymfonyLayout: true
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest, priority: '%default_listener_priority%' }

PrestaShopBundle\EventListener\Admin\Context\CurrencyContextListener.legacy:
class: PrestaShopBundle\EventListener\Admin\Context\CurrencyContextListener
arguments:
$isSymfonyLayout: false
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest, priority: '%legacy_default_listener_priority%' }

PrestaShopBundle\EventListener\Admin\Context\CountryContextListener:
arguments:
$isSymfonyLayout: true
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest, priority: '%default_listener_priority%' }

PrestaShopBundle\EventListener\Admin\Context\CountryContextListener.legacy:
class: PrestaShopBundle\EventListener\Admin\Context\CountryContextListener
arguments:
$isSymfonyLayout: false
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest, priority: '%legacy_default_listener_priority%' }

# This listener must run after the router listener since it's based on the request attributes that are defined by the router
PrestaShopBundle\EventListener\Admin\Context\LegacyControllerContextListener:
tags:
Expand Down
2 changes: 1 addition & 1 deletion classes/controller/AdminController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4395,7 +4395,7 @@ protected function setAllowAnonymous($value)
*
* @return bool
*/
protected function isAnonymousAllowed()
public function isAnonymousAllowed()
{
return $this->allowAnonymous;
}
Expand Down
5 changes: 3 additions & 2 deletions src/Adapter/Security/Admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@

use Context;
use PrestaShop\PrestaShop\Adapter\LegacyContext;
use PrestaShopBundle\Routing\LegacyControllerConstants;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\HttpKernelInterface;
Expand Down Expand Up @@ -89,7 +89,8 @@ public function __construct(
*/
public function onKernelRequest(RequestEvent $event): void
{
if ($this->security->getUser() !== null) {
$publicLegacyRoute = $event->getRequest()->attributes->get(LegacyControllerConstants::ANONYMOUS_ATTRIBUTE);
if ($this->security->getUser() !== null || $publicLegacyRoute) {
return;
}

Expand Down
6 changes: 6 additions & 0 deletions src/Core/Context/LegacyControllerContextBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,12 @@ public function build(): LegacyControllerContext

public function buildLegacyContext(): void
{
// In legacy pages the AdminController class already sets the context's controller, which is a more accurate
// candidate than our facade meant for backward compatibility, so we leave it untouched
if ($this->contextStateManager->getContext()->controller) {
return;
}

$this->assertArguments();

if (null === $this->_legacyControllerContext) {
Expand Down
42 changes: 9 additions & 33 deletions src/PrestaShopBundle/Controller/Admin/LegacyController.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
use PrestaShop\PrestaShop\Core\ConfigurationInterface;
use PrestaShop\PrestaShop\Core\Exception\CoreException;
use PrestaShopBundle\Entity\Repository\TabRepository;
use PrestaShopBundle\Routing\LegacyRouterChecker;
use PrestaShopBundle\Routing\LegacyControllerConstants;
use PrestaShopBundle\Twig\Layout\MenuBuilder;
use PrestaShopBundle\Twig\Layout\SmartyVariablesFiller;
use SmartyException;
Expand Down Expand Up @@ -84,11 +84,11 @@ public function legacyPageAction(Request $request): Response
// These parameters have already been set as request attributes by LegacyRouterChecker
$dispatcherHookParameters = [
'controller_type' => Dispatcher::FC_ADMIN,
'controller_class' => $request->attributes->get(LegacyRouterChecker::LEGACY_CONTROLLER_CLASS_ATTRIBUTE),
'is_module' => $request->attributes->get(LegacyRouterChecker::LEGACY_CONTROLLER_IS_MODULE_ATTRIBUTE),
'controller_class' => $request->attributes->get(LegacyControllerConstants::CLASS_ATTRIBUTE),
'is_module' => $request->attributes->get(LegacyControllerConstants::IS_MODULE_ATTRIBUTE),
];

$adminController = $this->initController($dispatcherHookParameters);
$adminController = $this->initController($request, $dispatcherHookParameters);
// Redirect if necessary after post process
if (!empty($adminController->getRedirectAfter())) {
// After each request the cookie must be written to save its modified state during AdminController workflow
Expand Down Expand Up @@ -196,30 +196,8 @@ protected function renderAjaxController(AdminController $adminController, string
} elseif (method_exists($adminController, 'displayAjax')) {
$adminController->displayAjax();
}
$outputContent = ob_get_clean();

// The output of the controller is either directly echoed or it can be properly appended in AdminController::content
// it depends on the implementation of the controllers.
if (!empty($outputContent) && !empty($adminController->content)) {
// Sometimes they are both done and are equal, in which case we only return one content to avoid duplicates.
if ($outputContent === $adminController->content) {
$responseContent = $outputContent;
} else {
// In case both contents are present and are different we concatenate them, first the echoed output and then the controller
// one since it is displayed last by smarty in the original workflow
// This concatenation approach is theoretical and naive and was not tested because of the lack of use cases, so it may need
// to be improved in the future
$responseContent = $outputContent . $adminController->content;
}
} elseif (!empty($outputContent)) {
$responseContent = $outputContent;
} elseif (!empty($adminController->content)) {
$responseContent = $adminController->content;
} else {
$responseContent = '';
}

return new Response($responseContent);
return new Response(ob_get_clean());
}

/**
Expand All @@ -228,17 +206,16 @@ protected function renderAjaxController(AdminController $adminController, string
*
* Note: some legacy controllers may already use die at this point (to echo content and finish the process) when postProcess is called.
*
* @param Request $request
* @param array $dispatcherHookParameters
*
* @return AdminController
*/
protected function initController(array $dispatcherHookParameters): AdminController
protected function initController(Request $request, array $dispatcherHookParameters): AdminController
{
$controllerClass = $dispatcherHookParameters['controller_class'];

// Loading controller
// Retrieving the controller instantiated in LegacyRouterChecker
/** @var AdminController $adminController */
$adminController = new $controllerClass();
$adminController = $request->attributes->get(LegacyControllerConstants::INSTANCE_ATTRIBUTE);

// Fill default smarty variables as they can be used in partial templates rendered in init methods
$this->assignSmartyVariables->fillDefault();
Expand All @@ -248,7 +225,6 @@ protected function initController(array $dispatcherHookParameters): AdminControl

// This part comes from AdminController::run method, it has been stripped from permission checks since the permission is already
// handled by this Symfony controller
$adminController->init();
$adminController->setMedia(false);
$adminController->postProcess();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@

use PrestaShop\PrestaShop\Core\ConfigurationInterface;
use PrestaShop\PrestaShop\Core\Context\CountryContextBuilder;
use PrestaShop\PrestaShop\Core\FeatureFlag\FeatureFlagSettings;
use PrestaShop\PrestaShop\Core\FeatureFlag\FeatureFlagStateCheckerInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;

/**
Expand All @@ -39,7 +41,9 @@ class CountryContextListener
{
public function __construct(
private readonly CountryContextBuilder $countryContextBuilder,
private readonly ConfigurationInterface $configuration
private readonly ConfigurationInterface $configuration,
private readonly FeatureFlagStateCheckerInterface $featureFlagStateChecker,
private readonly bool $isSymfonyLayout,
) {
}

Expand All @@ -49,6 +53,10 @@ public function onKernelRequest(RequestEvent $event): void
return;
}

if ($this->isSymfonyLayout !== $this->featureFlagStateChecker->isEnabled(FeatureFlagSettings::FEATURE_FLAG_SYMFONY_LAYOUT)) {
return;
}

$this->countryContextBuilder->setCountryId((int) $this->configuration->get('PS_COUNTRY_DEFAULT'));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@

use PrestaShop\PrestaShop\Core\ConfigurationInterface;
use PrestaShop\PrestaShop\Core\Context\CurrencyContextBuilder;
use PrestaShop\PrestaShop\Core\FeatureFlag\FeatureFlagSettings;
use PrestaShop\PrestaShop\Core\FeatureFlag\FeatureFlagStateCheckerInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;

/**
Expand All @@ -40,6 +42,8 @@ class CurrencyContextListener
public function __construct(
private readonly CurrencyContextBuilder $currencyContextBuilder,
private readonly ConfigurationInterface $configuration,
private readonly FeatureFlagStateCheckerInterface $featureFlagStateChecker,
private readonly bool $isSymfonyLayout,
) {
}

Expand All @@ -49,6 +53,10 @@ public function onKernelRequest(RequestEvent $event): void
return;
}

if ($this->isSymfonyLayout !== $this->featureFlagStateChecker->isEnabled(FeatureFlagSettings::FEATURE_FLAG_SYMFONY_LAYOUT)) {
return;
}

$this->currencyContextBuilder->setCurrencyId((int) $this->configuration->get('PS_CURRENCY_DEFAULT'));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to [email protected] so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <[email protected]>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
*/

declare(strict_types=1);

namespace PrestaShopBundle\EventListener\Admin\Context;

use PrestaShop\PrestaShop\Core\ConfigurationInterface;
use PrestaShop\PrestaShop\Core\Context\LanguageContextBuilder;
use Symfony\Component\HttpKernel\Event\RequestEvent;

/**
* Listener dedicated to set up default Language context for the Back-Office/Admin application.
* We need to initialize the LanguageContext earlier because it's used by components in the Symfony
* layout that will be displayed in the Not Found legacy page
*/
class DefaultLanguageContextListener
{
public function __construct(
private readonly LanguageContextBuilder $languageContextBuilder,
private readonly ConfigurationInterface $configuration,
) {
}

public function onKernelRequest(RequestEvent $event): void
{
if (!$event->isMainRequest()) {
return;
}

$defaultLanguageId = (int) $this->configuration->get('PS_LANG_DEFAULT');
$this->languageContextBuilder->setDefaultLanguageId($defaultLanguageId);
$this->languageContextBuilder->setLanguageId($defaultLanguageId);
}
}
Loading

0 comments on commit 35ae4cf

Please sign in to comment.