PrestaShop Website Development
PrestaShop is an open-source PHP framework optimized for e-commerce. Current stable branch 8.x is based on Symfony components, Doctrine ORM for some entities, and proprietary ObjectModel legacy core for catalog. This architectural duality is the key characteristic to account for during development.
Architecture and Stack
PrestaShop 8.x uses:
- PHP 8.1–8.2, Symfony 4.4 (components), partial Symfony DI
- Smarty 3 for front-office templates, Twig for back-office (Symfony)
-
MySQL/MariaDB—primary database, heavy use of
PREFIX_*tables - Doctrine ORM—only for new admin entities
- ObjectModel—legacy Active Record for all products, categories, orders
- Hook system—primary extension mechanism
Directory structure:
/
├── classes/ # ObjectModel entities (Product, Category, Order...)
├── controllers/ # Front-office controllers (FrontController)
├── modules/ # Third-party and custom modules
├── themes/ # Front-office themes (Smarty)
├── src/ # Symfony-style code (PrestaShop\PrestaShop\...)
├── admin-dev/ # Back-office (Symfony + Twig)
└── override/ # Core class overrides
Data Models and Catalog Work
All product work uses ObjectModel. Example of fetching and saving:
// Get product with translations
$product = new Product($id, true, $langId, $shopId);
echo $product->name; // localized string
echo $product->price; // base price without tax
echo $product->getPrice(); // with taxes and discounts
// Bulk fetch via static methods
$products = Product::getProducts(
$langId,
$page * $limit, // offset
$limit,
'id_product', // orderBy
'ASC',
$categoryId
);
For custom entities, extend ObjectModel:
class CustomAttribute extends ObjectModel
{
public $id_custom_attribute;
public $name;
public $value;
public $active;
public static $definition = [
'table' => 'custom_attribute',
'primary' => 'id_custom_attribute',
'multilang' => true,
'fields' => [
'active' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool'],
'name' => ['type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'required' => true, 'size' => 128],
'value' => ['type' => self::TYPE_STRING, 'lang' => true, 'size' => 255],
],
];
}
Controllers and Routing
Front-office routing in PrestaShop works via dispatcher + FrontController. URL rules set in dispatcher.php and meta table:
// Custom front-office controller
class CustomPageModuleFrontController extends ModuleFrontController
{
public $ssl = true;
public $display_column_left = false;
public function initContent()
{
parent::initContent();
$items = Db::getInstance()->executeS(
'SELECT * FROM `' . _DB_PREFIX_ . 'custom_items` WHERE `active` = 1'
);
$this->context->smarty->assign([
'items' => $items,
'pageTitle' => $this->trans('Custom Page', [], 'Modules.Custommodule.Shop'),
]);
$this->setTemplate('module:custommodule/views/templates/front/custom_page.tpl');
}
}
Hooks and Module Architecture
Hooks are the central extension pattern. Proper hook usage determines module compatibility with core updates:
class CustomModule extends Module
{
public function __construct()
{
$this->name = 'custommodule';
$this->tab = 'front_office_features';
$this->version = '1.0.0';
$this->author = 'Company';
$this->need_instance = 0;
$this->ps_versions_compliancy = ['min' => '8.0.0', 'max' => _PS_VERSION_];
parent::__construct();
}
public function install(): bool
{
return parent::install()
&& $this->registerHook('actionProductAdd')
&& $this->registerHook('displayProductAdditionalInfo')
&& $this->installDb();
}
public function hookDisplayProductAdditionalInfo(array $params): string
{
$product = $params['product'];
$this->smarty->assign('custom_data', $this->getCustomData($product['id_product']));
return $this->display(__FILE__, 'views/templates/hook/product_info.tpl');
}
}
Performance and Caching
PrestaShop supports multiple caching layers:
- CCC (Combine, Compress, Cache)—combine CSS/JS
- Smarty cache—compiled template cache
- Page cache—via modules (PrestaShop PageCache, built-in PS 8)
- Object cache—Redis/Memcached
// Redis configuration in app/config/parameters.php
parameters:
cache_driver: 'redis'
cache_server: '127.0.0.1'
cache_port: 6379
cache_prefix: '_PRESTASHOP_'
// Programmatic cache in module
$cacheKey = 'module_data_' . $productId . '_' . $langId;
if (!Cache::isStored($cacheKey)) {
$data = $this->fetchExpensiveData($productId);
Cache::store($cacheKey, $data);
} else {
$data = Cache::retrieve($cacheKey);
}
Multi-Store Support
PrestaShop manages multiple stores from one admin. Store context affects all queries:
// Bind data to specific shop
Shop::setContext(Shop::CONTEXT_SHOP, $shopId);
// Shop-dependent record
$product = new Product(null, false, null, $shopId);
$product->name[$langId] = 'Name for store ' . $shopId;
$product->price = 999.00;
$product->id_shop_default = $shopId;
$product->save();
Typical Development Timeline
- Basic store with standard theme customization: 3–5 weeks
- Store with custom theme and business-logic modules: 6–10 weeks
- Migration from other platform (WooCommerce, OpenCart): 4–8 weeks
- Multi-store configuration with different catalogs: +2–3 weeks to base development







