PrestaShop

フランス発のオープンソースECプラットフォーム。中小企業向けに使いやすさと機能のバランスを提供。

CMSeコマースPHPオープンソース多言語対応モジュールテーマ
ライセンス
OSL 3.0
言語
PHP
料金
コア機能無料

CMS

PrestaShop

概要

PrestaShopは、フランス発のオープンソースECプラットフォームです。中小企業向けに使いやすさと機能のバランスを提供し、特に欧州市場で人気があります。

詳細

PrestaShop(プレスタショップ)は、2007年にフランスで開発されたオープンソースのECプラットフォームです。OSL 3.0ライセンスで提供され、300,000以上のアクティブストアで利用されています。市場シェアは4%で、特にヨーロッパで強い存在感を持っています。PHPで開発され、Symfonyフレームワークのコンポーネントを採用しています。モジュールシステム、テーマエンジン、多言語・多通貨対応、SEO対応、在庫管理、レポート機能など、中小企業のECサイトに必要な機能を備えています。5,000以上のモジュールと2,000以上のテーマが利用可能で、柔軟なカスタマイズが可能です。PrestaShop Cloudサービスも提供しており、ホスティングとメンテナンスを含むSaaSオプションも選択できます。標準で75言語以上に対応し、国際展開を容易にします。

メリット・デメリット

メリット

  • 無料利用可能: コア機能は完全無料で利用できる
  • 多言語対応: 75言語以上に標準対応し国際展開が容易
  • 豊富なモジュール: 5,000以上のモジュールで機能拡張可能
  • コミュニティサポート: 活発なコミュニティと豊富なリソース
  • 直感的な管理画面: 初心者でも使いやすいインターフェース
  • SEO機能: 標準でSEO最適化機能を搭載
  • レスポンシブ対応: モバイルファーストのテーマが豊富

デメリット

  • 限定的なスケーラビリティ: 大規模サイトには不向き
  • 技術サポート不足: 無料版では公式サポートが限定的
  • 複雑な設定: 高度なカスタマイズには技術知識が必要
  • パフォーマンス問題: 最適化なしでは速度が遅い場合がある
  • プラグイン品質: サードパーティ製モジュールの品質にばらつき

主要リンク

使い方の例

PrestaShopモジュールの基本構造

// 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('カスタムモジュールの説明');
        $this->confirmUninstall = $this->l('本当にこのモジュールをアンインストールしますか?');
    }

    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);
    }
}

フックシステムの活用

// フックの登録と実装
class MyModule extends Module
{
    // ヘッダーフック(CSS/JSの追加)
    public function hookDisplayHeader($params)
    {
        // CSS/JSファイルの登録
        $this->context->controller->addCSS($this->_path . 'views/css/mymodule.css');
        $this->context->controller->addJS($this->_path . 'views/js/mymodule.js');
        
        // Smartyテンプレートに変数を渡す
        $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');
    }
    
    // 商品ページフック
    public function hookDisplayProductAdditionalInfo($params)
    {
        $product = $params['product'];
        
        // カスタムデータの取得
        $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');
    }
    
    // カート更新フック
    public function hookActionCartSave($params)
    {
        $cart = $params['cart'];
        
        // カート情報をログに記録
        PrestaShopLogger::addLog(
            'カートが更新されました: Cart ID ' . $cart->id,
            1,
            null,
            'Cart',
            $cart->id,
            true
        );
        
        // カスタム処理(割引適用、在庫チェックなど)
        $this->applyCustomDiscount($cart);
    }
    
    // 注文確定後フック
    public function hookActionValidateOrder($params)
    {
        $order = $params['order'];
        $customer = new Customer($order->id_customer);
        
        // 注文後の処理(メール送信、外部API連携など)
        $this->sendCustomOrderEmail($order, $customer);
        $this->syncWithExternalSystem($order);
    }
}

管理画面の設定フォーム

// モジュール設定画面の実装
public function getContent()
{
    $output = '';
    
    // フォーム送信時の処理
    if (Tools::isSubmit('submit' . $this->name)) {
        $mymodule_message = Tools::getValue('MYMODULE_MESSAGE');
        $mymodule_enable = Tools::getValue('MYMODULE_ENABLE');
        
        // バリデーション
        if (!$mymodule_message || empty($mymodule_message)) {
            $output .= $this->displayError($this->l('メッセージを入力してください'));
        } else {
            Configuration::updateValue('MYMODULE_MESSAGE', $mymodule_message);
            Configuration::updateValue('MYMODULE_ENABLE', $mymodule_enable);
            $output .= $this->displayConfirmation($this->l('設定が保存されました'));
        }
    }
    
    return $output . $this->displayForm();
}

public function displayForm()
{
    // フォームフィールドの定義
    $fields_form = [
        'form' => [
            'legend' => [
                'title' => $this->l('設定'),
                'icon' => 'icon-cogs'
            ],
            'input' => [
                [
                    'type' => 'text',
                    'label' => $this->l('メッセージ'),
                    'name' => 'MYMODULE_MESSAGE',
                    'desc' => $this->l('表示するメッセージを入力してください'),
                    'required' => true
                ],
                [
                    'type' => 'switch',
                    'label' => $this->l('モジュールを有効化'),
                    'name' => 'MYMODULE_ENABLE',
                    'is_bool' => true,
                    'values' => [
                        [
                            'id' => 'active_on',
                            'value' => 1,
                            'label' => $this->l('有効')
                        ],
                        [
                            'id' => 'active_off',
                            'value' => 0,
                            'label' => $this->l('無効')
                        ]
                    ]
                ]
            ],
            'submit' => [
                'title' => $this->l('保存'),
                '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');
    
    // フォームの値を設定
    $helper->fields_value['MYMODULE_MESSAGE'] = Configuration::get('MYMODULE_MESSAGE');
    $helper->fields_value['MYMODULE_ENABLE'] = Configuration::get('MYMODULE_ENABLE');
    
    return $helper->generateForm([$fields_form]);
}

コントローラーの実装

// modules/mymodule/controllers/front/display.php
class MyModuleDisplayModuleFrontController extends ModuleFrontController
{
    public function initContent()
    {
        parent::initContent();
        
        // データの取得
        $products = $this->getCustomProducts();
        $categories = Category::getCategories($this->context->language->id);
        
        // テンプレートに変数を渡す
        $this->context->smarty->assign([
            'products' => $products,
            'categories' => $categories,
            'module_link' => $this->context->link->getModuleLink('mymodule', 'display'),
            'nb_products' => count($products)
        ]);
        
        // メタタグの設定
        $this->context->smarty->assign('meta_title', $this->l('カスタム商品一覧'));
        $this->context->smarty->assign('meta_description', $this->l('カスタム商品の一覧ページ'));
        
        $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);
    }
}

多言語対応の実装

// 翻訳可能な文字列の定義
class MyModule extends Module
{
    public function __construct()
    {
        parent::__construct();
        
        // 基本情報の多言語対応
        $this->displayName = $this->l('My Module');
        $this->description = $this->l('Description of my module');
    }
    
    // 翻訳ファイルの作成
    // translations/ja.php
    global $_MODULE;
    $_MODULE = array();
    $_MODULE['<{mymodule}prestashop>mymodule_displayname'] = '私のモジュール';
    $_MODULE['<{mymodule}prestashop>mymodule_description'] = '私のモジュールの説明';
    $_MODULE['<{mymodule}prestashop>mymodule_save'] = '保存';
    $_MODULE['<{mymodule}prestashop>mymodule_settings'] = '設定';
    
    // テンプレート内での使用
    // 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サービスAPIの実装

// WebサービスAPIの設定
class MyModule extends Module
{
    public function install()
    {
        return parent::install() && $this->installWebservice();
    }
    
    private function installWebservice()
    {
        // WebサービスリソースをJ録
        $webservice_key = new WebserviceKey();
        $webservice_key->key = Tools::passwdGen(32);
        $webservice_key->description = 'My Module API Key';
        $webservice_key->add();
        
        // パーミッションの設定
        $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;
    }
    
    // カスタムWebサービスエンドポイント
    public function hookAddWebserviceResources($params)
    {
        return [
            'mymodule_custom' => [
                'description' => 'カスタムリソース',
                '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']
        ]
    ];
}

これらの例は、PrestaShopの主要な開発パターンを示しています。モジュール開発、フックシステム、管理画面の実装、コントローラー作成、多言語対応、WebサービスAPIなど、中小企業向けECサイト開発に必要な機能を網羅しています。