Skip to content

feat!: upgrade to prestashop 9#76

Merged
arnaud-hours merged 51 commits intomainfrom
feat/prestashop-9
Apr 2, 2026
Merged

feat!: upgrade to prestashop 9#76
arnaud-hours merged 51 commits intomainfrom
feat/prestashop-9

Conversation

@arnaud-hours
Copy link
Copy Markdown
Contributor

@arnaud-hours arnaud-hours commented Feb 27, 2026

⚠ BREAKING CHANGES

  • compatibility: PrestaShop versions below 8.0.0 are no longer supported. The minimum required version is now 8.0.0 and the maximum supported version is 9.x. All code paths that branched on _PS_VERSION_ < 1.7 / < 1.5 / < 1.6 have been removed.

Features

Admin Controllers — full migration to Symfony (PS 9 routing)

  • All nine admin pages (Home, Dashboard, Feed, Order, Order Settings, Main Settings, Legals, Help, Toolbox) have been rewritten as Symfony controllers extending a new AbstractLengowAdminController base class, located in src/Controller/Admin/.
  • Each tab now carries a route_name (lengow_home, lengow_dashboard, …) that is registered with the PS 9 router on install. On PS 8 the legacy AdminLengow* controller names are used as before — the install logic selects the right approach based on the PS version.
  • getContent() now uses the Symfony router service to redirect to lengow_home instead of the old LengowLink helper. A clearCompiledCache() helper deletes stale routing and DI-container cache files on install/uninstall so new routes are picked up immediately.
  • The legacy controllers/admin/ directory and the single src/Controller/AdminOrderController.php have been removed; all logic lives in the new src/Controller/Admin/ hierarchy.
  • The old controller override (controllers/admin/AdminOrdersController.php) has been removed; order-page customisation is now done exclusively through hooks.

Front Controllers replacing the webservice/ directory

  • webservice/export.php, webservice/cron.php and webservice/toolbox.php no longer exist as physical files. Three new FrontControllers (controllers/front/export.php, cron.php, toolbox.php) replace them.
  • A new hookModuleRoutes() implementation maps the old URLs (modules/lengow/webservice/*.php) to these controllers, preserving full backward-URL compatibility so existing cron jobs and integrations do not break.

Order detail — new Lengow tab

  • Two new hooks, displayAdminOrderTabLink and displayAdminOrderTabContent, inject a dedicated Lengow tab into the native PS order detail page.
  • The tab is conditionally displayed only for Lengow orders and only when the marketplace exposes return-tracking numbers, return carriers, refund reasons, or refund modes, replacing the controller override.
  • A new src/Service/OrderRefundDataUpdater.php service handles saving refund data from the tab form.

New LengowContext class

  • classes/models/LengowContext.php introduced as a thin wrapper around Context::getContext() that is being deprecated in the next prestashop updates. All code that previously called Context::getContext() directly has been migrated to LengowContext::getContext(), making the context easier to mock and consistent across the codebase.

New PHP 8.1 Enums (src/Enum/)

  • Backed enums added under src/Enum/ for type-safe representation of domain constants (previously raw strings or class constants).

Symfony service container integration

  • config/services.yml and config/admin/ routing files added so module controllers and services are registered in the PS Symfony DI container.

Changes

Tracker removed

  • The Lengow front-end tracker (hookDisplayHome, hookPaymentTop, hookFooter, hookDisplayFooter, page-type constants LENGOW_TRACK_*, static fields $currentPageType, $idCart, $idOrder, $orderPayment, etc.) has been fully removed from LengowHook. The displayFooter hook is no longer registered.

Hook fixes and additions

  • paymentTop hook registration corrected to displayPaymentTop to match the hookDisplayPaymentTop() method in lengow.php.
  • actionProductCancel hook added (PS 8.0+) to handle partial order cancellations.
  • displayAdminOrderTabLink and displayAdminOrderTabContent hooks registered (PS 1.7+).
  • moduleRoutes hook registered (PS 1.5+) to expose the front-controller URL mappings.
  • Deprecated home hook unregistered on upgrade; replaced by displayHome (PS 8.0+).

Views — Smarty .tpl → Twig .html.twig

  • All admin view templates have been rewritten from Smarty (.tpl) to Twig (.html.twig). Affected pages: Dashboard, Feed, Help, Home (connection flow), Order, Order Settings, Main Settings, Legals, Toolbox.
  • Legacy Smarty layout files (layout.tpl, header.tpl, footer.tpl, header_order.tpl) removed.
  • PS order-page block overrides (views/PrestaShop/Admin/Sell/Order/…) removed; order display is now handled via the new tab hooks.

Strict PHP type declarations across the entire codebase

  • All public and protected methods across LengowHook, LengowInstall, LengowMain, LengowImport, LengowConnector, LengowSync, LengowConfiguration, and all remaining model classes now carry explicit parameter types, typed properties, and return types (including union types like int|false, array|false, mixed).
  • PHPStan analysis raised to level 6.

Constructor signatures tightened

  • LengowHook, LengowInstall constructors now accept an explicit Context $context argument instead of calling Context::getContext() internally. Injected from lengow.php.

Bug Fixes

  • Security (XSS / open-redirect): All JavaScript files that used .attr('href') or window.location to build redirect URLs now validate targets through a lengowIsValidUrl() helper that checks protocol (http: / https:) before following any link. Affects order.js, feed.js, main_setting.js, order_setting.js and the corresponding CSS files that loaded affected scripts.
  • LengowImport: Fixed a missing return statement that caused the import loop to exit prematurely under certain conditions.
  • LengowInstall: setInstallationStatus(false) is now called before running update() during module upgrade to prevent a stale true status from skipping install steps.
  • hookActionObjectUpdateAfter: Removed a redundant instanceof Order check — LengowOrder::isFromLengow() already validates the object type internally.
  • hookActionProductCancel: Replaced $lengowOrder instanceof LengowOrder guard with Validate::isLoadedObject($orderDetail) for consistency with PS conventions.
  • Admin page titles: Translations for all admin page <title> tags corrected via the YML translation pipeline.
  • Backup restore: Fixed a regression in the module backup/restore flow introduced during the migration.

Removed

  • webservice/ directory (replaced by front controllers, see above).
  • controllers/admin/ directory (replaced by src/Controller/Admin/, see above).
  • src/Controller/AdminOrderController.php (merged into new hierarchy).
  • Smarty templates for all admin pages.
  • Order block Twig overrides (views/PrestaShop/…).
  • Lengow analytics tracker code (hooks, constants, static fields).
  • LengowMain::WEBSERVICE_EXPORT, WEBSERVICE_CRON, WEBSERVICE_TOOLBOX constants.
  • All conditional code branches targeting PrestaShop < 8.0.

arnaud-hours and others added 15 commits March 13, 2026 16:42
- Replace .html() with .text() for plain-text values (numeric counts,
  date strings, carrier scores) in feed.js, order.js, order_setting.js
- Add lengowIsValidUrl() helper to validate URLs before window.open()
  and window.location.href assignments in feed.js, order.js,
  main_setting.js
- Keep .html() for trusted backend-rendered HTML fragments

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@arnaud-hours arnaud-hours marked this pull request as ready for review March 26, 2026 10:14
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR upgrades the module for PrestaShop 8+ up to 9.x by migrating admin pages to Symfony controllers with Twig templates, replacing legacy webservice endpoints with FrontControllers, and tightening security/typing across the codebase.

Changes:

  • Migrates multiple admin pages from Smarty to Twig and introduces Symfony admin controllers + DI wiring.
  • Replaces webservice/*.php endpoints with module FrontControllers and adds route mappings for backward compatibility.
  • Improves security (URL validation, safer DOM writes) and adds stricter typing + PHPStan configuration.

Reviewed changes

Copilot reviewed 133 out of 186 changed files in this pull request and generated 12 comments.

Show a summary per file
File Description
views/templates/admin/lengow_main_setting/view.html.twig Adds Twig version of Main Settings admin view
views/templates/admin/lengow_main_setting/layout.tpl Removes legacy Smarty layout wrapper
views/templates/admin/lengow_main_setting/helpers/view/view.tpl Removes legacy Smarty view
views/templates/admin/lengow_legals/view.html.twig Adds Twig version of Legals admin view
views/templates/admin/lengow_legals/layout.tpl Removes legacy Smarty layout wrapper
views/templates/admin/lengow_legals/helpers/view/view.tpl Removes legacy Smarty view
views/templates/admin/lengow_home/view.html.twig Adds Twig version of Home admin view
views/templates/admin/lengow_home/layout.tpl Removes legacy Smarty layout wrapper
views/templates/admin/lengow_home/helpers/view/view.tpl Removes legacy Smarty view
views/templates/admin/lengow_home/helpers/view/connection_home.tpl Removes legacy Smarty partial
views/templates/admin/lengow_home/helpers/view/connection_home.html.twig Adds Twig partial for connection home
views/templates/admin/lengow_home/helpers/view/connection_cms_result.tpl Removes legacy Smarty partial
views/templates/admin/lengow_home/helpers/view/connection_cms_result.html.twig Adds Twig partial for CMS connection result
views/templates/admin/lengow_home/helpers/view/connection_cms.tpl Removes legacy Smarty partial
views/templates/admin/lengow_home/helpers/view/connection_cms.html.twig Adds Twig partial for CMS credentials form
views/templates/admin/lengow_home/helpers/view/connection_catalog_failed.tpl Removes legacy Smarty partial
views/templates/admin/lengow_home/helpers/view/connection_catalog_failed.html.twig Adds Twig partial for catalog-link failure
views/templates/admin/lengow_home/helpers/view/connection_catalog.tpl Removes legacy Smarty partial
views/templates/admin/lengow_home/helpers/view/connection_catalog.html.twig Adds Twig partial for catalog linking
views/templates/admin/lengow_help/view.html.twig Adds Twig version of Help admin view
views/templates/admin/lengow_help/layout.tpl Removes legacy Smarty layout wrapper
views/templates/admin/lengow_help/helpers/view/view.tpl Removes legacy Smarty view
views/templates/admin/lengow_feed/view.html.twig Adds Twig version of Feed admin view
views/templates/admin/lengow_feed/layout.tpl Removes legacy Smarty layout wrapper
views/templates/admin/lengow_feed/helpers/view/view.tpl Removes legacy Smarty view
views/templates/admin/lengow_dashboard/view.html.twig Adds Twig version of Dashboard admin view
views/templates/admin/lengow_dashboard/layout.tpl Removes legacy Smarty layout wrapper
views/templates/admin/lengow_dashboard/helpers/view/view.tpl Removes legacy Smarty view
views/templates/admin/lengow_dashboard/helpers/view/status.tpl Removes legacy Smarty status view
views/templates/admin/lengow_dashboard/helpers/view/status.html.twig Adds Twig status view
views/templates/admin/lengow_dashboard/helpers/view/dashboard.tpl Removes legacy Smarty dashboard view
views/templates/admin/lengow_dashboard/helpers/view/dashboard.html.twig Adds Twig dashboard view
views/templates/admin/header_order.tpl Removes legacy Smarty order header
views/templates/admin/header.tpl Removes legacy Smarty header (JS/CSS + menu)
views/templates/admin/footer.tpl Removes legacy Smarty footer (incl. upgrade modal)
views/js/lengow/order_setting.js Hardens DOM write by using .text()
views/js/lengow/order.js Adds URL validation before opening links
views/js/lengow/main_setting.js Adds URL validation before redirecting to selected log download
views/js/lengow/feed.js Adds URL validation + replaces .html() with .text() for counters
views/css/lengow-pages.css Updates dashboard/home layout styling
views/css/lengow-layout.css Adds PS9 layout adjustments and stronger link styling
views/css/lengow-components.css Adjusts component styling and link reset
views/PrestaShop/Admin/Sell/Order/Order/Blocks/View/shipping.html.twig Removes overridden PrestaShop order shipping block
views/PrestaShop/Admin/Sell/Order/Order/Blocks/View/Modal/update_shipping_modal.html.twig Removes overridden PrestaShop shipping modal
tools/translate.php Adds types and PHPDoc for CSV writer
tools/checkmd5.php Adds types and PHPDoc, and typed CSV writer
tools/build.sh Adjusts build cleanup list ordering/comment
tests/phpstan/index.php Adds index hardening file for phpstan test dir
tests/index.php Adds index hardening file for tests dir
src/Service/index.php Adds index hardening file for service dir
src/Service/OrderRefundDataUpdater.php Introduces service to persist refund reason/mode
src/Controller/Admin/LengowToolboxAdminController.php Adds Symfony admin controller for Toolbox
src/Controller/Admin/LengowOrderSettingAdminController.php Adds Symfony admin controller for Order Settings
src/Controller/Admin/LengowOrderAdminController.php Adds Symfony admin controller for Orders
src/Controller/Admin/LengowMainSettingAdminController.php Adds Symfony admin controller for Main Settings
src/Controller/Admin/LengowLegalsAdminController.php Adds Symfony admin controller for Legals
src/Controller/Admin/LengowHomeAdminController.php Adds Symfony admin controller for Home
src/Controller/Admin/LengowHelpAdminController.php Adds Symfony admin controller for Help
src/Controller/Admin/LengowFeedAdminController.php Adds Symfony admin controller for Feed
src/Controller/Admin/LengowDashboardAdminController.php Adds Symfony admin controller for Dashboard
src/Controller/Admin/AbstractLengowAdminController.php Adds shared Symfony admin base controller bridging legacy controllers
phpstan.neon Adds PHPStan config (level 6) and ignore rules
it.php Updates Italian translation string key/content
fr.php Updates French translation string key/content + fixes grammar/accents
es.php Updates Spanish translation string key/content
en.php Replaces incorrect PHP class content with translations array
controllers/front/toolbox.php Adds toolbox FrontController replacing webservice endpoint
controllers/front/index.php Adds index hardening file for controllers/front
controllers/front/cron.php Adds cron FrontController replacing webservice endpoint
controllers/admin/AdminLengowToolboxController.php Removes legacy ModuleAdminController wrapper
controllers/admin/AdminLengowOrderSettingController.php Removes legacy ModuleAdminController wrapper
controllers/admin/AdminLengowOrderController.php Removes legacy ModuleAdminController wrapper
controllers/admin/AdminLengowMainSettingController.php Removes legacy ModuleAdminController wrapper
controllers/admin/AdminLengowHomeController.php Removes legacy ModuleAdminController wrapper
controllers/admin/AdminLengowHelpController.php Removes legacy ModuleAdminController wrapper
controllers/admin/AdminLengowDashboardController.php Removes legacy ModuleAdminController wrapper
config/services.yml Imports admin DI service definitions
config/routes.yml Replaces old admin override routes with PS9 Symfony routes for module pages
config/admin/services.yml Registers admin controllers + OrderRefundDataUpdater in DI container
composer.json Requires PHP >=8.1 and adds PSR-4 mapping for Symfony controllers
classes/models/LengowTranslation.php Adds typing and path safety for translation file loading
classes/models/LengowToolboxElement.php Adds typing and escapes toolbox links
classes/models/LengowShop.php Adds typing for shop lookup helpers
classes/models/LengowOrderLine.php Adds typing and method signatures
classes/models/LengowOrderError.php Adds typing and tighter signatures
classes/models/LengowOrderDetail.php Refactors return carrier/tracking persistence to DB updates + typing
classes/models/LengowOrderCarrier.php Adds typed properties and typed constructor
classes/models/LengowNameParser.php Adds typing and path allowlist checks
classes/models/LengowMethod.php Adds typing and replaces Tools::strlen with mb_strlen
classes/models/LengowLog.php Adds typing, path allowlist, and safer download filename
classes/models/LengowLink.php Adds typing to admin link helper
classes/models/LengowGender.php Adds typing and fixes precedence in returned gender ID
classes/models/LengowFile.php Adds typed properties/methods and path allowlist checks
classes/models/LengowFeed.php Adds typing and switches context access to LengowContext
classes/models/LengowCustomer.php Adds typing, hardens field assignment, and simplifies size validation
classes/models/LengowCountry.php Adds typing and switches context access to LengowContext
classes/models/LengowContext.php Adds centralized Context provider (bridge for PS9 deprecation)
classes/models/LengowConfigurationForm.php Adds typing and escapes rendered HTML inputs
classes/models/LengowCatalog.php Adds typing and tightens token casting
classes/models/LengowBackup.php Adds typing and path allowlist check
classes/controllers/LengowToolboxController.php Ports Smarty assigns to controller templateVars
classes/controllers/LengowOrderSettingController.php Switches AJAX partial rendering to Twig + JSON helpers
classes/controllers/LengowMainSettingController.php Ports Smarty assigns to controller templateVars
classes/controllers/LengowHomeController.php Switches AJAX partial rendering to Twig + JSON helpers
classes/controllers/LengowFeedController.php Switches JSON outputs to helper + templateVars on full page
classes/controllers/LengowDashboardController.php Switches JSON outputs to helper + templateVars on full page
.php-cs-fixer.dist.php Adds PHP-CS-Fixer configuration

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

<br/>
<p>
{{ locale.t('connection.home.no_account') }}
<a href="https://my.{{ lengowUrl }}" target="_blank">
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

External links opened with target="_blank" should include rel="noopener noreferrer" to prevent reverse-tabnabbing and to match common security guidance. Add rel="noopener noreferrer" on this and similar external links (support/help center, my.lengow) across the Twig templates.

Suggested change
<a href="https://my.{{ lengowUrl }}" target="_blank">
<a href="https://my.{{ lengowUrl }}" target="_blank" rel="noopener noreferrer">

Copilot uses AI. Check for mistakes.
Comment on lines +85 to +97
<a href="#" class="lgw-modal-delete">
<button type="button" data-toggle="modal" data-target="#openDeleteModal"
class="lgw-btn lgw-btn-red lengow_delete_module" name="delete_module">
{{ locale.t('global_setting.screen.button_i_want_uninstall') }}
</button>
</a>
<div class="lgw-modal">
<a href="#" class="modal-close js-close-this-modal"></a>
<div class="lgw-modal-inner">
<div class="scrollable no-margin">
<div class="scrollable-in">
<div class="lgw-content-section text-center">
<img src="{{ lengowPathUri }}views/img/laser-gun.png">
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

This markup nests a <button> inside an <a>, which is invalid HTML and can cause inconsistent click/keyboard behavior for assistive tech and browsers. Replace with a single interactive element (either a <button> styled as a link or an <a role="button">), and add an alt attribute to the image for accessibility.

Suggested change
<a href="#" class="lgw-modal-delete">
<button type="button" data-toggle="modal" data-target="#openDeleteModal"
class="lgw-btn lgw-btn-red lengow_delete_module" name="delete_module">
{{ locale.t('global_setting.screen.button_i_want_uninstall') }}
</button>
</a>
<div class="lgw-modal">
<a href="#" class="modal-close js-close-this-modal"></a>
<div class="lgw-modal-inner">
<div class="scrollable no-margin">
<div class="scrollable-in">
<div class="lgw-content-section text-center">
<img src="{{ lengowPathUri }}views/img/laser-gun.png">
<button type="button" data-toggle="modal" data-target="#openDeleteModal"
class="lgw-btn lgw-btn-red lengow_delete_module lgw-modal-delete" name="delete_module">
{{ locale.t('global_setting.screen.button_i_want_uninstall') }}
</button>
<div class="lgw-modal">
<a href="#" class="modal-close js-close-this-modal"></a>
<div class="lgw-modal-inner">
<div class="scrollable no-margin">
<div class="scrollable-in">
<div class="lgw-content-section text-center">
<img src="{{ lengowPathUri }}views/img/laser-gun.png" alt="{{ locale.t('global_setting.screen.title_modal_uninstall') }}">

Copilot uses AI. Check for mistakes.
Comment on lines +85 to +97
<a href="#" class="lgw-modal-delete">
<button type="button" data-toggle="modal" data-target="#openDeleteModal"
class="lgw-btn lgw-btn-red lengow_delete_module" name="delete_module">
{{ locale.t('global_setting.screen.button_i_want_uninstall') }}
</button>
</a>
<div class="lgw-modal">
<a href="#" class="modal-close js-close-this-modal"></a>
<div class="lgw-modal-inner">
<div class="scrollable no-margin">
<div class="scrollable-in">
<div class="lgw-content-section text-center">
<img src="{{ lengowPathUri }}views/img/laser-gun.png">
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

This markup nests a <button> inside an <a>, which is invalid HTML and can cause inconsistent click/keyboard behavior for assistive tech and browsers. Replace with a single interactive element (either a <button> styled as a link or an <a role="button">), and add an alt attribute to the image for accessibility.

Suggested change
<a href="#" class="lgw-modal-delete">
<button type="button" data-toggle="modal" data-target="#openDeleteModal"
class="lgw-btn lgw-btn-red lengow_delete_module" name="delete_module">
{{ locale.t('global_setting.screen.button_i_want_uninstall') }}
</button>
</a>
<div class="lgw-modal">
<a href="#" class="modal-close js-close-this-modal"></a>
<div class="lgw-modal-inner">
<div class="scrollable no-margin">
<div class="scrollable-in">
<div class="lgw-content-section text-center">
<img src="{{ lengowPathUri }}views/img/laser-gun.png">
<button type="button" data-toggle="modal" data-target="#openDeleteModal"
class="lgw-btn lgw-btn-red lengow_delete_module lgw-modal-delete" name="delete_module">
{{ locale.t('global_setting.screen.button_i_want_uninstall') }}
</button>
<div class="lgw-modal">
<a href="#" class="modal-close js-close-this-modal"></a>
<div class="lgw-modal-inner">
<a href="#" class="modal-close js-close-this-modal"></a>
<div class="lgw-modal-inner">
<div class="scrollable no-margin">
<div class="scrollable-in">
<div class="lgw-content-section text-center">
<img src="{{ lengowPathUri }}views/img/laser-gun.png" alt="{{ locale.t('global_setting.screen.title_modal_uninstall') }}">

Copilot uses AI. Check for mistakes.
<input type="hidden" name="action" value="process">
<div class="lgw-box">
<h2>{{ locale.t('global_setting.screen.notification_alert_title') }}</h2>
{{ mail_report|raw }}
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

These variables are rendered with |raw, which disables Twig auto-escaping and can introduce XSS if any of the content is user-influenced (directly or indirectly). If these strings are meant to contain HTML, ensure they are generated exclusively from trusted server-side templates/whitelisted markup; otherwise, remove |raw and output escaped content (or rebuild these blocks using Twig templates/components rather than raw HTML strings).

Suggested change
{{ mail_report|raw }}
{{ mail_report }}

Copilot uses AI. Check for mistakes.
<div class="lgw-box">
<h2>{{ locale.t('global_setting.screen.default_export_carrier_title') }}</h2>
<p>{{ locale.t('global_setting.screen.default_export_carrier_description') }}</p>
{{ defaultExportCarrier|raw }}
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

These variables are rendered with |raw, which disables Twig auto-escaping and can introduce XSS if any of the content is user-influenced (directly or indirectly). If these strings are meant to contain HTML, ensure they are generated exclusively from trusted server-side templates/whitelisted markup; otherwise, remove |raw and output escaped content (or rebuild these blocks using Twig templates/components rather than raw HTML strings).

Suggested change
{{ defaultExportCarrier|raw }}
{{ defaultExportCarrier }}

Copilot uses AI. Check for mistakes.
<p>{{ locale.t('global_setting.screen.debug_mode_description') }}</p>
{{ debug_report|raw }}
<div id="lengow_wrapper_debug" style="display:none;">
{{ debug_wrapper|raw }}
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

These variables are rendered with |raw, which disables Twig auto-escaping and can introduce XSS if any of the content is user-influenced (directly or indirectly). If these strings are meant to contain HTML, ensure they are generated exclusively from trusted server-side templates/whitelisted markup; otherwise, remove |raw and output escaped content (or rebuild these blocks using Twig templates/components rather than raw HTML strings).

Suggested change
{{ debug_wrapper|raw }}
{{ debug_wrapper }}

Copilot uses AI. Check for mistakes.
Comment thread views/js/lengow/order.js
Comment on lines +24 to +31
function lengowIsValidUrl(url) {
try {
var parsed = new URL(url, window.location.origin);
return parsed.protocol === 'http:' || parsed.protocol === 'https:';
} catch (e) {
return false;
}
}
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

lengowIsValidUrl() is duplicated across multiple admin JS files (order.js, feed.js, main_setting.js). Consider centralizing it into a shared module/global utility (e.g., views/js/lengow/admin.js) to avoid divergent behavior over time and simplify future security fixes.

Suggested change
function lengowIsValidUrl(url) {
try {
var parsed = new URL(url, window.location.origin);
return parsed.protocol === 'http:' || parsed.protocol === 'https:';
} catch (e) {
return false;
}
}
// Use a shared/global URL validation helper if available, otherwise define it once here.
if (typeof window.lengowIsValidUrl !== 'function') {
window.lengowIsValidUrl = function (url) {
try {
var parsed = new URL(url, window.location.origin);
return parsed.protocol === 'http:' || parsed.protocol === 'https:';
} catch (e) {
return false;
}
};
}
var lengowIsValidUrl = window.lengowIsValidUrl;

Copilot uses AI. Check for mistakes.
right: -16px;
}

.lgw-ps9-content:has(.lengow-nav-bottom) .cms-global {
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

The :has() selector still has uneven browser support depending on the embedded admin browser/WebView. If PrestaShop back-office needs to work in environments without :has(), this rule will be ignored and layout can regress. Add a non-:has() fallback (e.g., an extra wrapper class toggled server-side) so spacing doesn’t rely solely on :has().

Suggested change
.lgw-ps9-content:has(.lengow-nav-bottom) .cms-global {
.lgw-ps9-content:has(.lengow-nav-bottom) .cms-global,
.lgw-ps9-content.lgw-ps9-content--has-nav-bottom .cms-global {

Copilot uses AI. Check for mistakes.
Comment on lines +32 to +33
* - Symfony controllers call setContext() via the @required setter injection in
* AbstractLengowAdminController, ensuring the context is always wired on PS9.
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

The comment mentions “@required setter injection” in AbstractLengowAdminController, but the current implementation sets the context in the controller constructor. Update the docblock to reflect the actual wiring mechanism to avoid misleading future maintainers.

Suggested change
* - Symfony controllers call setContext() via the @required setter injection in
* AbstractLengowAdminController, ensuring the context is always wired on PS9.
* - Symfony controllers rely on AbstractLengowAdminController, which sets the
* context in its constructor to ensure the context is always wired on PS9.

Copilot uses AI. Check for mistakes.
private static function getIdOrderCarrier(int $orderId): int
{
$result = Db::getInstance()->getValue(
'SELECT id_order_carrier FROM ' . _DB_PREFIX_ . 'order_carrier WHERE id_order = ' . $orderId . ' ORDER BY id_order_carrier DESC'
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

This query uses ORDER BY ... DESC but no LIMIT 1. Since only a single value is needed, add LIMIT 1 to reduce unnecessary work and make intent explicit (especially if an order has multiple carriers).

Suggested change
'SELECT id_order_carrier FROM ' . _DB_PREFIX_ . 'order_carrier WHERE id_order = ' . $orderId . ' ORDER BY id_order_carrier DESC'
'SELECT id_order_carrier FROM ' . _DB_PREFIX_ . 'order_carrier WHERE id_order = ' . $orderId . ' ORDER BY id_order_carrier DESC LIMIT 1'

Copilot uses AI. Check for mistakes.
@A-Oudjat A-Oudjat requested a review from a team March 26, 2026 14:15
@arnaud-hours arnaud-hours merged commit 08dd4da into main Apr 2, 2026
2 checks passed
@arnaud-hours arnaud-hours deleted the feat/prestashop-9 branch April 2, 2026 10:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants