# Prestashop

> This skill should be used when the user asks to "create a PrestaShop module", "build a PrestaShop extension", "PrestaShop hooks", "PrestaShop webservices API", "PrestaShop admin controller", "PrestaShop payment module", "publish to PrestaShop Addons marketplace", or needs guidance on PrestaShop module development.

- Skill: `biggora/prestashop` (Agent Skill, multi-file: 6 files)
- Install (CLI): `npx skillmds@latest add biggora/prestashop`
- Raw SKILL.md: https://api.skillmd.com/api/skills/biggora/prestashop/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Integrations & APIs
- Author: biggora (https://skillmd.com/u/biggora)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/biggora/prestashop

---


# PrestaShop Module Development

## Overview

PrestaShop is an open-source PHP e-commerce platform that has undergone significant architectural evolution. PrestaShop 1.7+ introduced Symfony components for the back office, and PrestaShop 8.x completed the transition to a Symfony-first architecture for all admin pages. Modules remain the primary extension mechanism, built as self-contained PHP packages that integrate through a powerful hook system, ObjectModel ORM (legacy), Doctrine ORM (modern), and Symfony service containers.

A PrestaShop module is a directory inside `/modules/` containing at minimum a main PHP class file and a `config.xml` descriptor. The main class extends `Module` and implements `install()`, `uninstall()`, and hook callback methods. Modules can add admin pages, modify the storefront, extend the checkout, integrate payment gateways, add shipping carriers, and interact with the PrestaShop webservices API.

PrestaShop 8.x runs on PHP 7.2.5+ (PHP 8.1 recommended), Symfony 4.4, and supports MySQL 5.6+ or MariaDB 10.x. The template engine is Smarty for the front office and Twig for the back office (Symfony controllers). Understanding both rendering engines is essential for full-stack module development.

For detailed directory structure, module lifecycle, ObjectModel, and Doctrine entity patterns, see [references/module-architecture.md](references/module-architecture.md).

## Module Structure

Every module follows a predictable directory layout. The module name must match the directory name and the main class name, using lowercase alphanumeric characters and underscores only.

### Main Module File

The main file (`mymodule.php`) defines a class extending `Module`. The constructor sets metadata:

```php
class MyModule extends Module
{
    public function __construct()
    {
        $this->name = 'mymodule';
        $this->tab = 'front_office_features';
        $this->version = '1.0.0';
        $this->author = 'Author Name';
        $this->need_instance = 0;
        $this->ps_versions_compliancy = ['min' => '1.7.0.0', 'max' => '8.99.99'];
        $this->bootstrap = true;

        parent::__construct();

        $this->displayName = $this->l('My Module');
        $this->description = $this->l('Module description.');
    }
}
```

### config.xml

PrestaShop reads `config.xml` to display module information in the back office before loading PHP. This file mirrors the constructor metadata and is auto-generated on first install but should be maintained manually for marketplace submissions.

### composer.json

Modern modules include `composer.json` for autoloading and dependency management. Use PSR-4 autoloading to organize classes into namespaces. Register the autoloader in the main module file or rely on PrestaShop's module autoloader for simple structures.

### Controllers

Modules can register front controllers (customer-facing pages) and admin controllers (back office pages). Front controllers extend `ModuleFrontController` and live in `controllers/front/`. Admin controllers extend `ModuleAdminController` (legacy) or use Symfony controllers with routes defined in `config/routes.yml`.

### Views

Template files for the front office use Smarty (`.tpl` extension) stored in `views/templates/front/`. Admin templates for Symfony controllers use Twig (`.html.twig`) stored in `views/templates/admin/`. CSS and JavaScript assets go in `views/css/` and `views/js/`.

For the complete directory tree and file conventions, see [references/module-architecture.md](references/module-architecture.md).

## Hook System

Hooks are the primary integration mechanism in PrestaShop. They allow modules to inject content into specific locations (display hooks) or react to system events (action hooks). PrestaShop defines hundreds of hooks across the front office, back office, and core business logic.

### Display Hooks

Display hooks inject HTML at specific template positions:

- `displayHeader` -- Add CSS/JS to the page `<head>`.
- `displayHome` -- Render content on the homepage.
- `displayProductExtraContent` -- Add tabs or sections to the product page.
- `displayShoppingCartFooter` -- Add content below the cart summary.
- `displayPaymentReturn` -- Show confirmation content after payment.
- `displayBackOfficeHeader` -- Add assets to the admin header.

### Action Hooks

Action hooks fire when business events occur:

- `actionProductSave` -- Triggered after a product is saved in the back office.
- `actionOrderStatusUpdate` -- Triggered when an order status changes.
- `actionCartSave` -- Triggered when the cart is modified.
- `actionCustomerAccountAdd` -- Triggered when a new customer registers.
- `actionValidateOrder` -- Triggered during order validation (before finalization).

### Hook Registration

Register hooks in the `install()` method. Every hook the module uses must be explicitly registered:

```php
public function install()
{
    return parent::install()
        && $this->registerHook('displayHome')
        && $this->registerHook('actionOrderStatusUpdate');
}
```

Implement the hook callback as a method named `hook` + hook name (camelCase):

```php
public function hookDisplayHome($params)
{
    $this->context->smarty->assign(['variable' => 'value']);
    return $this->display(__FILE__, 'views/templates/front/home.tpl');
}
```

For the complete hook catalog, custom hook creation, and advanced registration patterns, see [references/hooks-reference.md](references/hooks-reference.md).

## Development Setup

### Docker Environment

Use the official PrestaShop Docker image for local development:

```yaml
services:
  prestashop:
    image: prestashop/prestashop:8-apache
    ports:
      - "8080:80"
    environment:
      DB_SERVER: db
      DB_NAME: prestashop
      DB_USER: root
      DB_PASSWD: admin
      PS_INSTALL_AUTO: 1
      PS_DOMAIN: localhost:8080
      PS_FOLDER_ADMIN: admin-dev
    volumes:
      - ./modules/mymodule:/var/www/html/modules/mymodule
    depends_on:
      - db
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: admin
      MYSQL_DATABASE: prestashop
```

Mount the module directory as a volume to enable live code reloading. Access the admin panel at `http://localhost:8080/admin-dev`.

### Module Generator

Use the PrestaShop module generator to scaffold a new module:

```bash
# Install the generator globally
composer global require prestashop/module-generator

# Generate a module skeleton
prestashop:module:generate mymodule
```

Alternatively, copy a minimal module template and customize. Enable debug mode in `config/defines.inc.php` by setting `_PS_MODE_DEV_` to `true` for detailed error reporting during development.

### Development Tools

- **PrestaShop Console** -- CLI tool for cache clearing, module installation, and database migrations.
- **Symfony Debug Toolbar** -- Available in the back office when debug mode is enabled. Shows queries, hooks, and service container.
- **PHP CS Fixer** -- Use the PrestaShop coding standards configuration for consistent formatting.

## Key Integration Patterns

### Payment Modules

Payment modules extend `PaymentModule` and implement specific hooks and interfaces. The payment flow in PrestaShop 1.7+/8.x uses the `paymentOptions` hook:

```php
public function hookPaymentOptions($params)
{
    $option = new PrestaShop\PrestaShop\Core\Payment\PaymentOption();
    $option->setModuleName($this->name)
           ->setCallToActionText($this->l('Pay by Card'))
           ->setAction($this->context->link->getModuleLink($this->name, 'validation', [], true));

    return [$option];
}
```

Implement a validation front controller that processes the payment, calls the gateway API, and uses `$this->module->validateOrder()` to create the order. Handle success, failure, and pending states. Store the transaction ID on the order for reference.

### Carrier Modules

Carrier modules extend `CarrierModule` and implement `getOrderShippingCost()` and `getOrderShippingCostExternal()`. Register the carrier in `install()` using the `Carrier` ObjectModel. Return shipping rates based on cart weight, dimensions, and destination.

### Admin Controllers

Legacy admin controllers extend `ModuleAdminController` and use `HelperForm` and `HelperList` for rendering. Modern modules should use Symfony controllers with Twig templates and register routes in `config/routes.yml`. Both approaches are covered in detail in [references/admin-and-backoffice.md](references/admin-and-backoffice.md).

## Symfony Integration (PrestaShop 8.x)

PrestaShop 8.x embraces Symfony conventions for back office development. Modules can define services, use dependency injection, register Symfony routes, and render Twig templates.

### Service Definition

Define services in `config/services.yml`:

```yaml
services:
  mymodule.product_service:
    class: MyModule\Service\ProductService
    arguments:
      - '@doctrine.orm.entity_manager'
      - '@prestashop.adapter.legacy.context'
```

### Routing

Register routes in `config/routes.yml`:

```yaml
mymodule_admin_settings:
  path: /mymodule/settings
  methods: [GET, POST]
  defaults:
    _controller: 'MyModule\Controller\Admin\SettingsController::indexAction'
    _legacy_controller: AdminMyModuleSettings
    _legacy_link: AdminMyModuleSettings
```

### Modern Controllers

Symfony controllers extend `FrameworkBundleAdminController` and use Twig for rendering:

```php
use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController;

class SettingsController extends FrameworkBundleAdminController
{
    public function indexAction(Request $request)
    {
        return $this->render('@Modules/mymodule/views/templates/admin/settings.html.twig', [
            'layoutTitle' => 'My Module Settings',
        ]);
    }
}
```

For complete Symfony integration patterns including form handling, CQRS commands, and Grid components, see [references/admin-and-backoffice.md](references/admin-and-backoffice.md).

## Webservices API

PrestaShop includes a built-in REST-like webservices API for external integrations. The API exposes resources (products, orders, customers, categories) as XML or JSON endpoints with API key authentication.

Modules can extend the webservices by registering custom resources through the `addWebserviceResources` hook. This allows external systems to interact with module-specific data through the standard PrestaShop API.

For complete webservices documentation including CRUD operations, filtering, and custom resource creation, see [references/webservices-api.md](references/webservices-api.md).

## Anti-Patterns

Avoid these common mistakes in PrestaShop module development:

- **Direct database queries bypassing ObjectModel** -- Use `ObjectModel` subclasses or Doctrine entities for data access. Raw SQL creates upgrade fragility and skips validation hooks.
- **Overriding core classes** -- PrestaShop supports class overrides in `/override/`, but overrides conflict between modules and break on core updates. Use hooks instead.
- **Hardcoded SQL table prefixes** -- Always use `_DB_PREFIX_` constant. PrestaShop installations may use custom table prefixes.
- **Ignoring multishop context** -- PrestaShop supports multiple shops from a single installation. Always check `Shop::getContext()` and scope queries to the active shop.
- **Storing configuration in files** -- Use `Configuration::updateValue()` and `Configuration::get()` for module settings. File-based config breaks in multi-server and multishop environments.
- **Skipping uninstall cleanup** -- Remove database tables, configuration values, hooks, and tabs in `uninstall()`. Leftover data causes errors on reinstall.
- **Using deprecated payment hooks** -- PrestaShop 1.7+ replaced `displayPayment` and `displayPaymentEU` with `paymentOptions`. Use the modern approach for compatibility.

For deeper guidance on each anti-pattern and recommended alternatives, consult the relevant reference files linked throughout this document.

## Reference Files

- [Module Architecture](references/module-architecture.md) -- Directory structure, module lifecycle, ObjectModel, Doctrine entities, configuration management, auto-upgrade
- [Hooks Reference](references/hooks-reference.md) -- Display hooks, action hooks, custom hooks, hook registration, widget hooks, dynamic hooks
- [Webservices API](references/webservices-api.md) -- REST API, XML/JSON output, API key auth, resource endpoints, CRUD operations, filtering, custom resources
- [Admin and Back Office](references/admin-and-backoffice.md) -- Legacy vs Symfony controllers, HelperForm, HelperList, Twig templates, Grid components, module configuration pages
- [Marketplace Publishing](references/marketplace-publishing.md) -- PrestaShop Addons submission, technical validation, module checker, documentation requirements, pricing, version compatibility

