websenso/prestashop-module-devtools

Tools & script to automatically fix code for PrestaShop modules.

Maintainers

Package info

gitlab.com/JeffWebsenso/ws-module-devtools

Issues

pkg:composer/websenso/prestashop-module-devtools

Transparency log

Statistics

Installs: 811

Dependents: 0

Suggesters: 0

Stars: 1

1.4.4 2026-08-25 10:15 UTC

This package is auto-updated.

Last update: 2026-08-25 08:31:16 UTC


README

The ultimate PrestaShop developer tool to test and fix module source code to best fit the PrestaShop Online Module Validator standards.

Support

Built for PrestaShop 8.x & 9.x

Installation

1. Add as a Composer dev dependency

From your module root, run:

composer require --dev websenso/prestashop-module-devtools:^1

Or add it manually to your composer.json:

"require-dev": {
    "websenso/prestashop-module-devtools": "^1"
}

Then run composer install.

2. Run the setup command

After installation, run the setup command from your module root to:

  • Create the validator-api config file and optionally save your API key
  • Download and install the prestashop-module-development skill (via npx skills add if available, or a sparse git clone fallback from jeffsenso/prestashop-skills)
  • Download the PrestaShop 9 core AI context into skills/<skill-path>/ps9-core-ai/ (sparse clone of the .ai/ folder from PrestaShop/PrestaShop@develop)
  • Optional: Install official PrestaShop AI skills via npx skills add prestashop/skills (requires Node.js v22+)
  • Write .instructions.md (AI coding assistant instructions) to your project root, pointing to the installed skill path
  • Copy .gitlab-ci.yml (example CI pipeline) to your project root
  • Optionally install git pre-commit hooks for automatic documentation validation
php vendor/bin/lotr --install

Note: The optional official PrestaShop skills installation requires Node.js v22 or higher. If Node is not available or the version is too old, this step will be skipped automatically.

.instructions.md is always overwritten with the correct skill path. The skill and ps9-core-ai/ prompt to update if already present. All other files are only created if they do not already exist.

Re-run lotr --install at any time to update the skill and ps9-core-ai/ to the latest version.

3. Configure the licence header stamp

Edit vendor/websenso/prestashop-module-devtools/header-stamp/license_header.txt to set your licence header. Optionally edit license_header_phpDocs.txt as well.

4. Validator API key (online validation only)

If you skipped the API key during --install, edit: vendor/websenso/prestashop-module-devtools/validator-api/config/config.yaml

Get a free API key from https://validator.prestashop.com/.

5. GitLab pipeline

An example CI pipeline for PHP 8 / PrestaShop 8 is available at: vendor/websenso/prestashop-module-devtools/gitlab/.gitlab-ci.yml

It is automatically copied to your project root by --install.

6. Git pre-commit hooks (optional)

LOTR includes an optional pre-commit hook that ensures documentation files are updated when code changes are committed.

Features:

  • Detects code changes (PHP, JS, TS, etc.)
  • Warns if CHANGELOG.md, README.md, or AGENT.md/CLAUDE.md are not updated
  • Offers to launch AI documentation assistant via bin/lotr-update-docs
  • Can be bypassed with git commit --no-verify if intentional

Installation:

During lotr --install, you'll be prompted to enable git hooks. You can also install manually:

# Automatic (recommended)
php vendor/bin/lotr --install
# Select 'yes' when prompted about git hooks

# Manual installation
git config core.hooksPath .githook_template
chmod +x .githook_template/pre-commit

Documentation Auto-Update:

When the pre-commit hook detects missing documentation updates, you can choose [update] to launch the AI assistant:

bin/lotr-update-docs

This script:

  • Analyzes your staged changes
  • Creates an AI prompt with the git diff
  • Uses GitHub Copilot CLI or VS Code to update CHANGELOG.md, README.md, and AGENT.md
  • Applies changes automatically (no manual editing needed)

Requirements:

  • GitHub CLI with Copilot: gh extension install github/gh-copilot
  • OR VS Code with GitHub Copilot extension

See .githook_template/README.md for details.

7. Troubleshooting: Guzzle Autoload Conflict (PS 9.1+)

If you encounter this error after running lotr --install:

"PrestaShop\Module\Mbo\Addons\ApiClient" has a dependency on a non-existent service "Psr\Http\Client\ClientInterface"

This occurs because PrestaShop 9.1+ automatically loads vendor/autoload.php from your module, and the devtools Guzzle version conflicts with PrestaShop's bundled Guzzle.

Solution: Use a selective autoloader that loads only your module's namespaces (not devtools dependencies).

See the complete solution with implementation steps: restore-autoload-example/README.md

Quick steps:

  1. Copy restore-autoload-example/restore-autoload.php to your module's scripts/ folder
  2. Add the post-autoload-dump script to your composer.json (see example README)
  3. Run composer dump-autoload

This generates a production-safe autoloader that won't conflict with PrestaShop core.

Usage

Run from your module root:

php vendor/bin/lotr
php vendor/bin/lotr --dry-run

LOTR Options

FlagEffect
(none)Apply all fixes
--dry-runPreview changes without writing anything
--installSet up config and copy example files to project root
--releaseCreate a release ZIP after all tools pass
--validate-onlineSubmit the ZIP to validator.prestashop.com
--release --validate-onlineFull release workflow

What LOTR Runs

  1. AutoIndex

    vendor/bin/autoindex prestashop:add:index --exclude=vendor,tests,.devtools,_dev
    
  2. Header Stamp

    php vendor/websenso/prestashop-module-devtools/header-stamp/bin/smart-header-stamp [--dry-run]
    
  3. PS Version Checker

    php vendor/websenso/prestashop-module-devtools/psversion-checker/bin/psversion-checker fix [--dry-run]
    
  4. PS Validator

    php vendor/websenso/prestashop-module-devtools/homemade-ps-validator/bin/homemade-ps-validator validate [--dry-run]
    
  5. PHPStan

    _PS_ROOT_DIR_=<prestashop_root> vendor/bin/phpstan analyse --configuration=vendor/websenso/prestashop-module-devtools/phpstan/phpstan.neon
    
  6. PHP-CS-Fixer

    vendor/bin/php-cs-fixer fix --config=vendor/websenso/prestashop-module-devtools/.php-cs-fixer.dist.php [--dry-run]
    

After all steps pass, optional post-processing runs:

  1. Release ZIP creator (with --release)

    php vendor/websenso/prestashop-module-devtools/release-zip-creator/bin/create-release
    
  2. Online validation (with --validate-online)

    php vendor/websenso/prestashop-module-devtools/validator-api/bin/validate-online
    

AI Assistant integration

Quick start — add your naming conventions: Edit vendor/websenso/prestashop-module-devtools/steering/frameworks/prestashop/custom-patterns.md to set your table prefix, admin tab group, and namespace. The AI assistant loads this file automatically on every task.

The package ships a steering layer (always available in vendor/) and --install downloads two more context layers. Together they write a .instructions.md to your project root that tells the AI assistant to load all three before starting any task.

Note: skills/ is intentionally empty in the Composer package. Skills are never bundled — they are always downloaded fresh by lotr --install.

Layer 0 — Steering (shipped with the package)

Included in the Composer package at vendor/websenso/prestashop-module-devtools/steering/. No download required.

FileTopic
steering/resolver.mdLoad order and conflict resolution rules
steering/frameworks/prestashop/architecture.mdModule layout, DI, Doctrine ORM, FixturesInstaller, theme template injection, translations, Grid gotchas
steering/frameworks/prestashop/coding-standards.mdPHPCS, Symfony patterns, SQL rules, forbidden list
steering/frameworks/prestashop/custom-patterns.mdCompany-specific conventions: table prefix, admin tab group, namespace, validation, service guard patterns

custom-patterns.md ships with Websenso defaults. To apply your own team's naming conventions, edit the file directly at:

vendor/websenso/prestashop-module-devtools/steering/frameworks/prestashop/custom-patterns.md

For per-module overrides (e.g. a specific module that deviates from the team standard), use layer 4: create .ai/projects/<module-slug>/project-context.md at your project root. Rules defined there win over custom-patterns.md.

Layer 1 — prestashop-module-development skill

Downloaded from jeffsenso/prestashop-skills:

  • Primary: npx skills add → installs to skills/.agents/skills/prestashop-module-development/
  • Fallback: sparse git clone → installs to skills/prestashop-module-development/

The .instructions.md written to your project root is automatically updated to point to whichever path was used.

Layer 2 — PrestaShop 9 core AI context (ps9-core-ai/)

Sparse-cloned from PrestaShop/PrestaShop@develop (.ai/ sub-tree only). Placed at skills/<skill-path>/ps9-core-ai/. Provides domain and component contexts for the entire PS9 codebase (~50 domains: CQRS commands, Grid, Forms, Customer, Product, Order, …). Re-run lotr --install at any time to update it.

The installed skill (SKILL.md) is a lean index that delegates to topic-specific reference files under references/:

FileTopic
module-structure.mdFolder layout, namespace, autoloading
module-class-and-installer.mdMain class, hooks, installTabs() / uninstallTabs()
database-and-entities.mdObjectModel vs Doctrine overview
entity-doctrine.mdDoctrine ORM pattern: entity naming, ws_ prefix, Repository, Manager
grid-system.mdGrid definition, QueryBuilder, filters, position
configuration-page.mdSymfony form-based config page with FormHandler + constructor DI pattern
services-and-di.mdservices.yml, common.yml, factory registration, controller DI
translations.mdTrans domains, catalogue extraction
hooks-and-front-office.mdHook registration, front-office rendering
security.mdCSRF, SQL injection, input validation
legacy-conversion.mdMigrating from ObjectModel / legacy controllers
debugging.mdPHPStan, cache clearing, Symfony debug tools
validation.mdlotr pipeline, PS validator rules

Key rules enforced by the skill

  • No raw SQL outside Repository, Manager, or SqlQueries.php (CREATE/DROP only) — applies to FixturesInstaller, Installer, hooks, and widget methods too.
  • Controllers have a limited service locatorFrameworkBundleAdminController can only access core Symfony services (form.factory, http_kernel, router, etc.), NOT custom module services. ALWAYS use constructor dependency injection for controllers. Register controllers with public: true and controller.service_arguments tag.
  • Configuration pages use FormHandler pattern — 5-class pattern: DataConfiguration → FormDataProvider → FormType → FormHandler → Controller (with constructor DI). NEVER use $this->get('mymodule.service') in controllers — inject via constructor instead.
  • Services splitconfig/common.yml for Doctrine-only dependencies (both kernels); config/admin/services.yml for admin-only services; config/front/services.yml for front-office services. Do NOT create a root-level config/services.yml.
  • Service guard — admin: $this->has() ternary + early return; front-office: plain $this->get() + null check. Never use ContainerFinder.
  • FixturesInstaller must use Db::getInstance() raw SQL — SymfonyContainer::getInstance() returns null in the pr:mo console context, making all Doctrine ORM calls silently no-ops. Db::getValue() appends LIMIT 1 internally — never add it manually.
  • Theme template injection — PS8 does not support theme overrides from modules; use marker-based file patching. Two-class design: ThemeTemplateInjector (service) + ThemeTemplateInstaller (orchestrator). Never use Theme::getThemes() — use scandir(_PS_ALL_THEMES_DIR_) instead.
  • No getTabs() in the main module class — manage tabs via Installer::installTabs() / uninstallTabs().
  • Entity class name = table name without _DB_PREFIX_ — Doctrine derives the table name from the class name. Table prefix convention is defined in steering/frameworks/prestashop/custom-patterns.md.
  • FrameworkBundleAdminController::trans() parameter order is ($id, $domain, $parameters) — NOT Symfony's standard order. Never pass [] as domain.

Contributing

Contributions are welcome! This project is a work in progress and new features, fixes, and improvements are continuously being added.

To report a bug, request a feature, or track ongoing work, please visit the issue tracker: https://gitlab.com/JeffWebsenso/ws-module-devtools/-/work_items