Bienvenue, Invité
Merci de vous identifier ou de vous inscrire.    Mot de passe perdu?

[TUTO] Importer des options pour un attribut (très utile pour les produits configurables par exemple)
(1 lecteur(s)) (1) Invité(s)
Aller en basPage: 123
SUJET:

[TUTO] Importer des options pour un attribut (très utile pour les produits configurables par exemple)

#16687
zuiko
Moderator
Messages: 2865
graphgraph
Personne n'est hors ligne Cliquez ici pour voir le profil de cet utilisateur
Sexe: Masculin

[TUTO] Importer des options pour un attribut (très utile pour les produits configurables par exemple)

Il y a 9 Années
Karma: 85  
INTRODUCTION

Ce TUTO intéressera particulièrement ceux qui sont confrontés à la création de produits configurables avec une option aux très nombreuses valeurs. Par exemple vendre un chapeau en 400 couleurs possibles (si, si çà existe je vous assure .
En effet un produit configurable est d'abord composé de produits simples. Vous me direz, puisque l'importation de produits est native à Magento, pas de problèmes... En fait si on fait naïvement l'essai, on n'aura effectivement aucun problème à importer ses 400 chapeaux à partir d'un fichier CSV patiemment concocté sous Excel ou Calc d'Openoffice.
Seulement au moment de constituer son produit configurable on tombera vite sur le fait qu'il faudra au préalable créer les 400 couleurs comme options d'un attribut couleur. Magento n'étant pas fichu de relier ces produits simples à ce produit configurable sans çà. Le courageux se lance à corps perdu... Le paresseux... réfléchi : il y a surement quelqu'un dans la communauté qui a trouvé une solution pour contourner cet obstacle titanesque. En fait, cette personne existe et je l'ai rencontrée sur le forum officiel de Magento. Sa méthode consiste à importer ces options pour un attribut donné. C'est bien sûr un palliatif à une fonction qui devrait être native à Magento et vous verrez assez vite que bien qu'étant parfaitement fonctionnelle il lui manque encore quelques neurones pour les adeptes du multiboutique/multilingue (on ne sait pas, encore, importer les variantes d'appellation des options).
D'autre part on s'apercevra qu'après avoir réussi à importer ses options pour son attribut, et avoir affecté celui-ci à son produit configurable il se trouve (1.3.2.1) que Magento est capable de générer automatiquement les produits simples correspondant avec les SKU qui vont bien donc nul besoin de s'embêter à les créer pour les importer. Au pire on pourra jouer, après avoir créé ces produits simples, à les exporter, modifier le fichier CSV sous Calc (Stock, libellés etc) puis les réimporter par la fonction native qui marche très bien.

Après cette introduction situant la zone d'intérêt de ce tuto, puisque Gabriel me le demande si gentiment, voici replacé ici ce que j'ai pu écrire dans un autre fil et qui décrit la solution technique.

pour l'importation d'options d'attribut j'ai trouvé un fil sur le forum anglais
http://www.magentocommerce.com/boards/viewthread/9391/P0/
qui propose une solution que j'ai testée (sur des petites quantités d'options après avoir modifié le fichier import.php qui comportait un ; baladeur.
La solution est décomposée en plusieurs fichiers dont je propose le mode d'emploi ci-dessous et le contenu en fin de post.

    Fichier 1 : On place le fichier ImpAttributes.php à la racine, il sera donc accessible via :
    <your website>/ImpAttributes.php
    par exemple (à protéger sur site réel pour exécution par CRON seulement).
    L'option d'attribut aura au préalable été créée et on connaitra son attribute_id qui devra être modifié dans le fichier à l'instruction :
    $obj->saveOptionValues(502); //502 for “couleur_chapeau” // 66 for manufacturer
    Pour connnaitre l'attribute_id d'une option, utiliser PhpMyAdmin et rechercher dans la table eav_attribute à l'aide de l'attribute_code.

    Fichier 2 : On place Import.php dans app\code\core\Mage\Eav\Model

    Fichier 3 : On insère les valeurs que l'on veut importer dans un fichier CSV importAttrib.csv que l'on place dans var/import. La première ligne doit obligatoirement contenir "admin" . Les autres lignes les valeurs des options.

    “admin”
    “Blanc”
    “Noir”
    “Rouge”
    ...
    .
    ...
    Les valeurs seront toutes encadrées de guillemets doubles, toutes les données sont du texte pur en UTF8. Openoffice Calc fait çà très bien.
    Si les valeurs existent elles ne sont pas effacées ni ajoutées en double. On peut donc relancer le fichier autant qu'on veut.

    On importe ces options d'attribut en accédant à l'URL
    <your website>/ImpAttributes.php

    Fichier 4 : classementoptionattribut.sql pour ordonner ensuite les options par ordre alphabétique en prenant la précaution de changer l'attribute_id pour traiter la bonne option. Le fichier se télécharge sous PhpMyAdmin pour être lancé sur la table Magento.


Les fichiers :

ImpAttributes.php

Code :

<?php
define('MAGENTO', realpath(dirname(__FILE__)));
ini_set('memory_limit', '32M');
set_time_limit (0);
require_once MAGENTO . '/app/Mage.php';
Mage::app();
echo 1;
try {
  $obj = new Mage_Eav_Model_Import(MAGENTO);
  echo 2;
  $obj->saveOptionValues(502); //502 for “couleur_chapeau” // 66 for manufacturer 
echo 3;  
  } catch (Exception $e) {
    echo $e->getMessage();




Import.php

Code :

<?php
class Mage_Eav_Model_Import extends Mage_Eav_Model_Mysql4_Entity_Attribute
{
  private $fileName ;
  private $delimiter = '|';
  private $enclosure = '"';
    public function __construct($baseDirectory)
    {
      parent::__construct();
      $this->fileName = $baseDirectory . '/var/import/importAttrib.csv';
      echo $this->fileName;
    }

  private function &getCsv() {
    $file = fopen($this->fileName,"r");
    while(! feof($file))
    {
      $csvArr[] = fgetcsv($file, 0, $this->delimiter, $this->enclosure);
    }

    fclose($file);
    return $csvArr;
  }

  protected function populateOptionTable($attribId) {
echo "Upload Begin";  

    $fields = array();
    $values = array (); // store id => values
    $optionValues = array (); // option id => $values
    $option = array ('value' => $optionValues);    
    $updateOptionValId;
    $values = null;
    $row = null;
    $disCounter = 0;
    
    $optionTable        = $this->getTable('attribute_option');
    $optionValueTable   = $this->getTable('attribute_option_value');
    $write = $this->_getWriteAdapter();
    $csvStoreArr = array();

    // Get CSV into Array
    $csv = & $this->getCsv();

    $read = $this->_getReadAdapter();

    // exit if the csv file is empty or if it contains only the headers
    if (count($csv) < 1 or count($csv) == 1) return;

    $fields = $csv[0]; // get the field headers from first row of CSV

    // get the store Ids
    $stores = Mage::getModel('core/store')
                ->getResourceCollection()
                ->setLoadDefault(true)
                ->load();

    // determine the stores for which option values are being uploaded for
    foreach ($fields as $hdr) {
      if($hdr === 'position' || $hdr === 'isDefault' || $hdr === 'ERROR') {   
        continue;
      }
      foreach ($stores as $store) {
        if ($store->getCode() === $hdr) $csvStoreArr[$hdr] = $store->getId();
      }
    }  
    // start reading the option values - from row 1 (note that 0 represents headers)
    for ($indx=1;$indx<count($csv);$indx++) {
      $values = null; // initialize to null
      $row = $csv[$indx]; // get row

      if(isset($row) && count($row) > 0) {
       
        //escape the single quote
        //$whereParam = $read->quote($row);
        
        
        if (is_array($row)) $whereParam = '(\''.implode($row,'\',\'').'\')';
        else if  (strlen($row)) $whereParam = '(\''.$row.'\')';
        
        $select = $read->select()->from(array('vals' => $optionValueTable))
                ->join(array('opt' => $optionTable),'opt.option_id=vals.option_id')
                ->where('opt.attribute_id=?', $attribId);
        $select = $select
                ->where('vals.value in ' . $whereParam);

        $optionValData = $read->fetchAll($select);

       unset($select);

       // get the option Id for this option
       if (count($optionValData) > 0) {
         $optionValDataRow = $optionValData[0];
         $optionId = $optionValDataRow['option_id'];
       } else $optionId = null;

        $intOptionId = (int) $optionId;

        if (!$intOptionId) {
          $data = array(
                         'attribute_id'  => $attribId,
                         'sort_order'    => isset($option['order'][$optionId]) ? $option['order'][$optionId] : 0,
                        );
          try{
            $write->insert($optionTable, $data);
            $intOptionId = $write->lastInsertId();
          } catch (Exception $e) { Mage::log($e->getMessage()); }
        } else {
            $data = array(
                           'sort_order'    => isset($option['order'][$optionId]) ? $option['order'][$optionId] : 0,
                        );
            $write->update($optionTable, $data, $write->quoteInto('option_id=?', $intOptionId));
        }

          $colIndx = 0; //initialize row's column index
        if (isset($row) && is_array($row) && count($row) > 0) {
          foreach($row as $optVal) {
            if ($fields[$colIndx] !== 'position' || $fields[$colIndx] !== 'isDefault' || $fields[$colIndx] !== 'ERROR') {
                $values[$csvStoreArr[$fields[$colIndx]]] = $optVal; // store id => option value
            }
            $colIndx++;
          }
        }
      }

      
      if (isset($values) && is_array($values) && count($values) > 0) {
        foreach ($values as $storeId => $value) {
          if (!empty($value) || strlen($value) > 0) {
            $value = trim($value);
            $data = array(
                      'option_id' => $intOptionId,
                      'store_id'  => $storeId,
                      'value'     => $value,
                  );
            $optionValInsert = true;
            $optionValUpdate = false;

            foreach ($optionValData as $valData) {
              if ((int)$valData['option_id'] === $intOptionId &&
                    (int)$valData['store_id'] === $storeId) {
                $optionValInsert = false;
                if (strcasecmp(trim($valData['value']), $value) !== 0) {
                  $optionValUpdate = true;
                    $updateOptionValId = $valData['value_id'];
                }
                break;
              }
            }

          if ($optionValInsert) {
             $write->insert($optionValueTable, $data);
             Mage::log('Inserted Value -'.$value);
          } else if ($optionValUpdate) {
             $write->update($optionValueTable, $data, $write->quoteInto('option_id=?', $updateOptionValId));
             Mage::log('Updated Value -'.$value) 


importAttrib.csv

Code :

“admin”
“Blanc”
“Noir”
“Rouge”
...
.
... 



classementoptionattribut.sql
Code :


#Query to alphabetically sort options for an attribute ID
SET @a=-1, @attribute_to_sort=502; # '502' est pour couleur_chapeau, à changer selon vos besoins
CREATE TEMPORARY TABLE ReOrder 
SELECT (@a:=@a+1) AS RowNum, eav_attribute_option.option_id as ThisOptionID FROM eav_attribute_option LEFT JOIN eav_attribute_option_value ON eav_attribute_option.option_id=eav_attribute_option_value.option_id 
WHERE eav_attribute_option.attribute_id=@attribute_to_sort AND value IS NOT NULL 
ORDER BY value;
UPDATE eav_attribute_option, ReOrder SET sort_order= RowNum*10 WHERE option_id= ThisOptionID;



A expérimenter avec vos propre tests bien sûr...

Et si quelqu'un pouvait aller plus loin, c'est à dire jusqu'à l'importation des libellés en multiboutique/multivues, ce serait le top (il faudrait que le fichier importAttrib.csv comporte autant de colonnes que de vues magasin).


Je répète qu'à mon avis cette fonctionnalité devrait être intégrée au core tant elle devient vite indispensable à ceux qui vendent des produits un tout petit peu complexes.
 
Dernière édition: 10/07/09 à  17:28 Par zuiko.
Souvent support de mes exemples et conseils cette mercerie en ligne aux produits pro, au thème devenu responsive mobile en avril 2015.
L'administrateur a désactivé l'accès public en écriture.
#16705
Gabriiiel
I love Magento.
Expert Magento
Messages: 4118
graph
Personne n'est hors ligne Cliquez ici pour voir le profil de cet utilisateur
Sexe: Masculin gabriel.bouhatous Formation Magento Audit Conseil gabriel.bouhatous Ask me :) Lieu: Paris

Re:[TUTO] Importer des options pour un attribut (très utile pour les produits configurables par exemple)

Il y a 9 Années
Karma: 112  
Je pense que ce sera intégré à un moment ou à un autre ou sous forme de module, en tout cas super tuto ;)
 
Expert Magento @ The e-Commerce Academy

L'administrateur a désactivé l'accès public en écriture.
#37105
zuiko
Moderator
Messages: 2865
graphgraph
Personne n'est hors ligne Cliquez ici pour voir le profil de cet utilisateur
Sexe: Masculin

Re:[TUTO] Importer des options pour un attribut (très utile pour les produits configurables par exemple)

Il y a 7 Années, 10 Mois
Karma: 85  
Je ne l'avais pas écrit mais çà marche bien aussi en multiboutiques/multilangues, surtout quand on a découvert que le séparateur de champ du fichier CSV est | ce qui est assez inhabituel.
Il suffit donc de formater son fichier csv ainsi :
Code :


“admin”|"shop-fr"|"shop-en"
“Blanc”|"Blanc"|"White"
“Noir”|"Noir"|"Black"
“Rouge”|"Rouge"|"Red"
...


et bien sûr de l'enregistrer en UTF-8.
shop-fr et shop-en sont les codes des vues de la boutique.
 
Souvent support de mes exemples et conseils cette mercerie en ligne aux produits pro, au thème devenu responsive mobile en avril 2015.
L'administrateur a désactivé l'accès public en écriture.
#38185
MiisterTii
Fresh Boarder
Messages: 10
graphgraph
Personne n'est hors ligne Cliquez ici pour voir le profil de cet utilisateur

Re:[TUTO] Importer des options pour un attribut (très utile pour les produits configurables par exemple)

Il y a 7 Années, 9 Mois
Karma: 0  
Petite précision, le fichier Import.php qui été mentionné par Zuiko n'est pas le bon.
En effet, il a été modifié après sur le forum Anglais.

Je vous met le bon fichier en pièce jointe.

Peace
++

Miister Tii Fichier réservé aux membres.
Veuillez vous connecter ou vous enregistrer.
 
Dernière édition: 15/10/10 à  10:36 Par MiisterTii.
L'administrateur a désactivé l'accès public en écriture.
#38186
zuiko
Moderator
Messages: 2865
graphgraph
Personne n'est hors ligne Cliquez ici pour voir le profil de cet utilisateur
Sexe: Masculin

Re:[TUTO] Importer des options pour un attribut (très utile pour les produits configurables par exemple)

Il y a 7 Années, 9 Mois
Karma: 85  
Exact, j'avais oublié la mise à jour, heureusement que j'avais indiqué le lien.
 
Souvent support de mes exemples et conseils cette mercerie en ligne aux produits pro, au thème devenu responsive mobile en avril 2015.
L'administrateur a désactivé l'accès public en écriture.
#52750
lolvinc
Junior Boarder
Messages: 37
graphgraph
Personne n'est hors ligne Cliquez ici pour voir le profil de cet utilisateur

Re:[TUTO] Importer des options pour un attribut (très utile pour les produits configurables par exemple)

Il y a 6 Années, 10 Mois
Karma: 0  
Bonjour,

tout d'abord merci pour la procédure d'import.

quelques petites questions :

où sont censés arrivés les attributs importés ?
à quel attribut se rattachent-ils par défaut ?
Un nouvel attribut est-il créé à chaque import ?

Ensuite j'ai testé sur ma version locale et ai obtenu le message suivant :

111/Applications/MAMP/htdocs/magento/var/import/importAttrib.csv2Reading file contents - /Applications/MAMP/htdocs/magento/var/import/importAttrib.csvUpload BeginSQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`magento`.`eav_attribute_option_value`, CONSTRAINT `FK_EAV_ATTR_OPT_VAL_OPT_ID_EAV_ATTR_OPT_OPT_ID` FOREIGN KEY (`option_id`) REFERENCES `eav_attribute_option` (`option_id`) ON DELETE CASCADE )

une idée du problème rencontré ?


merci de votre aide.
 
L'administrateur a désactivé l'accès public en écriture.
#52752
zuiko
Moderator
Messages: 2865
graphgraph
Personne n'est hors ligne Cliquez ici pour voir le profil de cet utilisateur
Sexe: Masculin

Re:[TUTO] Importer des options pour un attribut (très utile pour les produits configurables par exemple)

Il y a 6 Années, 10 Mois
Karma: 85  
Bonjour,

ce script importe des valeurs pour un attribut donné, défini dans le script ImpAttributes.php :

L'attribut aura au préalable été créé sous Magento à la main et on connaitra son attribute_id qui devra être modifié dans le script à l'instruction :
$obj->saveOptionValues(502); //502 for “couleur_chapeau” // 66 for manufacturer
Pour connnaitre l'attribute_id d'un attribut, utiliser PhpMyAdmin et rechercher dans la table eav_attribute à l'aide de l'attribute_code (qu'on a donné dans l'interface de création de l'attribut).

Si tu n'as pas modifié le script avec ton attribute_id, il n'est pas étonnant que cela ne fonctionne pas.

Depuis ce TUTO, Magmi (le script d'importation) a été mis au point et sait créer les valeurs d'attributs à la volée à l'importation des produits. En mono store cela peut suffire. En multistore/multiview, avec nécessité de traduire les valeurs d'attribut, le script de ce TUTO garde son intérêt.
 
Souvent support de mes exemples et conseils cette mercerie en ligne aux produits pro, au thème devenu responsive mobile en avril 2015.
L'administrateur a désactivé l'accès public en écriture.
#52820
lolvinc
Junior Boarder
Messages: 37
graphgraph
Personne n'est hors ligne Cliquez ici pour voir le profil de cet utilisateur

Re:[TUTO] Importer des options pour un attribut (très utile pour les produits configurables par exemple)

Il y a 6 Années, 10 Mois
Karma: 0  
Merci pour ce retour au sujet de Magmi. Je vais tester cette solution. Existe-t-il un tuto disponible en Fr ou EN pour utiliser correctement Magmi ?

Bonne journée.
 
L'administrateur a désactivé l'accès public en écriture.
Revenir en hautPage: 123
Modérateur: Gabriiiel, ILOA, zuiko