🏪
Formularios multitienda — checkboxes y configuracion por tienda
Actualizado: 2024-12-01
En instalaciones multitienda, la configuracion de un modulo puede ser diferente por tienda. Un error comun es usar Configuration::updateValue('KEY', $value) sin tener en cuenta el contexto, lo que sobreescribe la configuracion de todas las tiendas a la vez.
#El problema multitienda en formularios
Configuration::updateValue sin contexto afecta a todas las tiendas
Si guardas Configuration::updateValue('MYKEY', $value) en el contexto 'ALL SHOPS', todas las tiendas veran ese valor aunque tengan su propia configuracion. Siempre pasa el id_shop correspondiente.
#Detectar el contexto multitienda
Detectar contexto y obtener el id_shop activo
php
<?php
// ¿Esta activa la funcion multitienda?
$isMultistoreActive = Shop::isFeatureActive();
// ¿En que contexto estamos?
$shopContext = Shop::getContext();
// Shop::CONTEXT_ALL → Todas las tiendas
// Shop::CONTEXT_GROUP → Grupo de tiendas
// Shop::CONTEXT_SHOP → Tienda especifica
// Obtener el id_shop activo (0 = global, >0 = tienda especifica)
$idShop = $this->context->shop->id; // ID de la tienda activa
$idShopGroup = $this->context->shop->id_shop_group;
// Para formularios de configuracion:
if (Shop::isFeatureActive() && Shop::getContext() == Shop::CONTEXT_SHOP) {
$idShop = (int) $this->context->shop->id;
} else {
$idShop = null; // Sin restriccion de tienda
}
#Guardar configuracion por tienda
Guardar configuracion respetando el contexto
php
<?php
/**
* Guardar configuracion de forma multitienda-safe.
*/
private function saveConfiguration(array $values): bool
{
foreach ($values as $key => $value) {
if (Shop::isFeatureActive()) {
$ctx = Shop::getContext();
if ($ctx == Shop::CONTEXT_SHOP) {
// Guardar solo para la tienda activa
Configuration::updateValue(
$key,
$value,
false, // html
null, // id_shop_group
(int) $this->context->shop->id // id_shop
);
} elseif ($ctx == Shop::CONTEXT_GROUP) {
// Guardar para el grupo de tiendas
Configuration::updateValue(
$key,
$value,
false,
(int) $this->context->shop->id_shop_group,
null
);
} else {
// Contexto ALL → guardar globalmente
Configuration::updateValue($key, $value);
}
} else {
// Sin multitienda → guardar globalmente
Configuration::updateValue($key, $value);
}
}
return true;
}
#Leer configuracion segun contexto
Leer configuracion con herencia de tiendas
php
<?php
// Leer con herencia: primero busca valor especifico de la tienda,
// si no existe, busca el del grupo, si no, el global
$value = Configuration::get('MY_KEY');
// Leer para una tienda especifica (sin herencia)
$valueForShop = Configuration::get('MY_KEY', null, null, 1); // id_shop = 1
// Leer para un grupo
$valueForGroup = Configuration::get('MY_KEY', null, 2, null); // id_shop_group = 2
// Verificar si tiene valor propio (no heredado)
$hasOwnValue = Configuration::hasContext('MY_KEY', null, Shop::CONTEXT_SHOP);
#Checkboxes multitienda en HelperForm
HelperForm con soporte multitienda automatico
php
<?php
protected function getConfigForm(): array
{
return [
'form' => [
'legend' => [
'title' => $this->trans('Configuration', [], 'Admin.Global'),
'icon' => 'icon-cogs',
],
'input' => [
[
'type' => 'switch',
'label' => $this->trans('Enable module', [], 'Admin.Global'),
'name' => 'MY_MODULE_ENABLED',
// Activar checkbox multitienda para este campo:
'class' => 't',
'is_bool' => true,
// PS mostrara el checkbox 'Todas las tiendas' automaticamente
// cuando multitienda esta activo
],
],
'submit' => ['title' => $this->trans('Save', [], 'Admin.Actions')],
],
];
}
protected function renderForm(): string
{
$helper = new HelperForm();
$helper->module = $this;
$helper->name_controller = $this->name;
$helper->token = Tools::getAdminTokenLite('AdminMyModule');
$helper->currentIndex = AdminController::$currentIndex . '&configure=' . $this->name;
// IMPORTANTE: registrar los ids para multitienda
if (Shop::isFeatureActive()) {
$helper->id_shop_list = Shop::getContextListShopID();
}
$helper->default_form_language = (int) $this->context->language->id;
$helper->fields_value = $this->getConfigValues();
return $helper->generateForm([$this->getConfigForm()]);
}
#Buenas practicas
| Practica | Descripcion |
|---|---|
| Siempre comprobar Shop::isFeatureActive() | No asumir que multitienda esta activo |
| Usar Shop::getContext() antes de guardar | Determinar el contexto correcto antes de updateValue() |
| Registrar la tienda en HelperForm | $helper->id_shop_list para los checkboxes automaticos |
| Definir valores por defecto en install() | Configuration::updateValue() en install() para todas las tiendas |
| Desinstalar por tiendas | Iterar todas las tiendas en uninstall() y borrar la config de cada una |
Descargar en Markdown
Pensado para pegar en ChatGPT, Claude u otra IA. Incluye solo el contenido de esta pagina.