Search code examples
phpprestashop-1.7

Prestashop - php script to add attachements to product


I've created a php script that allows me to add attachments to products that have already been imported (see below). Everything works fine, the 3 tables ps_attachemnt, lang... are filled in correctly. In the back office, in the product file, in the 'options' tab, I can see that my attachment is ticked.

Problem : I can't see it in the front end (on the product file) EXCEPT if I click on : Preview and/or Save.

Action taken :

  1. Empty cache
  2. Delete the cache folders in var/cache ( dev / prod)
  3. Create a php script that uses the save() function; ($product->save();)

Does anyone have any clues?

Thank you ;)

<?php
$csvFile = "xxxx.csv";
if (($handle = fopen($csvFile, "r")) !== FALSE) {
// Parcours des lignes du fichier CSV
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {

   $reference = $data[0]; // Référence du produit
   $files = explode(",", $data[1]); // Chemins vers les fichiers (séparés par une virgule)

   // Récupération de l'ID du produit
   $sql = "SELECT id_product FROM ps_product WHERE reference = '$reference'";
   $result = $conn->query($sql);

   echo "$reference";

   if ($result->num_rows > 0) {
       $row = $result->fetch_assoc();
       $productId = $row["id_product"];

       echo "$productId";

       // Parcours des fichiers joints
       foreach ($files as $file) {
           // Obtention de la taille du fichier en octets
           $fileSize = filesize($file);
           $fileName = basename($file); // Nom du fichier

           // Vérification si le fichier existe déjà pour le produit donné
           $sqlCheck = "SELECT id_attachment FROM ps_product_attachment WHERE id_product = '$productId'";
           $resultCheck = $conn->query($sqlCheck);

           $attachmentId = null;

           if ($resultCheck->num_rows > 0) {
               // Parcourir les résultats pour vérifier si le fichier existe déjà
               while ($rowCheck = $resultCheck->fetch_assoc()) {
                   $existingAttachmentId = $rowCheck["id_attachment"];

                   // Vérifier si le fichier est déjà associé au produit
                   $sqlFileCheck = "SELECT id_attachment FROM ps_attachment WHERE id_attachment = '$existingAttachmentId' AND file = '$file'";
                   $resultFileCheck = $conn->query($sqlFileCheck);

                   if ($resultFileCheck->num_rows > 0) {
                       // Le fichier existe déjà pour le produit donné
                       $attachmentId = $existingAttachmentId;
                       break;
                   }
               }
           }

           if ($attachmentId === null) {
               // Le fichier n'existe pas encore pour le produit, l'insérer dans ps_attachment
               $sqlInsertAttachment = "INSERT INTO ps_attachment (file, file_name, file_size, mime) VALUES ('$file', '$fileName', '$fileSize', 'application/pdf')";
               if ($conn->query($sqlInsertAttachment) === TRUE) {
                   $attachmentId = $conn->insert_id;
               } else {
                   echo "Erreur lors de l'ajout du fichier joint : " . $conn->error . "\n";
               }
           }

           if ($attachmentId !== null) {
               // Associer le fichier joint au produit dans ps_product_attachment
               $sqlInsertProductAttachment = "INSERT INTO ps_product_attachment (id_product, id_attachment) VALUES ('$productId', '$attachmentId')";
               if ($conn->query($sqlInsertProductAttachment) === TRUE) {
                   echo "Fichier joint ajouté avec succès pour le produit $reference.\n";

                   // Récupération de l'ID de l'attachment après insertion
                   $idAttachment = $attachmentId;

                   // Parcours des langues prises en charge
                   $idLang = 1;
                   $name = $data[$idLang]; // Récupération du nom du fichier joint dans la langue spécifiée
                   $description = $data[$idLang]; // Récupération de la description du fichier joint dans la langue spécifiée

                   // Insertion des informations de langue dans la table ps_attachment_lang
                   $sqlInsertAttachmentLang = "INSERT INTO ps_attachment_lang (id_attachment, id_lang, name, description) VALUES ('$idAttachment', '$idLang', '$name', '$description')";
                   if ($conn->query($sqlInsertAttachmentLang) === TRUE) {
                       echo "Informations de langue ajoutées avec succès pour l'attachment $idAttachment et la langue $idLang.\n";
                   } else {
                       echo "Erreur lors de l'ajout des informations de langue : " . $conn->error . "\n";
                   }
               } else {
                   echo "Erreur lors de l'association du fichier joint pour le produit $reference : " . $conn->error . "\n";
               }
           }
       }
   } else {
       echo "Produit non trouvé pour la référence : $reference.\n";
   }
}
fclose($handle);
}

$conn->close();

?>

Update script try :

<?php

require(dirname(__FILE__).'/config/config.inc.php');

define('_PS_ROOT_DIR_', dirname(dirname(__FILE__)).'/');
// Inclusion de la classe Product
require_once _PS_ROOT_DIR_ . '/classes/Product.php';

// Liste des références de produits à cibler
$targetReferences = array(
'20052'
);

foreach ($targetReferences as $reference) {
// Recherche du produit par référence
$productId = Product::getIdByReference($reference);

if ($productId) {
    $product = new Product($productId);

    // Enregistrer les options sans modification
    $product->save();



    echo "Produit mis à jour pour la référence : " . $reference . 
"<br>";
} else {
    // Gérer le cas où la référence du produit n'est pas trouvée
    echo "Produit non trouvé pour la référence : " . $reference . 
"<br>";
}
}

?>

Solution

  • Make sure to set the property

    $product->cache_has_attachments = 1;
    

    before saving the product.

    I encountered the same issue some time ago, and it took me quite a while to figure it out :)