PrestaShop

Open-source e-commerce platform from France. Provides balance of usability and functionality for SMEs.

CMSE-commercePHPOpen SourceMulti-languageModuleTheme
License
OSL 3.0
Language
PHP
Pricing
コア機能無料
Official Site
Visit Official Site

CMS

PrestaShop

Overview

PrestaShop is an open-source e-commerce platform from France. It provides a balance of usability and functionality for small and medium businesses, particularly popular in the European market.

Details

PrestaShop is an open-source e-commerce platform developed in France in 2007. Provided under the OSL 3.0 license, it's used by over 300,000 active stores. With a 4% market share, it has a particularly strong presence in Europe. Developed in PHP and adopting Symfony framework components, it includes module systems, theme engines, multi-language and multi-currency support, SEO capabilities, inventory management, and reporting features necessary for SME e-commerce sites. Over 5,000 modules and 2,000 themes are available, enabling flexible customization. PrestaShop Cloud service is also offered, providing a SaaS option that includes hosting and maintenance. Supporting over 75 languages by default, it facilitates international expansion.

Pros and Cons

Pros

  • Free to Use: Core functionality is completely free
  • Multi-language Support: Standard support for over 75 languages facilitates international expansion
  • Rich Modules: Over 5,000 modules available for feature extension
  • Community Support: Active community and abundant resources
  • Intuitive Admin Panel: User-friendly interface for beginners
  • SEO Features: Built-in SEO optimization features
  • Responsive Ready: Abundant mobile-first themes

Cons

  • Limited Scalability: Not suitable for large-scale sites
  • Insufficient Technical Support: Limited official support for free version
  • Complex Configuration: Technical knowledge required for advanced customization
  • Performance Issues: Can be slow without optimization
  • Plugin Quality: Variable quality in third-party modules

Key Links

Usage Examples

Basic PrestaShop Module Structure

// modules/mymodule/mymodule.php
<?php
if (!defined('_PS_VERSION_')) {
    exit;
}

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

        parent::__construct();

        $this->displayName = $this->l('My Module');
        $this->description = $this->l('Description of my custom module');
        $this->confirmUninstall = $this->l('Are you sure you want to uninstall this module?');
    }

    public function install()
    {
        return parent::install() &&
            $this->registerHook('displayHeader') &&
            $this->registerHook('displayFooter') &&
            $this->createDatabaseTables() &&
            Configuration::updateValue('MYMODULE_CONFIG', 'default_value');
    }

    public function uninstall()
    {
        return parent::uninstall() &&
            $this->deleteDatabaseTables() &&
            Configuration::deleteByName('MYMODULE_CONFIG');
    }

    private function createDatabaseTables()
    {
        $sql = 'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'mymodule_data` (
            `id_mymodule` int(11) NOT NULL AUTO_INCREMENT,
            `id_product` int(11) NOT NULL,
            `custom_field` varchar(255) NOT NULL,
            `date_add` datetime NOT NULL,
            PRIMARY KEY (`id_mymodule`)
        ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8;';

        return Db::getInstance()->execute($sql);
    }
}

Using the Hook System

// Hook registration and implementation
class MyModule extends Module
{
    // Header hook (adding CSS/JS)
    public function hookDisplayHeader($params)
    {
        // Register CSS/JS files
        $this->context->controller->addCSS($this->_path . 'views/css/mymodule.css');
        $this->context->controller->addJS($this->_path . 'views/js/mymodule.js');
        
        // Pass variables to Smarty template
        $this->context->smarty->assign([
            'mymodule_message' => Configuration::get('MYMODULE_MESSAGE'),
            'mymodule_link' => $this->context->link->getModuleLink($this->name, 'display')
        ]);
        
        return $this->display(__FILE__, 'views/templates/hook/header.tpl');
    }
    
    // Product page hook
    public function hookDisplayProductAdditionalInfo($params)
    {
        $product = $params['product'];
        
        // Get custom data
        $sql = 'SELECT * FROM `' . _DB_PREFIX_ . 'mymodule_data` 
                WHERE `id_product` = ' . (int)$product['id_product'];
        $customData = Db::getInstance()->getRow($sql);
        
        $this->context->smarty->assign([
            'product' => $product,
            'custom_data' => $customData,
            'module_dir' => $this->_path
        ]);
        
        return $this->display(__FILE__, 'views/templates/hook/product-info.tpl');
    }
    
    // Cart update hook
    public function hookActionCartSave($params)
    {
        $cart = $params['cart'];
        
        // Log cart information
        PrestaShopLogger::addLog(
            'Cart updated: Cart ID ' . $cart->id,
            1,
            null,
            'Cart',
            $cart->id,
            true
        );
        
        // Custom processing (apply discounts, check inventory, etc.)
        $this->applyCustomDiscount($cart);
    }
    
    // Order validation hook
    public function hookActionValidateOrder($params)
    {
        $order = $params['order'];
        $customer = new Customer($order->id_customer);
        
        // Post-order processing (send emails, sync with external systems, etc.)
        $this->sendCustomOrderEmail($order, $customer);
        $this->syncWithExternalSystem($order);
    }
}

Admin Configuration Form

// Module configuration screen implementation
public function getContent()
{
    $output = '';
    
    // Form submission handling
    if (Tools::isSubmit('submit' . $this->name)) {
        $mymodule_message = Tools::getValue('MYMODULE_MESSAGE');
        $mymodule_enable = Tools::getValue('MYMODULE_ENABLE');
        
        // Validation
        if (!$mymodule_message || empty($mymodule_message)) {
            $output .= $this->displayError($this->l('Please enter a message'));
        } else {
            Configuration::updateValue('MYMODULE_MESSAGE', $mymodule_message);
            Configuration::updateValue('MYMODULE_ENABLE', $mymodule_enable);
            $output .= $this->displayConfirmation($this->l('Settings saved'));
        }
    }
    
    return $output . $this->displayForm();
}

public function displayForm()
{
    // Form field definition
    $fields_form = [
        'form' => [
            'legend' => [
                'title' => $this->l('Settings'),
                'icon' => 'icon-cogs'
            ],
            'input' => [
                [
                    'type' => 'text',
                    'label' => $this->l('Message'),
                    'name' => 'MYMODULE_MESSAGE',
                    'desc' => $this->l('Enter the message to display'),
                    'required' => true
                ],
                [
                    'type' => 'switch',
                    'label' => $this->l('Enable module'),
                    'name' => 'MYMODULE_ENABLE',
                    'is_bool' => true,
                    'values' => [
                        [
                            'id' => 'active_on',
                            'value' => 1,
                            'label' => $this->l('Enabled')
                        ],
                        [
                            'id' => 'active_off',
                            'value' => 0,
                            'label' => $this->l('Disabled')
                        ]
                    ]
                ]
            ],
            'submit' => [
                'title' => $this->l('Save'),
                'class' => 'btn btn-default pull-right'
            ]
        ]
    ];
    
    $helper = new HelperForm();
    $helper->submit_action = 'submit' . $this->name;
    $helper->currentIndex = $this->context->link->getAdminLink('AdminModules', false) . 
                           '&configure=' . $this->name;
    $helper->token = Tools::getAdminTokenLite('AdminModules');
    
    // Set form values
    $helper->fields_value['MYMODULE_MESSAGE'] = Configuration::get('MYMODULE_MESSAGE');
    $helper->fields_value['MYMODULE_ENABLE'] = Configuration::get('MYMODULE_ENABLE');
    
    return $helper->generateForm([$fields_form]);
}

Controller Implementation

// modules/mymodule/controllers/front/display.php
class MyModuleDisplayModuleFrontController extends ModuleFrontController
{
    public function initContent()
    {
        parent::initContent();
        
        // Get data
        $products = $this->getCustomProducts();
        $categories = Category::getCategories($this->context->language->id);
        
        // Pass variables to template
        $this->context->smarty->assign([
            'products' => $products,
            'categories' => $categories,
            'module_link' => $this->context->link->getModuleLink('mymodule', 'display'),
            'nb_products' => count($products)
        ]);
        
        // Set meta tags
        $this->context->smarty->assign('meta_title', $this->l('Custom Product List'));
        $this->context->smarty->assign('meta_description', $this->l('Custom product listing page'));
        
        $this->setTemplate('module:mymodule/views/templates/front/display.tpl');
    }
    
    private function getCustomProducts()
    {
        $sql = 'SELECT p.*, pl.name, pl.description_short, i.id_image
                FROM `' . _DB_PREFIX_ . 'product` p
                LEFT JOIN `' . _DB_PREFIX_ . 'product_lang` pl 
                    ON (p.id_product = pl.id_product AND pl.id_lang = ' . (int)$this->context->language->id . ')
                LEFT JOIN `' . _DB_PREFIX_ . 'image` i 
                    ON (i.id_product = p.id_product AND i.cover = 1)
                WHERE p.active = 1
                ORDER BY p.date_add DESC
                LIMIT 10';
        
        return Db::getInstance()->executeS($sql);
    }
}

Multi-language Support Implementation

// Translatable string definition
class MyModule extends Module
{
    public function __construct()
    {
        parent::__construct();
        
        // Multi-language support for basic information
        $this->displayName = $this->l('My Module');
        $this->description = $this->l('Description of my module');
    }
    
    // Translation file creation
    // translations/en.php
    global $_MODULE;
    $_MODULE = array();
    $_MODULE['<{mymodule}prestashop>mymodule_displayname'] = 'My Module';
    $_MODULE['<{mymodule}prestashop>mymodule_description'] = 'Description of my module';
    $_MODULE['<{mymodule}prestashop>mymodule_save'] = 'Save';
    $_MODULE['<{mymodule}prestashop>mymodule_settings'] = 'Settings';
    
    // Usage in templates
    // views/templates/front/display.tpl
    {l s='Welcome to our store' mod='mymodule'}
    {l s='You have %d products in your cart' sprintf=[$nb_products] mod='mymodule'}
}

Web Service API Implementation

// Web service API configuration
class MyModule extends Module
{
    public function install()
    {
        return parent::install() && $this->installWebservice();
    }
    
    private function installWebservice()
    {
        // Register web service resources
        $webservice_key = new WebserviceKey();
        $webservice_key->key = Tools::passwdGen(32);
        $webservice_key->description = 'My Module API Key';
        $webservice_key->add();
        
        // Set permissions
        $permissions = [
            'products' => ['GET' => 1, 'PUT' => 1, 'POST' => 1, 'DELETE' => 0],
            'categories' => ['GET' => 1, 'PUT' => 0, 'POST' => 0, 'DELETE' => 0],
            'customers' => ['GET' => 1, 'PUT' => 1, 'POST' => 0, 'DELETE' => 0]
        ];
        
        WebserviceKey::setPermissionForAccount($webservice_key->id, $permissions);
        
        Configuration::updateValue('MYMODULE_WEBSERVICE_KEY', $webservice_key->key);
        
        return true;
    }
    
    // Custom web service endpoint
    public function hookAddWebserviceResources($params)
    {
        return [
            'mymodule_custom' => [
                'description' => 'Custom resource',
                'class' => 'MyModuleCustom'
            ]
        ];
    }
}

// classes/webservice/MyModuleCustom.php
class MyModuleCustomWebservice extends ObjectModel
{
    public $id;
    public $name;
    public $value;
    public $date_add;
    
    public static $definition = [
        'table' => 'mymodule_custom',
        'primary' => 'id_custom',
        'fields' => [
            'name' => ['type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => true],
            'value' => ['type' => self::TYPE_STRING, 'validate' => 'isCleanHtml'],
            'date_add' => ['type' => self::TYPE_DATE, 'validate' => 'isDate']
        ]
    ];
}

These examples demonstrate PrestaShop's major development patterns. From module development, hook system, admin panel implementation, controller creation, multi-language support, to web service APIs, they cover the functionality needed for SME e-commerce site development.