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

[TUTO] Moteur de recherche plus pertinent
(1 lecteur(s)) (1) Invité(s)
Aller en basPage: 1
SUJET:

[TUTO] Moteur de recherche plus pertinent

#55043
mparis
Junior Boarder
Messages: 25
graphgraph
Personne n'est hors ligne Cliquez ici pour voir le profil de cet utilisateur

[TUTO] Moteur de recherche plus pertinent

Il y a 6 Années, 10 Mois
Karma: 2  
Bonjour à tous.

Comme chacun le sait, le moteur de recherche de Magento n'est pas très pertinent dans ses recherches. On peut même dire que parfois il est complètement à coté.
J'ai donc créé un module permettant d'amélioré grandement celui-ci. Bien entendu, mon code peut être largement amélioré mais c'est un bon axe de recherche.
Pour expliquer le fonctionnement du module, il faut d'abord bien comprendre le fonctionnement du moteur de magento, le "Engine FullText" .
Magento a une table nommé catalogsearch_fulltext qui stock tous les produits_id, leur store_id et une colonne regroupant tous les attributs produits utilisé dans la recherche produits concaténés ensemble (séparé par des '|').

Lorsqu'un internaute tape la recherche suivante "ampoule LED", le moteur effectue la requête suivante :
Code :

SELECT `s`.`product_id`, MATCH (`s`.`data_index`) AGAINST ('ampoule LED') 
FROM catalogsearch_fulltext WHERE (MATCH (`s`.`data_index`) AGAINST ('ampoule LED') OR (`s`.`data_index` LIKE '%ampoule%' OR `s`.`data_index` LIKE '%LED%')) 


Ce qui nous ressort tous les produits ayant dans leur texte "ampoule LED" et tous les produits ayant "ampoule" ou "led" ce qui est très léger comme pertinence.
Pour un bien, il faudrait rechercher dans le nom du produit en priorité, puis s'il n'y a rien, dans le champ data_index de la table « catalogsearch_fulltext ».
Il faut donc créer une nouvelle table qui va contenir les mêmes éléments que catalogsearch_fulltext sauf qu’à la place d'intégrer tous les attributs de recherches concaténées, on va juste y mettre le nom du produit.
Voici le fichier de etc/config.xml
Code :

 <?xml version="1.0"?>
<config>
    <modules>
        <Monentreprise_Catalogsearch>
            <version>0.1.0</version>
        </Monentreprise_Catalogsearch>
    </modules>
    <global>
     <blocks>
<monentreprise_catalogsearch>
<class>Monentreprise_Catalogsearch_Block</class>
</monentreprise_catalogsearch>
</blocks>
     <helpers>
            <monentreprise_catalogsearch>
                <class>Monentreprise_Catalogsearch_Helper</class>
            </monentreprise_catalogsearch>
        </helpers>
        <models>
         <catalogsearch_mysql4>
         <rewrite>
         <fulltext>Monentreprise_Catalogsearch_Model_Mysql4_Fulltext</fulltext>
         </rewrite>
         </catalogsearch_mysql4>
         <catalogsearch_mysql4>
         <rewrite>
         <fulltext_engine>Monentreprise_Catalogsearch_Model_Mysql4_Fulltext_Engine</fulltext_engine>
         </rewrite>
         </catalogsearch_mysql4>
            <Monentreprise_Catalogsearch>
                <class>Monentreprise_Catalogsearch_Model</class>
                <resourceModel>monentreprise_catalogsearch_mysql4</resourceModel>
            </Monentreprise_Catalogsearch>
            <monentreprise_catalogsearch_mysql4>
                <class>Monentreprise_Catalogsearch_Model_Mysql4</class>
                <entities>
             <search><table>monentreprise_catalogsearch_search</table></search>
            </entities>
            </monentreprise_catalogsearch_mysql4>
        </models>
         
        
        <!-- Setup db read & write connection for Catalogsearch module -->
        <resources>
         <monentreprise_catalogsearch_setup>
         <setup>
         <module>Monentreprise_Catalogsearch</module>
         </setup>
         <connection>
         <use>core_setup</use>
         </connection>
         </monentreprise_catalogsearch_setup>
            <monentreprise_catalogsearch_write>
                <connection>
                    <use>core_write</use>
                </connection>
            </monentreprise_catalogsearch_write>
            <monentreprise_catalogsearch_read>
                <connection>
                    <use>core_read</use>
                </connection>
            </monentreprise_catalogsearch_read>
        </resources>
    </global>
    <frontend>
<routers>
<monentreprise_catalogsearch>
<use>standard</use>
<args>
<module>Monentreprise_Catalogsearch</module>
<frontName>monentreprise_catalogsearch</frontName>
</args>
</monentreprise_catalogsearch>
</routers>
<translate>
            <modules>
                <Monentreprise_Catalogsearch>
                     <files>
                          <default>Monentreprise_Catalogsearch.csv</default>
                     </files>
                </Monentreprise_Catalogsearch>
            </modules>
        </translate>
<layout>
<updates>
<monentreprise_catalogsearch>
<file>monentreprise_catalogsearch.xml</file>
</monentreprise_catalogsearch>
</updates>
</layout>
</frontend>
    <default>
        <catalog>
            <seo>
                <search_terms>1</search_terms>
                <site_map>1</site_map>
            </seo>
            <search>
                <min_query_length>1</min_query_length>
                <max_query_length>128</max_query_length>
                <max_query_words>5</max_query_words>
                <search_type>1</search_type>
                <use_layered_navigation_count>2000</use_layered_navigation_count>
            </search>
        </catalog>
    </default>
</config> 



Voici le fichier de setup sql/monentreprise_catalogsearch_setup/mysql4-install-0.1.0.php :
Code :

 <?php
$installer = new Mage_Catalog_Model_Resource_Eav_Mysql4_Setup('core_setup');
/* @var $installer Mage_Core_Model_Resource_Setup */

$installer->startSetup();

$installer->run("
DROP TABLE IF EXISTS {$this->getTable('monentreprise_catalogsearch_search')};
CREATE TABLE {$this->getTable('monentreprise_catalogsearch_search')}(
`product_id` int(11) NOT NULL,
   `store_id` int(11) DEFAULT NULL,
   `data_name` longtext NOT NULL,
`weight` int(11) DEFAULT NULL,
   `popularity` int(11) DEFAULT NULL,
   PRIMARY KEY (`product_id`),
   FULLTEXT KEY `data_name` (`data_name`)
)ENGINE=MyISAM DEFAULT CHARSET=utf8;");

$installer->endSetup(); 


Pour le fichier contrôleur on reprend le même que celui de Magento (j’ai apporté quelques modifications afin de pouvoir trouvé un produit juste en tapant sa référence et d’aller directement sur la fiche produit.) fichier controllers/ResultsController.php:
Code :

 <?php
class Monentreprise_Catalogsearch_ResultsController extends Mage_Core_Controller_Front_Action
{
/**
     * Retrieve catalog session
     *
     * @return Mage_Catalog_Model_Session
     */
    protected function _getSession()
    {
        return Mage::getSingleton('catalog/session');
    }

    
public function indexAction()
{
//Partie de recherche d’un produit par son SKU
$sku = Mage::helper('monentreprise_catalog/data')->getRealitySku($this->getRequest()->getParam(Mage::helper("catalogsearch")->getQueryParamName()));

$_product = Mage::getModel('catalog/product')->loadByAttribute('sku',$sku);
if($_product){
return $this->_redirectUrl($_product->getProductUrl());
}

//Si aucun produit n’est trouvé on lance la recherche par le moteur.

$query = Mage::helper("catalogsearch")->getQuery();

$query->setStoreId(Mage::app()->getStore()->getId());

if ($query->getQueryText()) {
            if (Mage::helper('catalogsearch')->isMinQueryLength()) {
                $query->setId(0)
                    ->setIsActive(1)
                    ->setIsProcessed(1);
            }
            else {
                if ($query->getId()) {
                    $query->setPopularity($query->getPopularity()+1);
                }
                else {
                    $query->setPopularity(1);
                }

                if ($query->getRedirect()){
                    $query->save();
                    $this->getResponse()->setRedirect($query->getRedirect());
                    return;
                }
                else {
                    $query->prepare();
                }
            }

            Mage::helper('catalogsearch')->checkNotes();

            $this->loadLayout();
            $this->_initLayoutMessages('catalog/session');
            $this->_initLayoutMessages('checkout/session');
            $this->renderLayout();

            if (!Mage::helper('catalogsearch')->isMinQueryLength()) {
                $query->save();
            }
        }
        else {
            $this->_redirectReferer();
        }
}


Et enfin le cœur du moteur le fichier Fulltext.php. J’ai également, modifié la ré indexation afin que celle-ci prenne en compte ma nouvelle table et la mette à jour :
Code :

 <?php 

class Monentreprise_Catalogsearch_Model_Mysql4_Fulltext extends Mage_CatalogSearch_Model_Mysql4_Fulltext
{
/**
     * Regénération de l'index de recherche produit.
     *
     * @param int $storeId Store View Id
     * @param int|array $productIds Product Entity Id
     * @return Mage_CatalogSearch_Model_Mysql4_Fulltext
     */
    protected function _rebuildStoreIndex($storeId, $productIds = null)
    {
        $this->cleanIndex($storeId, $productIds);

        // prepare searchable attributes
        $staticFields   = array();
        foreach ($this->_getSearchableAttributes('static') as $attribute) {
            $staticFields[] = $attribute->getAttributeCode();
        }
        $dynamicFields  = array(
            'int'       => array_keys($this->_getSearchableAttributes('int')),
            'varchar'   => array_keys($this->_getSearchableAttributes('varchar')),
            'text'      => array_keys($this->_getSearchableAttributes('text')),
            'decimal'   => array_keys($this->_getSearchableAttributes('decimal')),
            'datetime'  => array_keys($this->_getSearchableAttributes('datetime')),
        );

        // status and visibility filter
        $visibility     = $this->_getSearchableAttribute('visibility');
        $status         = $this->_getSearchableAttribute('status');
        $visibilityVals = Mage::getSingleton('catalog/product_visibility')->getVisibleInSearchIds();
        $statusVals     = Mage::getSingleton('catalog/product_status')->getVisibleStatusIds();

        $lastProductId = 0;
        while (true) {
            $products = $this->_getSearchableProducts($storeId, $staticFields, $productIds, $lastProductId);
            if (!$products) {
                break;
            }

            $productAttributes = array();
            $productRelations  = array();
            foreach ($products as $productData) {
                $lastProductId = $productData['entity_id'];
                $productAttributes[$productData['entity_id']] = $productData['entity_id'];
                $productChilds = $this->_getProductChildIds($productData['entity_id'], $productData['type_id']);
                $productRelations[$productData['entity_id']] = $productChilds;
                if ($productChilds) {
                    foreach ($productChilds as $productChildId) {
                        $productAttributes[$productChildId] = $productChildId;
                    }
                }
            }

            $productIndexes    = array();
            $productAttributes = $this->_getProductAttributes($storeId, $productAttributes, $dynamicFields);
            foreach ($products as $productData) {
                /*
                 * If using advanced index and there is no required fields - do not add to index.
                 * Skipping out of stock products if there are no prices for them in catalog_product_index_price table
                 */
                if ($this->_engine->allowAdvancedIndex() &&
                    (!isset($productData[$this->_engine->getFieldsPrefix() . 'categories']))) {
                    continue;
                }
                if (!isset($productAttributes[$productData['entity_id']])) {
                    continue;
                }

                $protductAttr = $productAttributes[$productData['entity_id']];
                if (!isset($protductAttr[$visibility->getId()])
                    || (!in_array($protductAttr[$visibility->getId()], $visibilityVals)
                        && !$this->_engine->allowAdvancedIndex()
                    )
                ) {
                    continue;
                }
                if (!isset($protductAttr[$status->getId()]) || !in_array($protductAttr[$status->getId()], $statusVals)) {
                    continue;
                }

                $productIndex = array(
                    $productData['entity_id'] => $protductAttr
                );
                
                if ($productChilds = $productRelations[$productData['entity_id']]) {
                    foreach ($productChilds as $productChildId) {
                        if (isset($productAttributes[$productChildId])) {
                            $productIndex[$productChildId] = $productAttributes[$productChildId];
                        }
                    }
                }

                $index = $this->_prepareProductIndex($productIndex, $productData, $storeId);

                $productIndexes[$productData['entity_id']] = $index;
                //$this->_saveProductIndex($productData['entity_id'], $storeId, $index);
            }
            $this->_saveProductIndexes($storeId, $productIndexes);
        }

        // On remets à jour la liste de recherche des noms de produits
        $this->updateSearchName();
       
        $this->resetSearchResults();

        return $this;
    }
    
/**
     * Reset search results
     *
     * @return Mage_CatalogSearch_Model_Mysql4_Fulltext
     */
    public function updateSearchName()
    {
        $this->beginTransaction();
        try {
            $sql = "delete from monentreprise_catalogsearch_search";
        $this->_getWriteAdapter()->query($sql);
        
        $sql = sprintf(
         "insert into monentreprise_catalogsearch_search (product_id, store_id, data_name, weight) ".
"select  cpe.entity_id, '1',  cpevn.value as data2, 1 ".
"FROM `catalog_product_entity` cpe inner join catalog_product_entity_varchar cpevn on cpe.entity_id=cpevn.entity_id ".    
"WHERE cpevn.attribute_id=(select max(attribute_id) from eav_attribute ea where ea.attribute_code='name')"
        );
        $this->_getWriteAdapter()->query($sql); 
        
        $sql = "update monentreprise_catalogsearch_search scs ".
"set scs.popularity=(select count(*) as nb from report_viewed_product_index rvpi where scs.product_id=rvpi.product_id group by product_id) ".
"WHERE EXISTS (select count(*) as nb from report_viewed_product_index rvpi where scs.product_id=rvpi.product_id group by product_id)";
        $this->_getWriteAdapter()->query($sql);

            $this->commit();
        }
        catch (Exception $e) {
            $this->rollBack();
            throw $e;
        }

        return $this;
    }
    
/**
     * Prepare results for query
     *
     * @param Mage_CatalogSearch_Model_Fulltext $object
     * @param string $queryText
     * @param Mage_CatalogSearch_Model_Query $query
     * @return Mage_CatalogSearch_Model_Mysql4_Fulltext
     */
    public function prepareResult($object, $queryText, $query)
    {
        if (!$query->getIsProcessed()) {
        
            $searchType = $object->getSearchType($query->getStoreId());

            $stringHelper = Mage::helper('core/string');
            /* @var $stringHelper Mage_Core_Helper_String */

            $bind = array(
                ':query' => '%'.$queryText.'%'
            );
            $like = array();

            ///////////////////////////////
            // On exécute la requète permettant de rechercher dans les noms des produits
            // en forcant la pertinance à +1000 pour le fulltext et +100 pour le like 
            ////////////
            $fulltextCond   = '';
            $likeCond       = '';
            $separateCond   = '';

            // Génération de la requête pour le Fulltext
            if ($searchType == Mage_CatalogSearch_Model_Fulltext::SEARCH_TYPE_FULLTEXT
                || $searchType == Mage_CatalogSearch_Model_Fulltext::SEARCH_TYPE_COMBINE) {
                $fulltextCond = 'lower(`s`.`data_name`) like (:query)';
            }
            if ($searchType == Mage_CatalogSearch_Model_Fulltext::SEARCH_TYPE_COMBINE && $likeCond) {
                $separateCond = ' OR ';
            }

            $sql = sprintf("INSERT IGNORE `{$this->getTable('catalogsearch/result')}` "
                . "(SELECT STRAIGHT_JOIN '%d', `s`.`product_id`, (`s`.`popularity`/10000)+30 "
                . "as relevance FROM `monentreprise_catalogsearch_search` AS `s` "
                . "INNER JOIN `{$this->getTable('catalog/product')}` AS `e` ON `e`.`entity_id`=`s`.`product_id` "
                . "WHERE (%s%s%s) AND `s`.`store_id`='%d' ORDER BY relevance DESC)",                
                $query->getId(),
                $fulltextCond,
                '',
                '',
                $query->getStoreId()
            );
            
            $this->_getWriteAdapter()->query($sql, $bind);
            
            // Génération de la requête pour le Like 1
         if ($searchType == Mage_CatalogSearch_Model_Fulltext::SEARCH_TYPE_LIKE
                || $searchType == Mage_CatalogSearch_Model_Fulltext::SEARCH_TYPE_COMBINE) {
                $words = $stringHelper->splitWords($queryText, true, $query->getMaxQueryWords());
                $likeI = 0;
                
                if (count($words)>0) {
                    $likeCond = '(lower(`s`.`data_name`) LIKE :query)';
                }
                $bind = array(
                 ':query' => '%'.join('%', $words).'%'
             );
            }
            
            $sql = sprintf("INSERT IGNORE `{$this->getTable('catalogsearch/result')}` "
                . "(SELECT STRAIGHT_JOIN '%d', `s`.`product_id`, (`s`.`popularity`/10000)+20 "
                . "as relevance FROM `monentreprise_catalogsearch_search` AS `s` "
                . "INNER JOIN `{$this->getTable('catalog/product')}` AS `e` ON `e`.`entity_id`=`s`.`product_id` "
                . "WHERE (%s%s%s) AND `s`.`store_id`='%d' ORDER BY relevance DESC)",
                $query->getId(),
                '',
                '',
                $likeCond,
                $query->getStoreId()
            );
            
$this->_getWriteAdapter()->query($sql, $bind);

 if (count($words)>0) {
$likeCond = '(lower(`s`.`data_index`) LIKE :query)';
$bind = array(
                 ':query' => '%'.join('%', $words).'%'
        );
     }


$sql = sprintf("INSERT IGNORE `{$this->getTable('catalogsearch/result')}` "
                . "(SELECT STRAIGHT_JOIN '%d', `s`.`product_id`, (`selec`.`popularity`/10000)+10 "
                . "as relevance FROM `{$this->getMainTable()}` AS `s` "
. "INNER JOIN `{$this->getTable('catalog/product')}` AS `e` ON `e`.`entity_id`=`s`.`product_id`"
. "INNER JOIN `monentreprise_catalogsearch_search` AS `selec` ON `s`.`product_id`=`selec`.`product_id` "
                . "WHERE (%s%s%s) AND `s`.`store_id`='%d' ORDER BY relevance DESC)",
                $query->getId(),
                '',
                '',
                $likeCond,
                $query->getStoreId()
            );
        $this->_getWriteAdapter()->query($sql, $bind);
            

        /*    ///////////////////////////////
            // On exécute la requète classique de recherche produit dans Magento
            ////////////
            $fulltextCond   = '';
            $likeCond       = '';
            $separateCond   = '';
$like = array();

            if ($searchType == Mage_CatalogSearch_Model_Fulltext::SEARCH_TYPE_LIKE
                || $searchType == Mage_CatalogSearch_Model_Fulltext::SEARCH_TYPE_COMBINE) {
                $words = $stringHelper->splitWords($queryText, true, $query->getMaxQueryWords());
                $likeI = 0;
                foreach ($words as $word) {
                    $like[] = '`s`.`data_index` LIKE :likew' . $likeI;
                    $bind[':likew' . $likeI] = '%' . $word . '%';
                    $likeI ++;
                }
                if ($like) {
                    $likeCond = '(' . join(' OR ', $like) . ')';
                }
            }
            if ($searchType == Mage_CatalogSearch_Model_Fulltext::SEARCH_TYPE_FULLTEXT
                || $searchType == Mage_CatalogSearch_Model_Fulltext::SEARCH_TYPE_COMBINE) {
                $fulltextCond = 'MATCH (`s`.`data_index`) AGAINST (:query)';
            }
            if ($searchType == Mage_CatalogSearch_Model_Fulltext::SEARCH_TYPE_COMBINE && $likeCond) {
                $separateCond = ' OR ';
            }

            $sql = sprintf("INSERT IGNORE `{$this->getTable('catalogsearch/result')}` "
                . "(SELECT STRAIGHT_JOIN '%d', `s`.`product_id`, MATCH (`s`.`data_index`) "
                . "AGAINST (:query ) FROM `{$this->getMainTable()}` AS `s` "
                . "INNER JOIN `{$this->getTable('catalog/product')}` AS `e` ON `e`.`entity_id`=`s`.`product_id` WHERE (%s%s%s) AND `s`.`store_id`='%d')",
                $query->getId(),
                $fulltextCond,
                $separateCond,
                $likeCond,
                $query->getStoreId()
            );

            $this->_getWriteAdapter()->query($sql, $bind);
*/
            $query->setIsProcessed(1);
        }

        return $this;
    }
}
 


Pour un bien, il faudrait également prévoir un système de correction orthographique que j’ai réalisé. Je créerais un deuxième tuto pour celui-ci.

N’hésitez pas à commenter et à critiquer mon premier tuto.
Le seul problème que j’ai avec mon module est que le nom des attributs servant au tri ne s’affiche plus, il faut que je regarde pourquoi.

Bon courage à tous.

Matthieu
 
L'administrateur a désactivé l'accès public en écriture.
#55087
mparis
Junior Boarder
Messages: 25
graphgraph
Personne n'est hors ligne Cliquez ici pour voir le profil de cet utilisateur

Re:[TUTO] Moteur de recherche plus pertinent

Il y a 6 Années, 10 Mois
Karma: 2  
J'ai oublié de vous dire que vous pouvez tester celui-ci sur www.selectronic.fr. N'hésitez pas à me critiquer sur celui-ci, c'est avec les critiques que l'on avance .
 
L'administrateur a désactivé l'accès public en écriture.
#55885
FL0
Junior Boarder
Messages: 21
graphgraph
Personne n'est hors ligne Cliquez ici pour voir le profil de cet utilisateur

Re:[TUTO] Moteur de recherche plus pertinent

Il y a 6 Années, 9 Mois
Karma: 0  
Très bien, cependant, je n'arrive pas à le mettre en place.
Ma table est bien créée, mais quand je lance une recherche, j'obtient cette erreur :

Code :


SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ') AND `s`.`store_id`='3' ORDER BY relevance DESC)' at line 1



Une idée d'où pourrait venir le problème?
 
L'administrateur a désactivé l'accès public en écriture.
#56115
mparis
Junior Boarder
Messages: 25
graphgraph
Personne n'est hors ligne Cliquez ici pour voir le profil de cet utilisateur

Re:[TUTO] Moteur de recherche plus pertinent

Il y a 6 Années, 9 Mois
Karma: 2  
Pourrais-tu me donner la requête exacte qu’exécute ton MySQL ? A mon avis, il faudrait faire un var_dump($sql); juste avant les 2 "$this->_getWriteAdapter()->query($sql, $bind);" dans la fonction prepareResult()
 
L'administrateur a désactivé l'accès public en écriture.
#57326
Yoann
Fresh Boarder
Messages: 12
graphgraph
Personne n'est hors ligne Cliquez ici pour voir le profil de cet utilisateur

Re:[TUTO] Moteur de recherche plus pertinent

Il y a 6 Années, 7 Mois
Karma: 0  
Excellent Tuto Mathieu, ton site est vraiment bien!!

Tu va le sortir en module bientôt ?
 
Dernière édition: 09/03/12 à  09:18 Par Yoann.
L'administrateur a désactivé l'accès public en écriture.
#57350
mparis
Junior Boarder
Messages: 25
graphgraph
Personne n'est hors ligne Cliquez ici pour voir le profil de cet utilisateur

Re:[TUTO] Moteur de recherche plus pertinent

Il y a 6 Années, 7 Mois
Karma: 2  
salut Yoann et merci pour ce compliment.

Concernant le moteur, non je n'ai pas l'intention de le sortir en module (cela ferait une rude concurrence au module payant qui existe ). Je n'ai tout simplement pas le temps de gérer les évolutions et surtout de le rendre stable sur les différentes versions de Magento.

N'hésite pas si tu as d'autre question.

Bonne soirée et bon week end.
 
L'administrateur a désactivé l'accès public en écriture.
#61655
ljr95
Senior Boarder
Messages: 50
graphgraph
Personne n'est hors ligne Cliquez ici pour voir le profil de cet utilisateur

Re:[TUTO] Moteur de recherche plus pertinent

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

Super Tuto

Par contre étant débutant je ne prend pas vraiment comment placer les fichiers

Peux-tu m'aider?

Je voudrais faire comme toi deux champs de recherche et une juste avec les références produits.

Merci pour ton aide
 
L'administrateur a désactivé l'accès public en écriture.
#70066
richo
Junior Boarder
Messages: 20
graphgraph
Personne n'est hors ligne Cliquez ici pour voir le profil de cet utilisateur

Re:[TUTO] Moteur de recherche plus pertinent

Il y a 4 Années, 1 Mois
Karma: 0  
Bonjour,
J'ai exactement le meme probleme, bravo pour cet amelioration !!
Est ce que je peux apporter ces modifications sur un Magento 1.7 ?

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