Skip to content

Commit

Permalink
Merge pull request PrestaShop#37274 from jolelievre/refacto-controllers
Browse files Browse the repository at this point in the history
Refacto controllers
  • Loading branch information
matthieu-rolland authored Oct 31, 2024
2 parents 8ab8a3a + cbe84b4 commit 277e018
Show file tree
Hide file tree
Showing 22 changed files with 513 additions and 374 deletions.
1 change: 1 addition & 0 deletions phpstan-disallowed-calls.neon
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@ parameters:
disallowIn:
- src/PrestaShopBundle/Controller/*
allowIn:
- src/PrestaShopBundle/Controller/Admin/CommonController.php
- src/PrestaShopBundle/Controller/Admin/FrameworkBundleAdminController.php
- src/PrestaShopBundle/Controller/Admin/PrestaShopAdminController.php
- src/PrestaShopBundle/Controller/Admin/Improve/Modules/ModuleAbstractController.php
Expand Down
19 changes: 3 additions & 16 deletions src/Core/Grid/Data/Factory/CustomerDiscountGridDataFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,36 +29,23 @@
namespace PrestaShop\PrestaShop\Core\Grid\Data\Factory;

use CartRule;
use Customer;
use PrestaShop\PrestaShop\Core\Grid\Data\GridData;
use PrestaShop\PrestaShop\Core\Grid\Record\RecordCollection;
use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface;

/**
* Class CustomerDiscountGridDataFactory is responsible of returning grid data for customer's discounts.
* Class CustomerDiscountGridDataFactory is responsible for returning grid data for customer's discounts.
*/
final class CustomerDiscountGridDataFactory implements GridDataFactoryInterface
{
/**
* @var Customer
*/
private $customer;

/**
* @param Customer $customer
*/
public function __construct(Customer $customer)
{
$this->customer = $customer;
}

/**
* {@inheritdoc}
*/
public function getData(SearchCriteriaInterface $searchCriteria)
{
$customerFilters = $searchCriteria->getFilters();
$allDiscounts = CartRule::getAllCustomerCartRules(
$this->customer->id
$customerFilters['id_customer']
);

$discountsToDisplay = array_slice(
Expand Down
47 changes: 47 additions & 0 deletions src/Core/Grid/Definition/Factory/GridDefinitionFactoryProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?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)
*/

namespace PrestaShop\PrestaShop\Core\Grid\Definition\Factory;

use Symfony\Component\DependencyInjection\Attribute\AutowireLocator;
use Symfony\Contracts\Service\ServiceProviderInterface;

/**
* This is a service locator that allows fetching grid definition factories via their index.
*/
class GridDefinitionFactoryProvider
{
public function __construct(
#[AutowireLocator('core.grid_definition_factory')]
protected ServiceProviderInterface $factories
) {
}

public function getFactory(string $name): GridDefinitionFactoryInterface
{
return $this->factories->get($name);
}
}
47 changes: 47 additions & 0 deletions src/Core/Grid/Position/PositionDefinitionProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?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)
*/

namespace PrestaShop\PrestaShop\Core\Grid\Position;

use Symfony\Component\DependencyInjection\Attribute\AutowireLocator;
use Symfony\Contracts\Service\ServiceProviderInterface;

/**
* This is a service locator that allows fetching position definitions via their index.
*/
class PositionDefinitionProvider
{
public function __construct(
#[AutowireLocator('core.grid_position_definition')]
protected ServiceProviderInterface $positionDefinitions
) {
}

public function getPositionDefinition(string $name): PositionDefinitionInterface
{
return $this->positionDefinitions->get($name);
}
}
129 changes: 51 additions & 78 deletions src/PrestaShopBundle/Controller/Admin/CommonController.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,20 @@

namespace PrestaShopBundle\Controller\Admin;

use Context;
use PrestaShop\PrestaShop\Adapter\Tools;
use PrestaShop\PrestaShop\Core\Domain\Notification\Command\UpdateEmployeeNotificationLastElementCommand;
use PrestaShop\PrestaShop\Core\Domain\Notification\Query\GetNotificationLastElements;
use PrestaShop\PrestaShop\Core\Domain\Notification\QueryResult\NotificationsResults;
use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\AbstractGridDefinitionFactory;
use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\FilterableGridDefinitionFactoryInterface;
use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\GridDefinitionFactoryInterface;
use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\GridDefinitionFactoryProvider;
use PrestaShop\PrestaShop\Core\Grid\Position\Exception\PositionUpdateException;
use PrestaShop\PrestaShop\Core\Grid\Position\GridPositionUpdaterInterface;
use PrestaShop\PrestaShop\Core\Grid\Position\PositionDefinitionInterface;
use PrestaShop\PrestaShop\Core\Grid\Position\PositionUpdateFactoryInterface;
use PrestaShop\PrestaShop\Core\Grid\Position\PositionDefinitionProvider;
use PrestaShop\PrestaShop\Core\Kpi\Row\KpiRowInterface;
use PrestaShopBundle\Entity\Employee\Employee;
use PrestaShop\PrestaShop\Core\Kpi\Row\KpiRowPresenter;
use PrestaShopBundle\Entity\Repository\AdminFilterRepository;
use PrestaShopBundle\Security\Attribute\AdminSecurity;
use PrestaShopBundle\Service\Grid\ControllerResponseBuilder;
use PrestaShopBundle\Service\Grid\ResponseBuilder;
use ReflectionClass;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
Expand All @@ -52,8 +49,15 @@
/**
* Admin controller for the common actions across the whole admin interface.
*/
class CommonController extends FrameworkBundleAdminController
class CommonController extends PrestaShopAdminController
{
public static function getSubscribedServices(): array
{
return parent::getSubscribedServices() + [
ControllerResponseBuilder::class => ControllerResponseBuilder::class,
];
}

/**
* Get a summary of recent events on the shop.
* This includes:
Expand All @@ -63,11 +67,10 @@ class CommonController extends FrameworkBundleAdminController
*
* @return JsonResponse
*/
public function notificationsAction()
public function notificationsAction(): JsonResponse
{
$employeeId = Context::getContext()->employee->id;
/** @var NotificationsResults $elements */
$elements = $this->getQueryBus()->handle(new GetNotificationLastElements($employeeId));
$elements = $this->dispatchQuery(new GetNotificationLastElements($this->getEmployeeContext()->getEmployee()->getId()));

return new JsonResponse($elements->getNotificationsResultsForJS());
}
Expand All @@ -79,10 +82,9 @@ public function notificationsAction()
*
* @return JsonResponse
*/
public function notificationsAckAction(Request $request)
public function notificationsAckAction(Request $request): JsonResponse
{
$type = $request->request->get('type');
$this->getCommandBus()->handle(new UpdateEmployeeNotificationLastElementCommand($type));
$this->dispatchCommand(new UpdateEmployeeNotificationLastElementCommand($request->request->get('type')));

return new JsonResponse(true);
}
Expand Down Expand Up @@ -112,7 +114,7 @@ public function notificationsAckAction(Request $request)
*
* @return Response
*/
public function paginationAction(Request $request, $limit = 10, $offset = 0, $total = 0, $view = 'full', $prefix = ''): Response
public function paginationAction(Request $request, ?int $limit = 10, ?int $offset = 0, ?int $total = 0, string $view = 'full', string $prefix = ''): Response
{
$offsetParam = empty($prefix) ? 'offset' : sprintf('%s[offset]', $prefix);
$limitParam = empty($prefix) ? 'limit' : sprintf('%s[limit]', $prefix);
Expand Down Expand Up @@ -210,10 +212,12 @@ public function paginationAction(Request $request, $limit = 10, $offset = 0, $to
*
* @return Response
*/
public function renderSidebarAction($url, $title = '', $footer = '')
{
$tools = $this->get(Tools::class);

public function renderSidebarAction(
Tools $tools,
string $url,
string $title = '',
string $footer = '',
): Response {
return $this->render('@PrestaShop/Admin/Common/_partials/_sidebar.html.twig', [
'footer' => $tools->purifyHTML($footer),
'title' => $title,
Expand All @@ -228,12 +232,12 @@ public function renderSidebarAction($url, $title = '', $footer = '')
*
* @return Response
*/
public function renderKpiRowAction(KpiRowInterface $kpiRow)
{
$presenter = $this->get('prestashop.core.kpi_row.presenter');

public function renderKpiRowAction(
KpiRowInterface $kpiRow,
KpiRowPresenter $kpiRowPresenter,
): Response {
return $this->render('@PrestaShop/Admin/Common/Kpi/kpi_row.html.twig', [
'kpiRow' => $presenter->present($kpiRow),
'kpiRow' => $kpiRowPresenter->present($kpiRow),
]);
}

Expand All @@ -246,11 +250,14 @@ public function renderKpiRowAction(KpiRowInterface $kpiRow)
*
* @throws \Doctrine\ORM\OptimisticLockException
*/
public function resetSearchAction($controller = '', $action = '', $filterId = '')
{
$adminFiltersRepository = $this->get('prestashop.core.admin.admin_filter.repository');
$employeeId = $this->getUser() instanceof Employee ? $this->getUser()->getId() : 0;
$shopId = $this->getContext()->shop->id;
public function resetSearchAction(
AdminFilterRepository $adminFiltersRepository,
string $controller = '',
string $action = '',
string $filterId = '',
): JsonResponse {
$employeeId = $this->getEmployeeContext()->getEmployee()->getId();
$shopId = $this->getShopContext()->getId();

// for compatibility when $controller and $action are used
if (!empty($controller) && !empty($action)) {
Expand All @@ -270,33 +277,6 @@ public function resetSearchAction($controller = '', $action = '', $filterId = ''
return new JsonResponse();
}

/**
* Specific action to render a specific field twice.
*
* @param string $formName the form name
* @param string $formType the form type FQCN
* @param string $fieldName the field name
* @param array $fieldData the field data
*
* @return Response
*/
public function renderFieldAction($formName, $formType, $fieldName, $fieldData)
{
$formData = [
$formName => [
$fieldName => $fieldData,
],
];

$form = $this->createFormBuilder($formData);
$form->add($formName, $formType);

return $this->render('@PrestaShop/Admin/Common/_partials/_form_field.html.twig', [
'form' => $form->getForm()->get($formName)->get($fieldName)->createView(),
'formId' => $formName . '_' . $fieldName . '_rendered',
]);
}

/**
* Process Grid search.
*
Expand All @@ -309,16 +289,15 @@ public function renderFieldAction($formName, $formType, $fieldName, $fieldData)
*/
#[AdminSecurity("is_granted('read', request.get('_legacy_controller'))")]
public function searchGridAction(
GridDefinitionFactoryProvider $gridDefinitionFactoryCollection,
Request $request,
$gridDefinitionFactoryServiceId,
$redirectRoute,
string $gridDefinitionFactoryServiceId,
string $redirectRoute,
array $redirectQueryParamsToKeep = []
) {
/** @var GridDefinitionFactoryInterface $definitionFactory */
$definitionFactory = $this->get($gridDefinitionFactoryServiceId);
$definitionFactory = $gridDefinitionFactoryCollection->getFactory($gridDefinitionFactoryServiceId);

$filterId = null;

if ($definitionFactory instanceof FilterableGridDefinitionFactoryInterface) {
$filterId = $definitionFactory->getFilterId();
} elseif ($definitionFactory instanceof AbstractGridDefinitionFactory) {
Expand All @@ -332,21 +311,18 @@ public function searchGridAction(
}

if (null !== $filterId) {
/** @var ResponseBuilder $responseBuilder */
$responseBuilder = $this->get('prestashop.bundle.grid.response_builder');

return $responseBuilder->buildSearchResponse(
return $this->buildSearchResponse(
$definitionFactory,
$request,
$filterId,
$redirectRoute,
$redirectQueryParamsToKeep
$redirectQueryParamsToKeep,
);
}

// Legacy grid definition which use controller/action as filter keys (and no scope for parameters)
/** @var ControllerResponseBuilder $controllerResponseBuilder */
$controllerResponseBuilder = $this->get('prestashop.bundle.grid.controller_response_builder');
$controllerResponseBuilder = $this->container->get(ControllerResponseBuilder::class);

return $controllerResponseBuilder->buildSearchResponse(
$definitionFactory,
Expand All @@ -362,24 +338,21 @@ public function searchGridAction(
* @return RedirectResponse
*/
#[AdminSecurity("is_granted('update', request.get('_legacy_controller'))")]
public function updatePositionAction(Request $request): RedirectResponse
{
public function updatePositionAction(
Request $request,
PositionDefinitionProvider $positionDefinitionProvider,
): RedirectResponse {
$positionsData = [
'positions' => $request->request->all('positions'),
];

/** @var PositionDefinitionInterface $positionDefinition */
$positionDefinition = $this->get($request->attributes->get('position_definition'));
$positionUpdateFactory = $this->get(PositionUpdateFactoryInterface::class);

$positionDefinition = $positionDefinitionProvider->getPositionDefinition($request->attributes->get('position_definition'));
try {
$positionUpdate = $positionUpdateFactory->buildPositionUpdate($positionsData, $positionDefinition);
$updater = $this->get(GridPositionUpdaterInterface::class);
$updater->update($positionUpdate);
$this->addFlash('success', $this->trans('Successful update', 'Admin.Notifications.Success'));
$this->updateGridPosition($positionDefinition, $positionsData);
$this->addFlash('success', $this->trans('Successful update', [], 'Admin.Notifications.Success'));
} catch (PositionUpdateException $e) {
$errors = [$e->toArray()];
$this->flashErrors($errors);
$this->addFlashErrors($errors);
}

return $this->redirectToRoute($request->attributes->get('redirect_route'));
Expand Down
Loading

0 comments on commit 277e018

Please sign in to comment.