Child pages
  • Specifics of multistore module development

Versions Compared


  • This line was added.
  • This line was removed.
  • Formatting was changed.


Usage of configuration variables

As indicated in the "Creating a PrestaShop module" chapter of this developer guide, some of the methods from the Configuration object have three optional parameters, which make it possible to target any other existing store on the current PrestaShop installation: id_shop, id_shop_group and id_lang.

While these can prove useful when having to handle multiple specific and know known stores from one of the presented Configuration method, they are generally not recommended for general usage. Your configuration code should only target the current store using the current Context, which every Configuration method does automatically.


Handling images and other types of files

Images can be defined on a per-store basis or per-store-group basis: a product an item can have a default image on one storemost stores on the PrestaShop installation, and another one image for a specific store.

In order to achieve that, the name of the image must be stored in a configuration variable. The default image is therefore then replaced on the fly by with the store-specific image.

Here is how the blockadvertising image Blockadvertising module does it.

First, here is how it saves a submitted file:

Code Block
titleSaving the file on a per-store basis
  // Saving only the main portion of the uploaded file's name, without the file extension.
    substr($_FILES['adv_img']['name'], strrpos($_FILES['adv_img']['name'], '.') + 1)

  // Setting the image's name with a name contextual to the shop context.
  $this->adv_imgname = 'advertising';

  // Creating two versions of the contextualimage name, depending on the store context.:
  if // If the context is the current group, use the image named 'advertising-g'
  // If the context is the current store, use the image named 'advertising-s'
  if (Shop::getContext() == Shop::CONTEXT_GROUP)
    $this->adv_imgname = 'advertising'.'-g'.(int)$this->context->shop->getContextShopGroupID();
  elseif (Shop::getContext() == Shop::CONTEXT_SHOP)
    $this->adv_imgname = 'advertising'.'-s'.(int)$this->context->shop->getContextShopID();

  // Copying the image in the module directory with its new contextual name.
  if (!move_uploaded_file($_FILES['adv_img']['tmp_name'], 
    $errors .= $this->l('File upload error.');

Second, here is how it decides which image to display:

Code Block
titleLoading the file on a per-store basis
protected function initialize()
  // Setting the main name of the image.
  $this->adv_imgname = 'advertising';

  // Setting the contextual name of the file, depending on the context.
  if ((Shop::getContext() == Shop::CONTEXT_GROUP  || Shop::getContext() == Shop::CONTEXT_SHOP)
    && file_exists(_PS_MODULE_DIR_.$this->name.'/'.$this->adv_imgname.'-g'
    $this->adv_imgname .= '-g'.$this->context->shop->getContextShopGroupID();
  if (Shop::getContext() == Shop::CONTEXT_SHOP
    && file_exists(_PS_MODULE_DIR_.$this->name.'/'.$this->adv_imgname.'-s'
    $this->adv_imgname .= '-s'.$this->context->shop->getContextShopID();
  $this->adv_img = Tools::getMediaServer($this->name)._MODULE_DIR_.$this->name.'/'


  • $share: is used to add a "WHERE" clause indicating that we are in the same group as the current store.
  • $alias: is used to set the table alias to which the WHERE clause should be applied.

For instance, this query retrieves visitor connections from a given shop:


Code Block
'SELECT date_add, COUNT(`date_add`) as total
 FROM `'._DB_PREFIX_.'connections`
 WHERE 1 '.Shop::addSqlRestriction();


Object in all stores

The method to use is Shop::addSqlAssociation($table, $alias, $inner_join = true, $on = null, $force_not_default = false).