From e804c37175b89a88bfcaf2ff1e8f62a3628f9720 Mon Sep 17 00:00:00 2001 From: Isabelle Date: Thu, 13 Aug 2026 16:42:17 +0200 Subject: [PATCH] feat(main): Make groups reorderable --- config/grid.yml | 10 ++++++++ config/routes.yml | 6 +++++ src/Controller/CustomHtmlGroupController.php | 24 +++++++++++++++++++ .../CustomHtmlGroupDataHandler.php | 12 +++++++++- .../CustomHtmlGroupGridDefinitionFactory.php | 11 +++++++++ src/Grid/Filters/CustomHtmlGroupFilters.php | 2 +- .../Query/CustomHtmlGroupQueryBuilder.php | 5 +++- upgrade/upgrade-1.11.0.php | 24 +++++++++++++++++++ .../admin/grid/customhtmlgroup.html.twig | 1 + ws_customhtml.php | 2 +- 10 files changed, 93 insertions(+), 4 deletions(-) create mode 100644 upgrade/upgrade-1.11.0.php diff --git a/config/grid.yml b/config/grid.yml index 814c55b..dcf2f9d 100644 --- a/config/grid.yml +++ b/config/grid.yml @@ -34,6 +34,16 @@ services: - '@prestashop.core.grid.filter.form_factory' - '@prestashop.core.hook.dispatcher' + websmid.customhtml.grid.position.customhtmlgroup_position_definition: + public: true + class: 'PrestaShop\PrestaShop\Core\Grid\Position\PositionDefinition' + arguments: + - 'ws_customhtml_group' + - 'id_ws_customhtml_group' + - 'ordering' + - ~ + - 0 + websmid.customhtml.grid.definition.factory.customhtmlblock_definition_factory: public: true class: 'Websmid\CustomHtml\Grid\Definition\Factory\CustomHtmlBlockGridDefinitionFactory' diff --git a/config/routes.yml b/config/routes.yml index a0eb2e5..b5595d4 100644 --- a/config/routes.yml +++ b/config/routes.yml @@ -39,6 +39,12 @@ customhtmlgroup_delete: defaults: _controller: 'Websmid\CustomHtml\Controller\CustomHtmlGroupController::deleteAction' +customhtmlgroup_update_position: + path: ws_customhtml/group/update-position + methods: [POST] + defaults: + _controller: 'Websmid\CustomHtml\Controller\CustomHtmlGroupController::updatePositionAction' + customhtmlblock_index: path: ws_customhtml/block methods: [GET] diff --git a/src/Controller/CustomHtmlGroupController.php b/src/Controller/CustomHtmlGroupController.php index 1dabed9..2bf3142 100644 --- a/src/Controller/CustomHtmlGroupController.php +++ b/src/Controller/CustomHtmlGroupController.php @@ -3,6 +3,9 @@ namespace Websmid\CustomHtml\Controller; use Exception; +use PrestaShop\PrestaShop\Core\Grid\Position\Exception\PositionUpdateException; +use PrestaShop\PrestaShop\Core\Grid\Position\GridPositionUpdaterInterface; +use PrestaShop\PrestaShop\Core\Grid\Position\PositionUpdateFactoryInterface; use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; use PrestaShopBundle\Security\Voter\PageVoter; use Symfony\Component\HttpFoundation\RedirectResponse; @@ -103,6 +106,27 @@ class CustomHtmlGroupController extends FrameworkBundleAdminController return $this->redirectToRoute('customhtmlgroup_index'); } + public function updatePositionAction(Request $request): RedirectResponse + { + $positionDefinition = $this->get('websmid.customhtml.grid.position.customhtmlgroup_position_definition'); + + try { + $positionUpdateFactory = $this->get(PositionUpdateFactoryInterface::class); + $positionUpdate = $positionUpdateFactory->buildPositionUpdate([ + 'positions' => $request->request->all('positions'), + ], $positionDefinition); + + $updater = $this->get(GridPositionUpdaterInterface::class); + $updater->update($positionUpdate); + + $this->addFlash('success', $this->trans('Successful update.', 'Admin.Notifications.Success')); + } catch (PositionUpdateException $e) { + $this->addFlash('error', $this->getErrorMessageForException($e, [])); + } + + return $this->redirectToRoute('customhtmlgroup_index'); + } + private function getToolbarButtons(?string $securitySubject): array { $toolbarButtons = []; diff --git a/src/Form/DataHandler/CustomHtmlGroupDataHandler.php b/src/Form/DataHandler/CustomHtmlGroupDataHandler.php index a7ebba3..8f86fe5 100644 --- a/src/Form/DataHandler/CustomHtmlGroupDataHandler.php +++ b/src/Form/DataHandler/CustomHtmlGroupDataHandler.php @@ -5,6 +5,7 @@ namespace Websmid\CustomHtml\Form\DataHandler; use PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler\FormDataHandlerInterface; use Websmid\CustomHtml\Model\CustomHtmlGroup; use Context; +use Db; use Hook; use Module; use Validate; @@ -17,7 +18,7 @@ final class CustomHtmlGroupDataHandler implements FormDataHandlerInterface $group->title = (string) $formData['title']; $group->hook_name = (string) $formData['hook_name']; $group->active = (int) $formData['active']; - $group->ordering = 0; + $group->ordering = $this->getNextOrdering(); if (!$group->add()) { return false; @@ -28,6 +29,15 @@ final class CustomHtmlGroupDataHandler implements FormDataHandlerInterface return $group->id; } + private function getNextOrdering(): int + { + $maxOrdering = Db::getInstance()->getValue( + 'SELECT MAX(`ordering`) FROM `' . _DB_PREFIX_ . 'ws_customhtml_group`' + ); + + return $maxOrdering !== false ? ((int) $maxOrdering + 1) : 0; + } + public function update($id, array $formData) { $group = new CustomHtmlGroup((int) $id); diff --git a/src/Grid/Definition/Factory/CustomHtmlGroupGridDefinitionFactory.php b/src/Grid/Definition/Factory/CustomHtmlGroupGridDefinitionFactory.php index eda0f4d..3a47da8 100644 --- a/src/Grid/Definition/Factory/CustomHtmlGroupGridDefinitionFactory.php +++ b/src/Grid/Definition/Factory/CustomHtmlGroupGridDefinitionFactory.php @@ -8,6 +8,7 @@ use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\LinkRowAction; use PrestaShop\PrestaShop\Core\Grid\Action\Type\SimpleGridAction; use PrestaShop\PrestaShop\Core\Grid\Column\ColumnCollection; use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ActionColumn; +use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\PositionColumn; use PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn; use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\AbstractGridDefinitionFactory; use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\DeleteActionTrait; @@ -81,6 +82,16 @@ final class CustomHtmlGroupGridDefinitionFactory extends AbstractGridDefinitionF ->setName($this->trans('Active', [], 'Admin.Global')) ->setOptions(['field' => 'active']) ) + ->add( + (new PositionColumn('position')) + ->setName($this->trans('Position', [], 'Admin.Global')) + ->setOptions([ + 'id_field' => 'id_ws_customhtml_group', + 'position_field' => 'ordering', + 'update_method' => 'POST', + 'update_route' => 'customhtmlgroup_update_position', + ]) + ) ->add( (new DataColumn('date_add')) ->setName($this->trans('Date added', [], 'Admin.Global')) diff --git a/src/Grid/Filters/CustomHtmlGroupFilters.php b/src/Grid/Filters/CustomHtmlGroupFilters.php index 6d4a48b..f94721c 100644 --- a/src/Grid/Filters/CustomHtmlGroupFilters.php +++ b/src/Grid/Filters/CustomHtmlGroupFilters.php @@ -14,7 +14,7 @@ final class CustomHtmlGroupFilters extends Filters return [ 'limit' => 10, 'offset' => 0, - 'orderBy' => 'wchg.id_ws_customhtml_group', + 'orderBy' => 'position', 'sortOrder' => 'asc', 'filters' => [], ]; diff --git a/src/Grid/Query/CustomHtmlGroupQueryBuilder.php b/src/Grid/Query/CustomHtmlGroupQueryBuilder.php index 8ddbaf9..f205fe8 100644 --- a/src/Grid/Query/CustomHtmlGroupQueryBuilder.php +++ b/src/Grid/Query/CustomHtmlGroupQueryBuilder.php @@ -46,6 +46,7 @@ final class CustomHtmlGroupQueryBuilder extends AbstractDoctrineQueryBuilder 'wchg.`title`', 'wchg.`hook_name`', 'wchg.`active`', + 'wchg.`ordering`', 'wchg.`date_add`', '(SELECT COUNT(*) FROM `' . $this->dbPrefix . 'ws_customhtml` wch WHERE wch.`id_ws_customhtml_group` = wchg.`id_ws_customhtml_group`) AS blocks_count' @@ -53,8 +54,10 @@ final class CustomHtmlGroupQueryBuilder extends AbstractDoctrineQueryBuilder $this->applyFilters($qb, $searchCriteria); + $orderBy = $searchCriteria->getOrderBy() === 'position' ? 'wchg.ordering' : $searchCriteria->getOrderBy(); + $qb - ->orderBy($searchCriteria->getOrderBy(), $searchCriteria->getOrderWay()) + ->orderBy($orderBy, $searchCriteria->getOrderWay()) ->setFirstResult($searchCriteria->getOffset() ?? 0) ->setMaxResults($searchCriteria->getLimit()); diff --git a/upgrade/upgrade-1.11.0.php b/upgrade/upgrade-1.11.0.php new file mode 100644 index 0000000..d9b74b2 --- /dev/null +++ b/upgrade/upgrade-1.11.0.php @@ -0,0 +1,24 @@ +executeS( + 'SELECT `id_ws_customhtml_group` FROM `' . _DB_PREFIX_ . 'ws_customhtml_group` ORDER BY `id_ws_customhtml_group` ASC' + ); + + foreach ($groups as $index => $group) { + if (!Db::getInstance()->update( + 'ws_customhtml_group', + ['ordering' => (int) $index], + '`id_ws_customhtml_group` = ' . (int) $group['id_ws_customhtml_group'] + )) { + return false; + } + } + + return true; +} diff --git a/views/templates/admin/grid/customhtmlgroup.html.twig b/views/templates/admin/grid/customhtmlgroup.html.twig index 6131566..b1c6390 100644 --- a/views/templates/admin/grid/customhtmlgroup.html.twig +++ b/views/templates/admin/grid/customhtmlgroup.html.twig @@ -20,6 +20,7 @@ customhtmlgroupGrid.addExtension(new window.prestashop.component.GridExtensions.FiltersResetExtension()); customhtmlgroupGrid.addExtension(new window.prestashop.component.GridExtensions.ColumnTogglingExtension()); customhtmlgroupGrid.addExtension(new window.prestashop.component.GridExtensions.SubmitRowActionExtension()); + customhtmlgroupGrid.addExtension(new window.prestashop.component.GridExtensions.PositionExtension()); }); {% endblock %} diff --git a/ws_customhtml.php b/ws_customhtml.php index f2a9677..31739e3 100644 --- a/ws_customhtml.php +++ b/ws_customhtml.php @@ -29,7 +29,7 @@ class Ws_CustomHtml extends Module implements WidgetInterface public function __construct() { $this->name = 'ws_customhtml'; - $this->version = '1.10.0'; + $this->version = '1.11.0'; $this->author = 'Isabelle Oving-Anno | De Websmid BV'; $this->need_instance = 0; $this->bootstrap = true;