Aller au contenu principal

Ajouter un champ personnalisé à la fiche produit en back-office (PrestaShop 1.7)

Fiche écrite en 2021, pour les navigateurs et les versions de l’époque. Vérifiez qu’elle correspond encore à votre environnement avant de l’appliquer.

Délai de fabrication, référence fournisseur, mention réglementaire : il manque souvent un champ à la fiche produit. La tentation est d’ajouter une colonne à ps_product et un override de la classe Product. C’est plus robuste de laisser le cœur tranquille : une table propre au module, trois hooks, et le champ apparaît dans l’onglet « Modules » de la fiche produit.

PHP
public function install()
{
    return parent::install()
        && Db::getInstance()->execute('
            CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'w4u_produit` (
                `id_product`        INT UNSIGNED NOT NULL PRIMARY KEY,
                `delai_fabrication` VARCHAR(64)  NOT NULL DEFAULT ""
            ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8mb4')
        && $this->registerHook('displayAdminProductsExtra')
        && $this->registerHook('actionProductUpdate')
        && $this->registerHook('displayProductAdditionalInfo');
}

public function hookDisplayAdminProductsExtra(array $params)
{
    $this->context->smarty->assign('delai', $this->lireDelai((int) $params['id_product']));

    return $this->display(__FILE__, 'views/templates/admin/champ.tpl');
}

public function hookActionProductUpdate(array $params)
{
    $delai = Tools::getValue('w4u_delai_fabrication');
    if ($delai === false) {
        return; // mise à jour venue d'un import ou de l'API : on ne touche à rien
    }
    Db::getInstance()->execute('
        REPLACE INTO `' . _DB_PREFIX_ . 'w4u_produit` (id_product, delai_fabrication)
        VALUES (' . (int) $params['id_product'] . ', "' . pSQL($delai) . '")');
}

public function hookDisplayProductAdditionalInfo(array $params)
{
    $delai = $this->lireDelai((int) $params['product']['id_product']);

    return $delai === '' ? '' : '<p class="w4u-delai">Délai de fabrication : ' . Tools::safeOutput($delai) . '</p>';
}

private function lireDelai($idProduit)
{
    return (string) Db::getInstance()->getValue('
        SELECT delai_fabrication FROM `' . _DB_PREFIX_ . 'w4u_produit`
        WHERE id_product = ' . (int) $idProduit);
}

Le test $delai === false dans actionProductUpdate est essentiel : ce hook se déclenche aussi lors des imports CSV et des mises à jour par l’API, où le champ n’est pas envoyé. Sans ce test, chaque import viderait les délais saisis. Toutes les valeurs passent par pSQL() et un transtypage en entier avant d’atteindre la base.

Smarty
{* views/templates/admin/champ.tpl *}
<div class="form-group">
  <label class="form-control-label" for="w4u_delai_fabrication">Délai de fabrication</label>
  <input type="text" class="form-control" id="w4u_delai_fabrication"
        name="w4u_delai_fabrication" value="{$delai|escape:'html':'UTF-8'}">
</div>

Sources

  1. Documentation développeur PrestaShop 1.7, liste des hooks devdocs.prestashop-project.org