---
title: Overrides blindados — instalacion sin conflictos
section: trucos
slug: safe-overrides
description: Tecnica profesional para instalar overrides de PrestaShop evitando el sistema nativo installOverrides() que puede bloquear la tienda al detectar conflictos. Metodo de copia manual blindado.
keywords: prestashop overrides blindados sin conflictos installOverrides class_index override seguro
last_updated: 2024-12-01
source_url: "https://ayudaprestashop.es/trucos/safe-overrides"
---

# Overrides blindados — instalacion sin conflictos

> Tecnica profesional para instalar overrides de PrestaShop evitando el sistema nativo installOverrides() que puede bloquear la tienda al detectar conflictos. Metodo de copia manual blindado.

> **[TIP] Tecnica profesional**
>
> Esta tecnica evita uno de los errores mas comunes en produccion: el bloqueo de instalacion de modulos por conflicto de overrides. Es la aproximacion recomendada para modulos que deben coexistir con otros en tiendas de clientes.

## El problema con installOverrides()

El sistema nativo `installOverrides()` de PrestaShop detecta si otro modulo ya ha overrideado la misma clase o metodo. Si hay conflicto, **bloquea la instalacion del modulo**. En tiendas con muchos modulos, esto es un problema frecuente.

> **[!!] Escenario de fallo tipico**
>
> Modulo A ya overridea `Product::getProductProperties()`. Cuando el cliente intenta instalar tu Modulo B que tambien overridea ese metodo, PrestaShop bloquea la instalacion con el error: **"Override conflict in class Product"**. El cliente no puede instalar tu modulo.

## La solucion: copia manual blindada

En lugar de usar el directorio `override/` del modulo (que activa el sistema nativo), guardamos los overrides en un directorio personalizado (ej. `override_v8/`) y los copiamos manualmente durante la instalacion, **solo si no existe ya el fichero destino**. No hay deteccion de conflictos, no hay bloqueo.

## Implementacion completa

*Estructura de directorios del modulo*

```php
mymodule/
├── mymodule.php          # Archivo principal
├── override_v8/          # Overrides propios (NO usar 'override/')
│   └── classes/
│       └── Product.php
└── ...
```

*mymodule.php — instalacion y desinstalacion seguras*

```php
<?php

declare(strict_types=1);

if (!defined('_PS_VERSION_')) {
    exit;
}

class MyModule extends Module
{
    public function __construct()
    {
        $this->name    = 'mymodule';
        $this->tab     = 'front_office_features';
        $this->version = '1.0.0';
        parent::__construct();
    }

    public function install(): bool
    {
        return parent::install()
            && $this->registerHook('actionFrontControllerSetMedia')
            && $this->installSafeOverrides();
    }

    public function uninstall(): bool
    {
        $this->uninstallSafeOverrides();
        return parent::uninstall();
    }

    /**
     * Copia overrides manualmente SIN usar installOverrides().
     * Solo copia si el fichero destino NO existe todavia.
     */
    private function installSafeOverrides(): bool
    {
        $overrides = [
            'classes/Product.php',
            // Añadir mas ficheros aqui
        ];

        foreach ($overrides as $path) {
            $source      = _PS_MODULE_DIR_ . $this->name . '/override_v8/' . $path;
            $destination = _PS_ROOT_DIR_ . '/override/' . $path;

            if (!file_exists($source)) {
                continue; // El override no existe en el modulo
            }

            if (!file_exists($destination)) {
                $dir = dirname($destination);
                if (!is_dir($dir)) {
                    mkdir($dir, 0755, true);
                }
                copy($source, $destination);
            }
            // Si ya existe, lo dejamos (podria ser de otro modulo)
        }

        // Limpiar class_index para que PS reconozca los nuevos overrides
        $this->clearClassIndex();

        return true;
    }

    /**
     * Elimina overrides SOLO si son identicos a los del modulo.
     * Nunca elimina overrides modificados por otros.
     */
    private function uninstallSafeOverrides(): void
    {
        $overrides = [
            'classes/Product.php',
        ];

        foreach ($overrides as $path) {
            $source      = _PS_MODULE_DIR_ . $this->name . '/override_v8/' . $path;
            $destination = _PS_ROOT_DIR_ . '/override/' . $path;

            if (file_exists($destination) && file_exists($source)) {
                // Solo eliminar si el contenido coincide exactamente con el nuestro
                if (md5_file($destination) === md5_file($source)) {
                    @unlink($destination);
                }
            }
        }

        $this->clearClassIndex();
    }

    private function clearClassIndex(): void
    {
        // PS 8/9 — rutas de cache
        $cachePaths = [
            _PS_ROOT_DIR_ . '/var/cache/prod/class_index.php',
            _PS_ROOT_DIR_ . '/var/cache/dev/class_index.php',
        ];
        foreach ($cachePaths as $path) {
            if (file_exists($path)) {
                @unlink($path);
            }
        }
    }
}
```

## Extender ObjectModel con override

Cuando haces override de un `ObjectModel` para añadir campos propios, debes actualizar el array `$definition` en el constructor antes de llamar al padre.

*override_v8/classes/Product.php*

```php
<?php

if (!defined('_PS_VERSION_')) {
    exit;
}

/**
 * IMPORTANTE:
 * - No usar namespace en overrides
 * - No usar ::class  (usar get_class() para PHP 7.4 compat)
 * - No poner closing PHP tag
 */
class Product extends ProductCore
{
    /** @var string Nuestro campo extra */
    public $my_custom_field;

    public function __construct(
        $id = null,
        $id_lang = null,
        $id_shop = null
    ) {
        // Añadir campo al definition ANTES de llamar al parent
        self::$definition['fields']['my_custom_field'] = [
            'type'     => self::TYPE_STRING,
            'validate' => 'isCleanHtml',
            'size'     => 255,
            'lang'     => false,
            'shop'     => true,  // respeta multitienda
        ];

        parent::__construct($id, $id_lang, $id_shop);
    }
}
```

## Reglas de oro

| Regla | Razon |
| --- | --- |
| Nunca usar `installOverrides()` en prod | Bloquea la instalacion en caso de conflicto |
| Nunca usar namespace en ficheros de override | PrestaShop espera clases sin namespace en /override/ |
| Nunca usar `::class` en overrides | Compatibilidad con PHP 7.4, usar get_class() |
| Comprobar que el fichero fuente existe | El modulo podria instalarse en PS 9 sin el override_v8 |
| Limpiar class_index despues de copiar | PS no reconoce nuevos overrides sin regenerar el indice |
| Solo eliminar si el contenido coincide | Otro modulo podria haber modificado el fichero |
| Dejar el fichero si ya existe en /override/ | No asumir que somos los unicos duenos del override |


---

*Fuente: [https://ayudaprestashop.es/trucos/safe-overrides](https://ayudaprestashop.es/trucos/safe-overrides). Version Markdown generada automaticamente para consumo por LLMs.*
