Skip to content

Conversation

@CySSoO
Copy link
Contributor

@CySSoO CySSoO commented Oct 17, 2025

Summary

  • replace the legacy AdminEverBlock controller with a Symfony controller exposing the list, CRUD actions, bulk operations, export and cache clear flows
  • introduce grid definition/data factories, Symfony form data provider/type/handler and new Twig templates to cover the legacy HTML block fields and documentation tabs
  • update service wiring, routes and allowed files to point to the new implementation

Testing

  • php -l src/Controller/Admin/EverblockBlockController.php
  • php -l src/Grid/Definition/Factory/EverblockGridDefinitionFactory.php
  • php -l src/Grid/Query/EverblockQueryBuilder.php
  • php -l src/Grid/Data/EverblockGridDataFactory.php
  • php -l src/Form/DataProvider/EverblockFormDataProvider.php
  • php -l src/Form/Handler/EverblockFormHandler.php
  • php -l src/Form/Type/EverblockFormType.php

https://chatgpt.com/codex/tasks/task_e_68f27524435483228e201a06bf789fdf

@CySSoO CySSoO merged commit 590e8f3 into master Oct 17, 2025
0 of 6 checks passed
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +214 to +336
public function duplicate(int $everblockId): RedirectResponse
{
$source = new EverBlockClass($everblockId);
if (!Validate::isLoadedObject($source)) {
$this->addFlash('error', $this->translate('Unable to find the block to duplicate.'));

return $this->redirectToRoute('everblock_admin_blocks');
}

$duplicate = new EverBlockClass();
$duplicate->name = $source->name;
$duplicate->id_hook = (int) $source->id_hook;
$duplicate->id_shop = (int) $source->id_shop;
$duplicate->only_home = (bool) $source->only_home;
$duplicate->only_category = (bool) $source->only_category;
$duplicate->only_category_product = (bool) $source->only_category_product;
$duplicate->only_manufacturer = (bool) $source->only_manufacturer;
$duplicate->only_supplier = (bool) $source->only_supplier;
$duplicate->only_cms_category = (bool) $source->only_cms_category;
$duplicate->categories = $source->categories;
$duplicate->manufacturers = $source->manufacturers;
$duplicate->suppliers = $source->suppliers;
$duplicate->cms_categories = $source->cms_categories;
$duplicate->groups = $source->groups;
$duplicate->content = $source->content;
$duplicate->custom_code = $source->custom_code;
$duplicate->device = (int) $source->device;
$duplicate->background = $source->background;
$duplicate->css_class = $source->css_class;
$duplicate->data_attribute = $source->data_attribute;
$duplicate->bootstrap_class = $source->bootstrap_class;
$duplicate->position = (int) $source->position;
$duplicate->delay = (int) $source->delay;
$duplicate->timeout = (int) $source->timeout;
$duplicate->modal = (bool) $source->modal;
$duplicate->date_start = $source->date_start;
$duplicate->date_end = $source->date_end;
$duplicate->active = false;
$duplicate->obfuscate_link = (bool) $source->obfuscate_link;
$duplicate->add_container = (bool) $source->add_container;
$duplicate->lazyload = (bool) $source->lazyload;

if ($duplicate->save()) {
$this->addFlash('success', $this->translate('The block has been duplicated.'));
} else {
$this->addFlash('error', $this->translate('An error occurred while duplicating the block.'));
}

return $this->redirectToRoute('everblock_admin_blocks');
}

public function toggle(int $everblockId): RedirectResponse
{
$block = new EverBlockClass($everblockId);
if (!Validate::isLoadedObject($block)) {
$this->addFlash('error', $this->translate('Unable to update the block status.'));

return $this->redirectToRoute('everblock_admin_blocks');
}

$block->active = (int) !$block->active;
if ($block->save()) {
$this->addFlash('success', $this->translate('The block status has been updated.'));
} else {
$this->addFlash('error', $this->translate('An error occurred while updating the block status.'));
}

return $this->redirectToRoute('everblock_admin_blocks');
}

public function bulkDelete(Request $request): RedirectResponse
{
$ids = $request->request->all('ids');
if (!is_array($ids)) {
$ids = [];
}

$deleted = 0;
foreach ($ids as $id) {
$block = new EverBlockClass((int) $id);
if (Validate::isLoadedObject($block) && $block->delete()) {
++$deleted;
}
}

if ($deleted > 0) {
$this->addFlash('success', $this->translate('%count% block(s) have been deleted.', ['%count%' => $deleted]));
} else {
$this->addFlash('error', $this->translate('No block was deleted.'));
}

return $this->redirectToRoute('everblock_admin_blocks');
}

public function bulkDuplicate(Request $request): RedirectResponse
{
$ids = $request->request->all('ids');
if (!is_array($ids)) {
$ids = [];
}

$duplicated = 0;
foreach ($ids as $id) {
$block = new EverBlockClass((int) $id);
if (!Validate::isLoadedObject($block)) {
continue;
}

$duplicate = $block->duplicateObject();
if ($duplicate && $duplicate->id) {
$duplicate->active = false;
$duplicate->save();
++$duplicated;
}
}

if ($duplicated > 0) {
$this->addFlash('success', $this->translate('%count% block(s) have been duplicated.', ['%count%' => $duplicated]));
} else {
$this->addFlash('error', $this->translate('No block was duplicated.'));
}

return $this->redirectToRoute('everblock_admin_blocks');

Choose a reason for hiding this comment

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

P1 Badge Guard state-changing actions with CSRF tokens

The new Symfony controller exposes all mutating operations (duplicate, toggle, bulkDelete, bulkDuplicate, clearCache, export) as plain GET/POST endpoints without verifying any admin token or other CSRF protection. The legacy ModuleAdminController automatically injected and validated token parameters for these same actions, so moving to Symfony removed that protection. A logged-in admin can now be tricked into deleting or duplicating blocks simply by visiting a malicious page that issues requests to these routes. Consider requiring a generated token (e.g. via Symfony’s CsrfTokenManager or a signed URL) before executing these actions.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants