Jump to content

[MODIFICATION] Sélectionner plusieurs valeurs pour une caractéristique


Mellow
 Share

Recommended Posts

Same topic in English

 

Bon, je sais que le forum n'encourage pas les modifs du coeur de PrestaShop mais je crois que cette fonctionnalité manque vraiment à beaucoup de monde.

Voici donc les modifications que j'ai effectué sur PS 1.4.8.2 pour pouvoir utiliser des caractéristiques à multiples valeurs :

 

Pour PS v1.5.x voir ce post : http://www.prestasho...post__p__967310

Maintenant il existe également un module pour PS1.5.x http://www.prestasho...s-par-produits/ Merci à Flo_180

 

Tout d'abord il faut modifier la structure de la table ps_feature_product pour autoriser l’insertion de plusieurs lignes avec les mêmes id_feature et id_product. (je suppose ici que le préfixe de vos tables est "ps", sinon il suffit de remplacer ps par votre préfixe)

 

- Accédez à votre base de donnée via phpmyadmin, et affichez la structure de la table ps_feature_product

- Dans la zone Index, supprimez la caractéristique PRIMERY des champs id_feature et id_product.

post-344943-0-05893200-1340994439_thumb.png

- Si la zone index n'apparait pas, cliquez sur l'onglet SQL et exécutez la commande :

ALTER TABLE ps_feature_product DROP PRIMARY KEY

 

Maintenant votre base de données est prête à recevoir plusieurs valeurs pour une même caractéristique.

 

 

Ensuite il faut modifier le fichier AdminProducts.php qui se trouve dans le sous dossier tabs de votre répertoire admin.

Éditez le fichier AdminProducts.php pour faire les modifications suivantes :

 

Dans la fonction postProcess, ligne 668 (pour PS 1.4.8.2, peut-être une autre ligne pour une autre version...)

Remplacez :

   if ($val)
	   $product->addFeaturesToDB($match[1], $val);

Par :

   if ($val && $val[0] != 0)
	   foreach ($val AS $feature_val) $product->addFeaturesToDB($match[1], $feature_val);

La variable $val sera devenu un tableau contenant les différentes valeurs de la caractéristique. On va donc ajouter une ligne pour chacune de ces valeurs dans la table ps_feature_product.

 

 

Dans la fonction displayFormFeatures (ligne 3578 - PS 1.4.8.2)

Remplacez :

	   	 foreach ($feature AS $tab_features)
			{
				$current_item = false;
				$custom = true;
				foreach ($obj->getFeatures() as $tab_products)
					if ($tab_products['id_feature'] == $tab_features['id_feature'])
						$current_item = $tab_products['id_feature_value'];

				$featureValues = FeatureValue::getFeatureValuesWithLang((int)$cookie->id_lang, (int)$tab_features['id_feature']);

				echo '
				<tr>
					<td>'.$tab_features['name'].'</td>
					<td style="width: 30%">';

				if (sizeof($featureValues))
				{
					echo '
						<select id="feature_'.$tab_features['id_feature'].'_value" name="feature_'.$tab_features['id_feature'].'_value"
							onchange="$(\'.custom_'.$tab_features['id_feature'].'_\').val(\'\');">
							<option value="0">--- </option>';

					foreach ($featureValues AS $value)
					{
						if ($current_item == $value['id_feature_value'])
							$custom = false;
						echo '<option value="'.$value['id_feature_value'].'"'.(($current_item == $value['id_feature_value']) ? ' selected="selected"' : '').'>'.substr($value['value'], 0, 40).(Tools::strlen($value['value']) > 40 ? '...' : '').' </option>';
					}

					echo '</select>';
				}
				else
					echo '<input type="hidden" name="feature_'.$tab_features['id_feature'].'_value" value="0" /><span style="font-size: 10px; color: #666;">'.$this->l('N/A').' - <a href="index.php?tab=AdminFeatures&addfeature_value&id_feature='.(int)$tab_features['id_feature'].'&token='.Tools::getAdminToken('AdminFeatures'.(int)(Tab::getIdFromClassName('AdminFeatures')).(int)($cookie->id_employee)).'" style="color: #666; text-decoration: underline;">'.$this->l('Add pre-defined values first').'</a></span>';

				echo '
					</td>
					<td style="width:40%" class="translatable">';
				$tab_customs = ($custom ? FeatureValue::getFeatureValueLang($current_item) : array());
				foreach ($this->_languages as $language)
					echo '
						<div class="lang_'.$language['id_lang'].'" style="display: '.($language['id_lang'] == $this->_defaultFormLanguage ? 'block' : 'none').'; float: left;">
							<textarea class="custom_'.$tab_features['id_feature'].'_" name="custom_'.$tab_features['id_feature'].'_'.$language['id_lang'].'" cols="40" rows="1"
								onkeyup="if (isArrowKey(event)) return ;$(\'#feature_'.$tab_features['id_feature'].'_value\').val(0);" >'.htmlentities(Tools::getValue('custom_'.$tab_features['id_feature'].'_'.$language['id_lang'], FeatureValue::selectLang($tab_customs, $language['id_lang'])), ENT_COMPAT, 'UTF-8').'</textarea>
						</div>';
				echo '
					</td>
				</tr>';
			}

Par :

	   	 foreach ($feature AS $tab_features)
			{
				$current_item = false;
				$custom = true;
				foreach ($obj->getFeatures() as $tab_products)
					if ($tab_products['id_feature'] == $tab_features['id_feature'])
						$current_item[] = $tab_products['id_feature_value'];

				$featureValues = FeatureValue::getFeatureValuesWithLang((int)$cookie->id_lang, (int)$tab_features['id_feature']);

				echo '
				<tr>
					<td>'.$tab_features['name'].'</td>
					<td style="width: 30%">';

				if (sizeof($featureValues))
				{
					echo '<div style="width:200px;max-height:200px;margin:4px 0px;padding:2px;border:1px solid #e0d0b1;overflow: auto;text-align:left;">';
					if (!$current_item) $current_item[0] = null;
					foreach ($featureValues AS $value) if (in_array($value['id_feature_value'], $current_item)) $custom = false;
					echo '<input type="checkbox" style="display:none;" name="feature_'.$tab_features['id_feature'].'_value[]" id="feature_'.$tab_features['id_feature'].'_value" value="" '.($custom ? 'checked="checked"' : '').'/>';
					foreach ($featureValues AS $value) {
						echo '<label style="padding:2px;text-align:left;cursor:pointer;width:98%;'.((in_array($value['id_feature_value'], $current_item)) ? 'background-color:#acd8fe;' : '').'">
						<input type="checkbox" name="feature_'.$tab_features['id_feature'].'_value[]" class="feature_'.$tab_features['id_feature'].'_value" value="'.$value['id_feature_value'].'"'.((in_array($value['id_feature_value'], $current_item)) ? ' checked="checked"' : '')
						.'onchange="$(\'.custom_'.$tab_features['id_feature'].'_\').val(\'\'); $(\'#feature_'.$tab_features['id_feature'].'_value\').attr(\'checked\', false); if ($(this).attr(\'checked\')) $(this).closest(\'label\').css(\'background-color\', \'#acd8fe\'); else $(this).closest(\'label\').css(\'background-color\', \'#ffffff\');"> '
						.substr($value['value'], 0, 40).(Tools::strlen($value['value']) > 40 ? '...' : '').' </label><br />';
					}
					echo '</div>';
				}
				else
					echo '<input type="hidden" name="feature_'.$tab_features['id_feature'].'_value" value="0" /><span style="font-size: 10px; color: #666;">'.$this->l('N/A').' - <a href="index.php?tab=AdminFeatures&addfeature_value&id_feature='.(int)$tab_features['id_feature'].'&token='.Tools::getAdminToken('AdminFeatures'.(int)(Tab::getIdFromClassName('AdminFeatures')).(int)($cookie->id_employee)).'" style="color: #666; text-decoration: underline;">'.$this->l('Add pre-defined values first').'</a></span>';

				echo '
					</td>
					<td style="width:40%" class="translatable">';
				$tab_customs = ($custom ? FeatureValue::getFeatureValueLang($current_item[0]) : array());
				foreach ($this->_languages as $language)
					echo '
						<div class="lang_'.$language['id_lang'].'" style="display: '.($language['id_lang'] == $this->_defaultFormLanguage ? 'block' : 'none').'; float: left;">
							<textarea class="custom_'.$tab_features['id_feature'].'_" name="custom_'.$tab_features['id_feature'].'_'.$language['id_lang'].'" cols="40" rows="1"
							onkeyup="if (isArrowKey(event)) return; $(\'#feature_'.$tab_features['id_feature'].'_value\').attr(\'checked\', true); $(\'.feature_'.$tab_features['id_feature'].'_value\').attr(\'checked\', false); $(\'.feature_'.$tab_features['id_feature'].'_value\').closest(\'label\').css(\'background-color\', \'#ffffff\');" >'
							.htmlentities(Tools::getValue('custom_'.$tab_features['id_feature'].'_'.$language['id_lang'], FeatureValue::selectLang($tab_customs, $language['id_lang'])), ENT_COMPAT, 'UTF-8').'</textarea>
						</div>';
				echo '
					</td>
				</tr>';
			}

La variable $current_item est transformée en tableau et récupère les différentes valeurs enregistrées de la caractéristique.

La zone de sélection est remplacée par une liste avec des cases à cocher dont les valeurs seront récupérées par la fonction postProcess modifiée précédemment.

 

Maintenant vous pouvez sélectionner plusieurs valeurs pour vos caractéristiques en cliquant sur les valeurs désirées.

post-344943-0-58119400-1345163439_thumb.png

 

Pour ceux qui sont sous PS 1.4.8.2, voici mon fichier AdminProducts.php modifié :

AdminProducts.php

 

Toujours pour PS 1.4.8.2, voici les fichiers ProductController.php et CompareController.php, à AJOUTER dans /override/controllers/ pour corriger l'affichage des caractéristiques à valeurs multiples dans la fiche produit et dans la comparaison de produits (voir captures d'écrans)

ProductController.php

post-344943-0-83427900-1341234522_thumb.png

CompareController.php

post-344943-0-98980200-1341234548_thumb.png

Si vous êtes sur une autre version de prestashop ou si vous avez déjà ces fichiers dans votre dossier override, ouvrez les fichiers et repérez le code à changer pour effectuer vous-même les modifs sur vos fichiers (les modifs sont commentés)

 

 

J'ai fais beaucoup d'essais sur un site que je développe en local, et tout semble fonctionner sans problème.

- La navigation à facettes prend bien en compte ces valeurs de caractéristiques multiples, sans aucune modif suplémentaire

- On peut toujours entrer des caractéristiques personnalisées (non gérées par la navigation à facettes)

- Avec les deux fichiers override joints, les caractéristiques à plusieurs valeurs s'affichent correctement dans la fiche technique produit et dans la comparaison de produits.

 

 

Voila, je pense que cette modif pourra intéresser pas mal de monde...

 

Mais, malgré tous mes essais, il est toujours possible que cette modification interfère avec d'autres parties du code, alors si vous rencontrez des problèmes faites le savoir ici.

post-344943-0-58470300-1340994547_thumb.png

Edited by Mellow (see edit history)

Share this post


Link to post
Share on other sites

Testé sur ps 1.4.8.2

 

le fichier renvoie 2 fois la caractéristique dans l'onglet fiche technique

dans " Ajouter une nouvelle valeur de caractéristique"

la sélection multiple ne se fait pas...

 

bon début de modif

 

Croyez vous qu'il serait possible de faire pareil avec les déclinaisons :

cad ajouter dans une seule déclinaison tout ou partie des critères ?

ce qui pourrait grouper de multiples déclinaisons en une seule déclinaison du produit de base

 

Bravo Cordialement

Share this post


Link to post
Share on other sites

Désolé je n'avais pas compris le fonctionnement :

la sélection semble se faire : dans la sélection

mais à l'affichage il transmet la même valeur

-1 que l'on sélectionne un ou deux critères = 2 critères

-2 le panneau de sélection ne retourne qu'une case de caractéristiques : le texte se modifie bien

 

Cordialement

Share this post


Link to post
Share on other sites

un exemple avec 4 champs :

 

voila ce qui est renvoyé 2 fois

  • Couleur non
  • Noir et BLanc Haute qualité
  • Verre brillant non
  • Verre dépoli non
  • Couleur non
  • Noir et BLanc Haute qualité
  • Verre brillant non
  • Verre dépoli non

Share this post


Link to post
Share on other sites

Bonjour redtango,

 

J'ai essayé de reproduire le comportement que tu décris en refaisant la modif manuellement et en laissant volontairement des erreurs, sans succès...

 

J'ai effectué une nouvelle installation de PS 1.4.8.2, et j'ai appliqué la modif dessus.

- D'abord manuellement en copiant/collant le code placé sur mon post (des fois que le code serait corrompu...)

- Puis en téléchargeant le fichier joint (encore au cas ou le fichier serait corrompu)

Dans les deux cas tout a fonctionné parfaitement, j'ai bien mes valeurs multiples sélectionnables en BO, et ils se sauvegardent sans problème (que j'en sélectionne un seul ou plusieurs)

 

Par exemple, en ajoutant une nouvelle valeur à la caractéristique "prise casque" et en l'appliquant sur un produit, l'affichage sur la fiche technique du produit donne quelque chose de ce genre :

  • Prise casque Nouvelle valeur test
  • Prise casque Micro-jack stéréo
  • Poids 49,2 g
  • Largeur 52,3 mm

L'affichage reste donc à corriger, comme je l'ai signalé sur le premier post, mais les valeurs sont bien prises en compte.

[Edit] J'ai rajouté au premier post deux fichiers override, à placer dans /override/controllers/ pour corriger l'affichage des caractéristiques à valeurs multiples dans la fiche produit et la comparaison de produits.

 

 

Je pense que tu a peut-être un souci au niveau de l'application de la modif...

 

- Comment as-tu effectué la modif ? En utilisant le fichier AdminProducts.php joint, ou en le modifiant manuellement ?

- La modification de la base de donnée s'est bien déroulée ???

Edited by Mellow (see edit history)

Share this post


Link to post
Share on other sites

Bonsoir,

j'avais remplacé uniquement le fichier Adminproducts

 

ce soir j'ai remplacé les 2 fichiers Controllers,

et je n'ai plus d'accès en front office : produits et compare

 

Idem : affichage de 2 fois le même résultat

Cela dit ton script est béton : et si le même était développé avec les déclinaisons ce serait génial

c'est vraiment un sacré développement.

 

en test sur la dernière mouture de PS implémentée Jeudi dernier,

le doublon viendrait peut-être des tables ? : je vais jeter un coup d'oeil dessus

dès que j'ai le temps je regarde les deux fichiers controllers.

 

Merci de ta réactivité

Cordialement

 

Version

 

PrestaShop™ 1.4.8.2

Share this post


Link to post
Share on other sites

OK, ça doit venir de la table à modifier alors

 

Une précision : il ne faut surtout pas remplacer les fichiers controleur, mais les AJOUTER dans /override/controllers/

Ce sont des fichiers de surcharge pour les controleurs d'origine, et il ne contiennent que les fonction modifiées ! (d'ou l’impossibilité d’accéder à certaines pages si on remplace les controleurs d'origine)

 

Pour ce qui est des déclinaisons, je ne pense pas que ce soit envisageable, car les déclinaisons sont très différentes des caractéristiques.

Une caractéristique concerne un produit dans sa globalité, alors qu'une déclinaison est une variante du produit, et peut avoir un prix, un poids, un stock, et même une référence différente. Il est donc nécessaire de traiter chaque déclinaison séparément...

Share this post


Link to post
Share on other sites

@ nick2paris

 

J'avoue que n'utilisant pas les export/import csv, je ne me suis pas penché sur la question.

 

Mais Il faudrait déjà voir comment exporter les valeurs multiples...

Je suppose que les modules d'export doivent prendre la première valeur trouvée pour chaque caractéristique. il faudrait donc modifier le module d'export de manière à enregistrer pour chaque caractéristique, les différentes valeurs séparées par des virgules.

 

Après il faudrait modifier le fichier AdminImport.php pour séparer les valeurs lors de l'import et les enregistrer une par une...

Share this post


Link to post
Share on other sites

Tout d'abord bravo et merci Mellow

 

Super modif, super topic, bref, si tout le monde prenait le temps de rédiger et tester comme toi, le dev serait vraiment simple !

 

Donc ta modif tourne sur PS 1.4.5.1 (en local, mais il n'y a pas de raison que ça ne marche pas sur le serveur de prod).

 

J'ai juste une question, ou plutôt un souhait concernant une amélioration de l'affichage des caractéristiquse en front sur la page Produit ; y-a-t-il un moyen simple de regrouper les valeurs par caractéristiques en ne répétant pas le nom (nomenclature) de la caractéristique.

Afin d'éviter l'affichage comme sur l'image ci-jointe.

 

Si tu as un peu de temps pour cette optimisation, je suis preneur

 

Encore une fois, super boulot.

 

Merci

 

Sébastien

post-135121-0-43211700-1341954010_thumb.png

Share this post


Link to post
Share on other sites

@unbiocadeau

 

Merci de ton retour pour PS 1.4.5.1 et de tes encouragements.

 

Dans le premier post il y a deux fichiers ProductController.php et CompareController.php à ajouter dans /override/controllers/ pour corriger l'affichage dans la fiche produit ainsi que dans la page de comparaison de produit, mais ils sont pour PS 1.4.8.2

 

Pour une autre version de Prestashop (1.4.xx) voici la procédure pour créer ces deux fichiers :

 

Copier les deux fichiers ProductController.php et CompareController.php depuis le dossier controllers vers le dossier override/controllers/ (attention, copier et non déplacer !)

 

Ouvrir override/controllers/ProductController.php

 

Au début du fichier remplacer :

class ProductControllerCore extends FrontController

Par :

class ProductController extends ProductControllerCore

 

Et supprimer toutes les fonctions et définitions sauf la fonction process (si tu as un doute regarde la structure du fichier ProductController.php joint au premier poste)

 

Ensuite, dans la fonction process, remplacer :

			$features = $this->product->getFrontFeatures((int)self::$cookie->id_lang);
			$attachments = ($this->product->cache_has_attachments ? $this->product->getAttachments((int)self::$cookie->id_lang) : array());

Par :

			$features = $this->product->getFrontFeatures((int)self::$cookie->id_lang);
			$done = null;
			foreach ($features as $key => $feature) {
				$caract = $features[$key]['name'];
				if (!isset($done[$caract][0])) {
					$features[$key]['name'] .= ' :' ;
					$done[$caract][0] = true;
					$done[$caract][1] = $key;
				} else {
					$features[(int)$done[$caract][1]]['value'] .= ', ' . $features[$key]['value'] ;
					unset($features[$key]);
				}
			}
			$attachments = ($this->product->cache_has_attachments ? $this->product->getAttachments((int)self::$cookie->id_lang) : array());

 

 

 

Ouvrir ensuite override/controllers/CompareController.php

 

Au début du fichier remplacer :

class CompareControllerCore extends FrontController

Par :

class CompareController extends CompareControllerCore

 

Et supprimer toutes les fonctions et définitions sauf la fonction process...

 

Dans la fonction process, remplacer :

		   	 foreach ($curProduct->getFrontFeatures(self::$cookie->id_lang) AS $feature)
					$listFeatures[$curProduct->id][$feature['id_feature']] = $feature['value'];

Par :

		   	 $features = $curProduct->getFrontFeatures((int)self::$cookie->id_lang);
				$done = null;
				foreach ($features as $key => $feature) {
					$caract = $features[$key]['name'];
					if (!isset($done[$caract][0])) {
						$features[$key]['name'] .= ' :' ;
						$done[$caract][0] = true;
						$done[$caract][1] = $key;
					} else {
						$features[(int)$done[$caract][1]]['value'] .= ', ' . $features[$key]['value'] ;
						unset($features[$key]);
					}
				}
				foreach ($features AS $feature)
					$listFeatures[$curProduct->id][$feature['id_feature']] = $feature['value'];

Share this post


Link to post
Share on other sites

Merci pour ta réponse rapide et ces éléments supplémentaires.

J'ai effectué la démarche, mais cela n'a pas fonctionné. Du coup, j'ai fait un truc qu'il ne faut pas faire, mais au moins ça marche, j'ai modifié le fichier "Core".

C'est pas la première fois que j'ai des problèmes avec l'overide du Product.

En tous, cas merci beaucoup, ça marche super.

Share this post


Link to post
Share on other sites

Merci pour ce tuto, tout marche très bien en 1.4.8.2.

 

J'utilise les import CSV et ai donc effectué quelques modification dans le "AdminImport.php" ligne 864 afin de pouvoir attribuer plusieurs valeurs à une caractéristique lors de cet import:

$features = get_object_vars($product);
   // ****************************************************
   // 19/07/2012 Trezo
   // Modification to multi feature values
   //
   // old :
   //foreach ($features AS $feature => $value)
   // if (!strncmp($feature, '#F_', 3) AND Tools::strlen($product->{$feature}))
   // {
   //  $feature_name = str_replace('#F_', '', $feature);
   //  $id_feature = Feature::addFeatureImport($feature_name);
   //  $id_feature_value = FeatureValue::addFeatureValueImport($id_feature, $product->{$feature});
   //  Product::addFeatureProductImport($product->id, $id_feature, $id_feature_value);
   // }
   // new :
   // if you want delete all features of the product before add
   $product->deleteFeatures();

   $separator = ((is_null(Tools::getValue('multiple_value_separator')) OR trim(Tools::getValue('multiple_value_separator')) == '' ) ? ',' : Tools::getValue('multiple_value_separator'));
   foreach ($features AS $feature => $value)
 if (!strncmp($feature, '#F_', 3) AND Tools::strlen($product->{$feature}))
 {
  $feature_name = str_replace('#F_', '', $feature);
  $id_feature = Feature::addFeatureImport($feature_name);
  // if you want only delete added feature before add
  //Db::getInstance()->Execute('
  // DELETE FROM `'._DB_PREFIX_.'feature_product`
  // WHERE `id_feature` = '.(int)($id_feature).'
  // AND `id_product` = '.(int)($product->id)
  //);
  $array_features = explode($separator,$product->{$feature});
  foreach($array_features AS $a_feature){
   $id_feature_value = FeatureValue::addFeatureValueImport($id_feature, $a_feature);
   Product::addFeatureProductImport($product->id, $id_feature, $id_feature_value);
  }
 }
   // ****************************************************

 

J'ai rencontré un problème lors de l'import d'un produit plusieurs fois de suite, la clef primaire ayant été supprimée de la table, les valeurs n'était plus remplacées mais s'ajoutaient les unes aux autres que ce soit dans la vue du comparateur ou de la fiche produit.

 

J'ai résolu le problème en ajoutant $product->deleteFeatures() avant l'import des caractéristiques qui nettoie l'ensemble des caractéristiques du produit.

J'avais auparavant choisi une autre stratégie qui ne supprimait que les valeurs de la caractéristique ayant été importée. J'ai tout de même laissé cette partie de code au cas ou certains serait intéressés.

 

Encore merci à toi Mellow.

Edited by trezo (see edit history)
  • Like 1

Share this post


Link to post
Share on other sites

Super, j'avais aussi préparé une petite modif pour récupérer les valeurs multiples dans un csv, mais la tienne est bien plus complète.

 

J'avais effectué des essais sommaires et je n'avais pas remarqué la duplication des valeurs lors d'imports successifs.

Je n'avais pas non plus pensé à utiliser une variable "multiple_value_separator" très utile pour s'ajuster aux différents types de valeurs utilisées. Je suppose que tu génère cette variable par ton module d'export ?

 

En tout cas merci trezo pour cette modif, je m'en servirais si j'ai besoin d'utiliser l'export/import de produit

Share this post


Link to post
Share on other sites

La variable "multiple_value_separator" est générée par le champ "Séparateur champs à valeurs multiples" de la fonction d'import du back office.

 

Je ne me sers que de la fonction d'import car je suis en phase de création d'une boutique, je me pencherai sur l'export si besoin.

 

J'attaque actuellement la gestion de couleurs en tant que caractéristiques, à la manière des déclinaisons, autant back-office (hormis images) que front office et dans mon cas pour la navigation à facettes, t'es tu déjà penché sur la question ?

Edited by trezo (see edit history)

Share this post


Link to post
Share on other sites

ah ok, je n'avais remarqué qu'il y avait une variable

 

Pour les couleurs, non, je n'y ai pas réfléchi. Je sais juste qu'elle peuvent être gérer avec les déclinaisons, mais je n'utilise pas de paramètre de couleur pour le moment.

 

Bonne continuation en tout cas

Share this post


Link to post
Share on other sites

  • 2 weeks later...

Bonjour,

 

Cette modif est super.

 

Par contre, est-ce qu'il y a un moyen de mettre les caractéristiques dans l'ordre que l'on veut sur la fiche produit ?

 

Car avec les essais que j'ai fait cela parait assez erratique ...

 

A bientôt

 

Phil

Share this post


Link to post
Share on other sites

Bonjour,

 

Il n'y a pas de gestion d'ordre sur les caractéristiques ni sur leurs valeurs, et c'est bien dommage.

La seule chose qu'on peut faire c'est un tri alphabétique avant de les afficher dans la fiche produit.

 

Pour ça dans ProductController.php on peut rajouter

asort($features);

juste après

$features = $this->product->getFrontFeatures((int)self::$cookie->id_lang);

 

Mais c'est vrai que ce serait bien mieux de pouvoir gérer l'ordre d'affichage des caractéristiques...

Share this post


Link to post
Share on other sites

  • 2 weeks later...

Hello,

 

BRAVO MELLOW, pour ta contribution, excellent job et merci beaucoup, c'est exactement ce dont j'avais besoin !

 

J'ai cependant une petite erreur de notice

 

[b]Notice[/b]: Undefined offset: 0 in [b]................../tabs/AdminProducts.php[/b] on line [b]3621[/b]

 

cette ligne correspond à cette partie de code :

$tab_customs = ($custom ? FeatureValue::getFeatureValueLang($current_item[0]) : array());

 

c'est apparemment ceci qui pose problème :

$current_item[0]

 

aurais-tu une idée ?

 

D'avance un grand merci et meilleures salutations

Share this post


Link to post
Share on other sites

@link80

 

Effectivement, quand l'affichage des erreurs php est activé il y a ce notice qui apparait lorsqu'une caractéristique n'a pas encore de valeur attribuée.

A noté qu'il s'agit d'un "notice" donc pas une erreur bloquante. C'est plutôt le signalement d'une mauvaise pratique. (qui n’empêche pas le script de bien fonctionner)

 

En fait j'ai voulu trop bien faire en déclarant des le début la variable $current_item comme étant un tableau, si bien que dans ce cas de figure le tableau existe déjà mais pas son index 0 (qui sera tout de même créé, mais avec un notice). Il suffit donc de ne pas déclarer de type pour $current_item, et le tableau ainsi que son index 0 seront créés lors de l'appel de cet index ($current_item[0])

 

Donc remplacer :

$current_item = array();

par :

$current_item = false;

Comme c'était à l'origine... ;)

 

Merci de ton retour link80, je corrige le code sur le premier post

Share this post


Link to post
Share on other sites

Bonjour,

 

Attention, nous avons remarqué qu'en appliquant cette astuce (en particulier la suppression de la clé primaire), le chargement du contenu d'un filtre dans le BO et configuration du module BlockLayered (navigation à facettes) devient trop long et renvoi une erreur 500 sur l'appel ajax du fichier blocklayered_ajax_back.php.

Celui-ci appele le fichier blocklayered.php qui execute la requête sql en ligne 3525 censée récupérée les valeurs de caractéristiques.

Malheureusement, on passe d'un temps de réponse de 3-4s à plus de 9s ce qui fait planter l'appel Ajax.

 

Et oui tout ça à cause de la clé primaire supprimée !

 

Quelqu'un de très fort en sql serait-il capable de remodeler cette requête ?

 

Mais je ne peux m'empêcher de me demander pourquoi cette possibilité de multivaleurs (demandée par beaucoup de gens) n'est toujours pas implémentée en natif dans Prestashop même pas dans la 1.5 ?!!!!!

Quelqu'un de la Prestateam peut-il nous répondre ???

 

J'ajoute juste que cette possibilité n'est pas compatible avec la gestion des caractéristiques par Store Commander.

 

Je reste à l'écoute...

Edited by revolving (see edit history)

Share this post


Link to post
Share on other sites

Bonjour,

 

Je me demande si le fait de remplacer la clef primaire par un simple index ne suffirait pas à re-gagner une partie de ce temps d’exécution.

 

Concernant l'ordre d'affichage des caractéristiques dans la page produit, c'est certainement faisable en attaquant directement la base de données, ajouter un champ "index" dans la table feature et un "order by index" à la requête de sortie.

 

Ce sont les quelques pistes qui me passent par la tête, je n'ai malheureusement pas le temps de me pencher sur la question.

 

Bonne continuation

Edited by trezo (see edit history)

Share this post


Link to post
Share on other sites

Bonsoir,

 

@revolving,

Oui effectivement, il est clair que sur un site avec un grand nombre de produits et de caractéristiques le temps d'exécution des requêtes sql pour récupérer ces valeurs risquent d'augmenter considérablement. Surtout pour le blocklayered qui est déjà plutôt gourmand en ressources...

 

A ce moment là je crains qu'il ne soit obligatoire de faire un choix entre navigation à facette et caractéristiques à plusieurs valeurs. A moins d'une évolution du module blocklayered avec peut-être un système de cache...

 

Pourrais tu stp nous dire le nombre de produits et de caractéristiques présents dans la config ou tu a relevé ces valeurs ? ça donnera peut-être une idée des limites au delà desquelles le problème apparait.

 

Pour ma part je n'ai testé que sur un site en développement, avec une douzaine de produits, et 3 caractéristiques, dont une principale pouvant prendre 8 valeurs.

Je ne pense pas que ça soit suffisant pour percevoir un réel ralentissement, j'essayerais de faire aussi des mesures en dupliquant les produits pour arriver à une centaine (c'est ce que devrait avoir le site au final)

 

 

@trezo

Oui, je pense que le remplacement par un index devrait déjà permettre de gagner quelque chose...

 

 

Ah si seulement un presta-spécialiste pouvait se pencher avec nous sur la question... ;)

Share this post


Link to post
Share on other sites

Bon, hé bien malgré cette mauvaise nouvelle, voici quand même une petite amélioration :

 

L'utilisation du multiselect n'étant pas toujours très commode (ni très esthétique) et entrainant un comportement différent selon les navigateurs, je l'ai remplacé par des cases à cocher dans une div dont la taille s'adapte au nombre de valeurs de la caractéristique.

Et du coup le petit javascript n'est plus nécessaire non plus.

Ce qui donne ça dans la fiche produit en BO :

post-344943-0-58119400-1345163439_thumb.png

 

J'ai mis à jour le post initial avec le nouveau code, ainsi qu'un nouveau fichier AdminProducts.php pour PS 1.4.8.2

Share this post


Link to post
Share on other sites

Bonjour,

 

Les tests ont été faits sur une base de 1800 produits dans 270 catégories avec 20 caractéristiques pour chaque produit et 2 produits seulement avaient reçus une double valeur sur 2 caractéristiques.

Je ne pense pas être exceptionnel pour le nombre de produits gérés, je pense plus qu'il suffirait juste de revoir la requête pour l'alléger mais je ne suis pas un spécialiste SQL.

 

A suivre donc.

Share this post


Link to post
Share on other sites

Ok, merci

 

Je n'avais pas bien interprété ton premier message, je pensais qu'il y avait également des problèmes en front office avec le module blocklayered...

 

J'ai l'impression que cette requête sert uniquement à déterminer les caractéristiques réellement utilisées afin de les proposer comme filtre.

Donc effectivement un spécialiste SQL pourrait sans doute la reformuler et l'optimiser...

 

Mais déjà, comme le suggérait Trezo, j'ai constaté que l'ajout d'un index sur le champ 'id_product' améliore un peu le temps d'exécution de cette requête (mais pas sur 'id_feature', car ça semble ralentir au contraire)

Share this post


Link to post
Share on other sites

  • 1 month later...

Bonjour,

 

Super intéressant vos échanges, j’essaie de mettre en place les caractéristiques multiples sur PS1.5, mais pour le moment sans succès.

Mon souci est que les admin tabs ne sont pas présents dans le rep, donc cela implique de modifier les contrôleurs.

Malheureusement, je ne sais pas trop par ou commencer.

 

Si quelqu'un pourrait m'aider a faire cela sur PS1.5, je lui en serait reconnaissant.

 

Marc

Share this post


Link to post
Share on other sites

  • 3 weeks later...

Geniale cette modif, par contre avez vous la même chose que moi :

en backend, si je retourne sur les caracteristiques de mes produits, plus rien n'est sélectionné, et si je modifie une caractéristique, je perd les autres caractéristiques précédemment affectées.

 

En soi ce n'est pas trop gênant, il faut juste refaire a chaque modif toutes les caractéristiques mais ce serait mieux si elles restaient affichées

je suis en 1.4.7.0

Share this post


Link to post
Share on other sites

en backend, si je retourne sur les caracteristiques de mes produits, plus rien n'est sélectionné, et si je modifie une caractéristique, je perd les autres caractéristiques précédemment affectées.

 

Non, ce n'est pas normal, les caractéristiques sauvegardées devraient être sélectionnées lorsque tu reviens sur la fiche produit.

Il doit y avoir un pb dans ta modif de AdminProducts.php

Vérifie si tu n'a pas oublié un petit bout de code, en particulier dans la deuxième partie, la fonction displayFormFeatures

Share this post


Link to post
Share on other sites

exact , j'ai du zappé quelque chose, j'ai repris le code ça fonctionne c'est top.

 

merci bien;

Ce serait pas mal de le passer en module , je suis certain que cette évolution en intéresse plus d'un.

 

Est ce que tu t'es intéressé à la nouvelle version de presta ? et penses tu que cette modif est également réalisable ?

 

bonne continuation

Share this post


Link to post
Share on other sites

Je me suis intéréssé à la version 1.5 mais seulement pour me tenir informé.

 

Je viens de terminer mon premier site Prestashop en 1.4.9 (commencé en 1.4.7) sur lequel j'ai fait pas mal de modifs qui ne sont pas non plus présente dans la v1.5 alors j'ai la fleme de me retapper tout ce boulot ;)

 

Et puis l'expérience (sur d'autres systèmes) m'a apris qu'il valait mieux laisser murir quelques mois avant d'adopter une évolution majeure...

 

Mais je pense que cette modif devrait être assez facilement transposable sur la v1.5, les fichiers à modifier ne seront peut-être pas les mêmes, mais le fait qu'on puisse utiliser la fonction override sur les controleurs admin devrait faciliter les choses, enfin je pense...

 

Sinon pour passer en module, je ne crois pas que ce soit possible. On touche au coeur du système donc il faut soit modifier soit "overrider"

Share this post


Link to post
Share on other sites

OK, pour Prestashop v1.5 :

 

Avec PS 1.5, les contrôleurs et les templates admin sont surchargeables (fonction override), donc nous n'avons plus besoin de modifier les fichiers du coeur.

 

Il y avait 4 fichiers à modifier :

/controllers/admin/AdminProductsController.php (c'est là que les caractéristiques sont chargées/traitées/sauvegardées)

/admin/themes/default/template/controllers/products/features.tpl (template qui affiche des caractéristiques sur la page produit dans le back office)

/controllers/front/ProductController.php (contrôleur qui charge les caractéristiques pour la page produit en front office)

/controllers/front/CompareController.php (contrôleur qui charge les caractéristiques pour la page de comparaison de produit)

 

Ces fichiers peuvent être surchargés comme ceci :

/override/controllers/admin/AdminProductsController.php

/override/controllers/admin/templates/products/features.tpl

/override/controllers/front/ProductController.php

/override/controllers/front/CompareController.php

 

Voici donc les fichiers override pour PS 1.5.1

select-multiple-feature-values_override-files_PSv1.5.1.zip

Il suffit de copier le contenu de cette archive par dessus votre dossier override dans PS 1.5.1, et vous avez terminé.

 

N'oubliez pas de modifier la structure de la table ps_feature_product

ALTER TABLE ps_feature_product DROP PRIMARY KEY

OU :

ALTER TABLE ps_feature_product DROP PRIMARY KEY, ADD PRIMARY KEY (id_feature, id_product, id_feature_value)

 

Comme d'habitude, vous devriez tester localement avant d'appliquer ces modifs sur une boutique en ligne...

select-multiple-feature-values_override-files_PSv1.5.1.zip

Share this post


Link to post
Share on other sites

Hello Mellow,

 

J'ai appliqué ta modification sur une boutique prestashop, je constate egalement un FORT RALENTISSEMENT de la boutique après avoir appliqué la modif et en utilisant également le module Recherche Avance 4 :

http://www.presta-module.com/modules-prestashop/36-navigation-a-facettes.html

 

Mes pages mettent entre 5 et 10 secondes pour s'afficher...

 

Je ne force pas la compilation, le cache est activé ainsi que les différentes options de CCC (compression et mise en cache proposée par Prestashop).

 

Pour info, ma boutique comporte 212 produits.

 

ps_feature comporte 12 entrées

ps_feature_values 350 entrées

ps_feature_product 2'757 entrées

ps_feature_value_lang 1'050 entrées

 

J'ai monté deux autres shops, relativements identiques ces derniers temps sur la même version (1.4.8.3), le même hébergement (infomaniak), les deux autres tournent très bien comparé à celui ou j'ai appliqué ta modification.

 

N'y a il pas quelqu'un qui aurait une solution à proposer ?

 

D'avance un grand merci pour votre aide et encore une fois un grand bravo à toi Mellow pour ton module qui fonctionne parfaitement hormis ce détail assez génant :D

Share this post


Link to post
Share on other sites

Bonjour link80,

 

Je pense que c'est la combinaison de cette modif avec le module Advance Search qui provoque de tel ralentissements.

Ce module semble déjà réclamer pas mal de ressources en temps normal, alors avec des caractéristiques multiple en grande quantité ça ne doit pas arranger les chose...

 

J'essaye d'expliquer un peu le problème tel que je le vois:

 

Ce genre de module créé en général des tables d'index pour les filtres les plus gourmands en ressources (prix et attribut principalement) de manière à accélérer les recherches.

 

Mais je suppose que le module ne doit pas créer d'index pour les caractéristiques (la navigation à facettes de base ne le fait pas non plus) puisque la recherche est sensé être rapide dans la table ps_feature_product (avec une seule correspondance possible par produit et par caractéristique)

 

Seulement avec les caractéristiques multiples, et à partir d'une certaine quantité, cette recherche doit devenir nettement plus longue !

Et le module doit rechercher, à chaque chargement, les caractéristiques de tous les produits pour élaborer les filtres correspondants...

 

Je ne vois qu'une amélioration possible : Rendre primaire les 3 champs de la table ps_feature_product (plutôt que de supprimer les 2 champs primaires) ça devrait théoriquement accélérer un peu les recherches dans cette table, mais je doutes que ça soit suffisant...

ALTER TABLE ps_feature_product DROP PRIMARY KEY, ADD PRIMARY KEY (id_feature, id_product, id_feature_value)

 

Tiens nous informé si ça donne des résultats, pour ma part je n'utilise pas le module Advance Search, et je n'ai pas assez de produits ni de caractéristiques dans la boutique sur laquelle je travail pour constater une réel différence.

 

Mais la vraie solution ce serait que la PrestaTeam intègre les caractéristiques multiples, et peut-être d'une façon mieux élaborée que ma modif.... :)

Share this post


Link to post
Share on other sites

Hello,

 

Oui effectivement, ça serait vraiment une bonne chose que cette possibilité soit intégrée par défaut dans prestashop, ça me semble être une option qui pourrait intéresser pas mal de gens...

 

En attendant, j'ai testé de rendre primaire les 3 champs comme tu le suggère mais je ne constate malheureusement aucune amélioration...

Share this post


Link to post
Share on other sites

  • 3 weeks later...
  • 1 month later...

Bonjour,

Merci pour votre modification qui est très utilie.

Malheuresement je suis gourmant et je voudrai aussi cette modification : http://www.prestashop.com/forums/topic/189716-ajout-des-produits-virtuels-avec-declinaisions/page__st__0

Les deux, utilisent, le fichier : AdminProductsController.php

Je voudrai donc fusionner les deux modifications.

J'ai essayé avec un include("mon_fichier_a_fusionner") mais cela ne fonctionne pas.

Avez vous une solution ?

Il me faut absolument les deux ....

 

Bonne journée,

Morgan

Share this post


Link to post
Share on other sites

@Antirouille

 

Les deux modifs interviennent sur des fonctions différentes, donc ça simplifie les choses.

Il te suffit de conserver l'un des deux fichiers, de l'éditer, et d'y copier les fonctions contenues dans l'autre.

 

fichier 1

<?php
class AdminProductsController extends AdminProductsControllerCore
{
fonction X
fonction Y
}

 

fichier 2

<?php
class AdminProductsController extends AdminProductsControllerCore
{
fonction A
fonction B
fonction C
}

 

fichier final

<?php
class AdminProductsController extends AdminProductsControllerCore
{
fonction X
fonction Y
fonction A
fonction B
fonction C
}

Share this post


Link to post
Share on other sites

MEEERRRCCCIIII

tout fonctionne parfaitement !! j'espère que ca en aidera plus d'un :)

 

A tout hasard il me reste quelques modif' a faire avant de lancer ma boutique mais voilà ce que je cherche :

 

Un module qui permet de faire un espace de téléchargement de fichier acheté.

Un module qui permet de rajouter dans mon processus de commande un formulaire de personnalisation quand l'attribut modification est choisi.

 

Je sais que ce n'est pas l'endroit pour poster cette demande, mais avant d'ouvrir un sujet specifique on ne sait jamais si tu connais ce type de module.

 

Encore merci pour ton fichier.

 

Morgan

Share this post


Link to post
Share on other sites

  • 4 weeks later...

Bonjour nick2paris,

 

Pour l'export tu utilises quoi comme module ? Est-ce que tu as pu exporter les caractéristiques multiples ?

 

Quand j'importe plusieurs caractéristiques elles ne s'affichent pas dans le BO mais bien dans FO, as-tu le même problème ?

 

En te remerciant d'avance

Share this post


Link to post
Share on other sites

  • 3 weeks later...

Bonjour,

 

Je viens de tester sous Prestashop 1.5.3.1 et j'arrive sans problème à mettre les caractéristiques multiples dans le back-office.

Par contre, dans le front-office, dans l'onglet "Fiche technique" du produit, seule une valeur de chaque caractéristique apparaît.

Je n'ai rien bidouillé, j'ai juste mis les 4 fichiers de ton archive 1.5 dans le répertoire override.

 

Quelqu'un sait-il pourquoi ça n'affiche pas toutes les valeurs de ma caractéristique ?

 

Merci d'avane

Share this post


Link to post
Share on other sites

Bonjour tout le monde,

 

Merci Mellow pour le code.

 

Sur ma V1531, les valeurs ne s'affichent pas correctement sur le front.

Cela vient du code Prestashop qui fourni 2 méthodes assez proches pour la récupération des features: getFrontFeaturesStatic et cacheFrontFeatures, mais qui ont un code légérement différent.

 

Pour corriger cela, recherchez donc la méthode 'getFrontFeaturesStatic' dans 'classes/product.php', et ajoutez 'id_product,' après le 'SELECT'. (vous devez avoir : 'SELECT id_product, name, value, pf.id_feature')

 

Voila, ça devrait marcher.

Share this post


Link to post
Share on other sites

Bonjour,

 

Oui, il semble bien que la version 1.5.3 introduit un petit changement dans la gestion des caractéristiques.

 

Sur le même sujet en anglais quelqu'un a posté une nouvelle version avec un override de la classe Product.php qui remplace les overrides des controleurs ProductController.php et CompareController.php, en faisant le même travail.

Je n'ai pas testé (pas encore essayé la 1.5.3) mais ça devrait corriger ce problème d'affichage...

J'espère que vous n'êtes pas fâchés avec la langue de Shakespeare... ;)

http://www.prestasho...ost__p__1085967

Edited by Mellow (see edit history)

Share this post


Link to post
Share on other sites

Bonjour tout le monde,

 

Merci Mellow pour le code.

 

Sur ma V1531, les valeurs ne s'affichent pas correctement sur le front.

Cela vient du code Prestashop qui fourni 2 méthodes assez proches pour la récupération des features: getFrontFeaturesStatic et cacheFrontFeatures, mais qui ont un code légérement différent.

 

Pour corriger cela, recherchez donc la méthode 'getFrontFeaturesStatic' dans 'classes/product.php', et ajoutez 'id_product,' après le 'SELECT'. (vous devez avoir : 'SELECT id_product, name, value, pf.id_feature')

 

Voila, ça devrait marcher.

 

Effectivement, ça a marché !

Merci beaucoup.

 

Bonjour,

 

Oui, il semble bien que la version 1.5.3 introduit un petit changement dans la gestion des caractéristiques.

 

Sur le même sujet en anglais quelqu'un a posté une nouvelle version avec un override de la classe Product.php qui remplace les overrides des controleurs ProductController.php et CompareController.php, en faisant le même travail.

Je n'ai pas testé (pas encore essayé la 1.5.3) mais ça devrait corriger ce problème d'affichage...

J'espère que vous n'êtes pas fâchés avec la langue de Shakespeare... ;)

http://www.prestasho...ost__p__1085967

 

Je regarderai aussi et je vous dirai...

Share this post


Link to post
Share on other sites

  • 3 weeks later...

Bonjour à tous,

 

je suis intéressé par cette modification, mais avec la possibilité d'affichage de pictogrammes

J'ai trouvé ce sujet http://www.prestashop.com/forums/topic/83009-tutorial-devforever-ajouter-pictogrammes-valeurs-carateristiques/ mais, malheureusement, la variable n'est pas passée au template ...

Un peu d'aide serait la bienvenue ...

 

Cordialement,

Share this post


Link to post
Share on other sites

J'ai fait un 2ème site, sous 1.5.3.1 (comme le 1er pour lequel les modifs de Mellow et le changement du SELECT préconisé par Nomata avait très bien fonctionné) : les caractéristiques multiples ne veulent plus s'afficher correctement !?

Je n'en ai qu'une qui apparait.

J'ai regardé les fichiers en long en large et en travers : sur les 2 sites j'ai les mêmes fichiers, à la même place, la BDD est correcte, je n'arrive pas à comprendre pourquoi sur le nouveau site ça n'en affiche qu'une alors que sur l'autre site ça fonctionne.

Savez-vous si quelque chose à changer ?

 

Merci

 

Edit : ben voilà, après 2 jours à chercher sans rien trouver, j'avais laissé tomber et continuer à renseigner la boutique et ben, en regardant la page produit après une journée, les caractéristiques s'affichaient correctement... je ne sais donc pas pourquoi ça ne marchait pas.............

Edited by MarineWD (see edit history)

Share this post


Link to post
Share on other sites

Bonjour,

 

Peut-on faire un récapitulatif sur cette question en version 1.5.3.1 ?

Perso, je n'ai pas modifié de codes ni rien. seulement fait des tests d'importation csv avec des caractéristiques en écrivant par exemple "couleur : rouge". s'affiche alors couleur rouge -- mais 1 seule caractéristique, pas 7, 8, comme j'en ai besoin.

 

Question :

comment avoir le choix multiple caractéristiques dans l'import comme on avait sous la 1.4.6 par exemple ?

comment avoir plusieurs caractéristiques sur la même fiche ?

doit-on changer des codes ?

 

Merci de votre réponse rapide, ça fait des jours que je cherche et je suis censé lancer mon site aujourd'hui, 12h max !

Share this post


Link to post
Share on other sites

Bon, je viens de tester sur PS1.5.3.1

Avec la version posté par un membre sur le topic en Anglais (et après correction d'une petite erreur dans le zip) tout à l'air de fonctionner très bien.

 

Je vous met donc ici le zip corrigé, il contient les fichiers :

/override/controllers/admin/AdminProductsController.php

/override/controllers/admin/templates/products/features.tpl

/override/classes/Product.php

install.sql

 

select-multiple-feature-values_override-files_PSv1.5.3.1.zip

 

Sur une installation "fraiche" de PS1.5.3.1 en mettant en place les fichiers override, et en appliquant sur la base de donnée la commande sql contenu dans install.sql, tout fonctionne bien.

On peut bien choisir plusieurs valeurs pour une caractéristique en back office, et l'affichage est correctement répercuté en front office. (aussi bien sur les fiches produits que sur la page de comparaison des produits)

 

Maintenant pour ce qui est des imports/exports csv il faudra voir comment modifier/adapter votre code.

Tel quel, Prestashop ne devrait importer ou exporter qu'une seule valeur par caractéristique et par produit.

 

Si quelqu'un a fait une modif pour la gestion de ces valeurs multiples lors de l'import/export merci de le poster ici, ça pourra servir à certains

Edited by Mellow (see edit history)

Share this post


Link to post
Share on other sites

  • 2 weeks later...

Merci Mellow pour ton partage!

 

 

Je suis en 1.5.3.1, j'ai une install fraiche de prestashop (seulement un thème installé) et en copiant les fichiers du zip + en mettant les 3 clef primaires sur la table ps_feature_product cela n'a pas l'air de fonctionner:

Depuis le BO, je peux bien sélectionner des multiples valeurs pour une caractéristique mais lorsque j'enregistre et que je reviens ensuite sur le produit seulement une est cochée!

 

Par ailleurs ma table: ps_feature_product reste vide, c'est normal?

Edited by sloshy (see edit history)

Share this post


Link to post
Share on other sites

Hello,

 

Le code fourni par Mellow et notre ami anglophone fonctionne de façon assez aléatoire chez moi aussi en 1.5.3.1.

 

C'est lié au fait que les fonctions getFrontFeaturesStatic et cacheFrontFeatures font presque la même chose.

Si on passe d'abord dans cacheFrontFeatures, alors les données sont mises en 'cache' (!), sans le traitement qui remplace les lignes multiples par une seule ligne avec plusieurs valeurs.

Quand on passe après par getFrontFeaturesStatic, la fonction utilise ce pseudo cache qui ne contient donc plus nos valeurs.

 

Je vous propose donc les fonctions suivantes à placer dans l'override de la classe product: (\override\classes\Product.php)

 

//Plutot que de dupliquer du code comme c'est fait actuellement, autant réutiliser le code existant dans 'cacheFrontFeatures'
public static function getFrontFeaturesStatic($id_lang, $id_product)
{
 if (!array_key_exists($id_product.'-'.$id_lang, parent::$_frontFeaturesCache))
 {
  parent::cacheFrontFeatures(array($id_product), $id_lang);
 }
 if(!array_key_exists($id_product.'-'.$id_lang, parent::$_frontFeaturesCache)) {
  //on mets tout de même un tableau vide pour ne pas y essayer de le replir à chaque fois
  parent::$_frontFeaturesCache[$id_product.'-'.$id_lang] = array();
 }
 $features = parent::$_frontFeaturesCache[$id_product.'-'.$id_lang];
 return $features;
}
public static function cacheFrontFeatures($product_ids, $id_lang)
{
 if (!Feature::isFeatureActive())
  return;
 $product_implode = array();
 foreach ($product_ids as $id_product)
  if ((int)$id_product && !array_key_exists($id_product.'-'.$id_lang, self::$_cacheFeatures))
   $product_implode[] = (int)$id_product;
 if (!count($product_implode))
  return;
 $features = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('
 SELECT id_product, name, value, pf.id_feature
 FROM '._DB_PREFIX_.'feature_product pf
 LEFT JOIN '._DB_PREFIX_.'feature_lang fl ON (fl.id_feature = pf.id_feature AND fl.id_lang = '.(int)$id_lang.')
 LEFT JOIN '._DB_PREFIX_.'feature_value_lang fvl ON (fvl.id_feature_value = pf.id_feature_value AND fvl.id_lang = '.(int)$id_lang.')
 LEFT JOIN '._DB_PREFIX_.'feature f ON (f.id_feature = pf.id_feature)
 WHERE `id_product` IN ('.implode($product_implode, ',').')
 ORDER BY f.position ASC');
 //NOMATA 20130308: ajouté pour transformer plusieurs lignes en 1 seule avec plusieurs valeurs
 $features_key = array();
 foreach ($features as $key => $feature) {
  if (!array_key_exists($feature['name'], $features_key)) {
 $features_key[$feature['name']] = $key;
  } else {
 $features[ (int)$features_key[$feature['name']] ]['value'] .= ', ' . $feature['value'] ;
 unset($features[$key]);
  }
 }
 //fin ajout
 foreach ($features as $row)
 {
  if (!array_key_exists($row['id_product'].'-'.$id_lang, parent::$_frontFeaturesCache))
   parent::$_frontFeaturesCache[$row['id_product'].'-'.$id_lang] = array();
  if (!isset(parent::$_frontFeaturesCache[$row['id_product'].'-'.$id_lang][$row['id_feature']]))
   parent::$_frontFeaturesCache[$row['id_product'].'-'.$id_lang][$row['id_feature']] = $row;
 }
}

 

Voila, ça devrait mieux marcher... mais je n'ai pas vérifié toutes les fonctions.

Share this post


Link to post
Share on other sites

Merci Nomata, même avec ce code cela ne marche toujours pas chez moi, je "coche" plusieurs propriétés mais une seule semble sauvegardé. (j'ai pas eu le temps encore de débugger pour voir ce qui ne va pas)

Share this post


Link to post
Share on other sites

Sloshy,

Regarde en base de données sur la table ps_product_features si c'est bien enregistré (pour un id_product et un id_feature, tu dois avoir plusieurs lignes id_feature_value). Normalement c'est bon.

Regarde aussi si tu as un cache activé qui garderai les anciennes valeurs mal calculées. Si oui désactive et vide ton cache (les fichiers dans le cache ou ton cache APC suivant ta config). J'ai l'impression que toute la table ps_configuration peut se retrouver en cache. Du coup la clé indiquant si le cache est activé se retrouve aussi en cache et n'est pas mise à jour !!!.

Share this post


Link to post
Share on other sites

Hello,

 

Mon code s'est mis à ne plus fonctionner (sans changement !?).

En regardant de plus près, on dirait que cela vient du fait de faire appel à une fonction overridée à partir d'une autre fonction overridée... (???)

Voici une modification qui contourne ce problème:

 

//Plutot que de dupliquer du code comme c'est fait actuellement, autant réutiliser le code existant dans 'cacheFrontFeatures'
public static function getFrontFeaturesStatic($id_lang, $id_product)
{
 //ppp("public static function Override _ getFrontFeaturesStatic($id_lang, $id_product)");
 if (!array_key_exists($id_product.'-'.$id_lang, parent::$_frontFeaturesCache))
 {
  self::cacheFrontFeaturesFromOverride(array($id_product), $id_lang);
 }
 if(!array_key_exists($id_product.'-'.$id_lang, parent::$_frontFeaturesCache)) {
  //on mets tout de même un tableau vide pour ne pas y essayer de le replir à chaque fois
  parent::$_frontFeaturesCache[$id_product.'-'.$id_lang] = array();
 }
 $features = parent::$_frontFeaturesCache[$id_product.'-'.$id_lang];
 return $features;
}
//Je n'arrive pas à appeler la fonction 'cacheFrontFeatures' à partir de la fonction dans l'override.
//je passe donc par une fonction intermédiaire 'cacheFrontFeaturesFromOverride' !
public static function cacheFrontFeatures($product_ids, $id_lang)
{
 return self::cacheFrontFeaturesFromOverride($product_ids, $id_lang);
}
public static function cacheFrontFeaturesFromOverride($product_ids, $id_lang)
{
 //ppp("public static function cacheFrontFeatures OVERRIDE ($id_lang, $product_ids)");
 if (!Feature::isFeatureActive())
  return;
 $product_implode = array();
 foreach ($product_ids as $id_product)
  if ((int)$id_product && !array_key_exists($id_product.'-'.$id_lang, self::$_cacheFeatures))
$product_implode[] = (int)$id_product;
 if (!count($product_implode))
  return;
 $sql='
 SELECT id_product, name, value, pf.id_feature
 FROM '._DB_PREFIX_.'feature_product pf
 LEFT JOIN '._DB_PREFIX_.'feature_lang fl ON (fl.id_feature = pf.id_feature AND fl.id_lang = '.(int)$id_lang.')
 LEFT JOIN '._DB_PREFIX_.'feature_value_lang fvl ON (fvl.id_feature_value = pf.id_feature_value AND fvl.id_lang = '.(int)$id_lang.')
 LEFT JOIN '._DB_PREFIX_.'feature f ON (f.id_feature = pf.id_feature)
 WHERE `id_product` IN ('.implode($product_implode, ',').')
 ORDER BY f.position ASC';
 $features = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql);
 //ppp($features);
 //NOMATA 20130308: ajouté pour transformer plusieurs lignes en 1 seule, avec plusieurs valeurs
 $separator = ' / ';
 $features_key = array();
 foreach ($features as $key => $feature) {
  if (!array_key_exists($feature['name'], $features_key)) {
 $features_key[$feature['name']] = $key;
  } else {
 $features[ (int)$features_key[$feature['name']] ]['value'] .= $separator . $feature['value'] ;
 unset($features[$key]);
  }
 }
 //fin ajout
 foreach ($features as $row)
 {
  if (!array_key_exists($row['id_product'].'-'.$id_lang, parent::$_frontFeaturesCache))
parent::$_frontFeaturesCache[$row['id_product'].'-'.$id_lang] = array();
  if (!isset(parent::$_frontFeaturesCache[$row['id_product'].'-'.$id_lang][$row['id_feature']]))
parent::$_frontFeaturesCache[$row['id_product'].'-'.$id_lang][$row['id_feature']] = $row;
 }
}

Edited by Nomata (see edit history)

Share this post


Link to post
Share on other sites

Bonjour,

 

Désolé pour les utilisateurs de PS1.5.x, mais je ne peux pas vraiment vous aider car je n'ai pas fais d’essais prolongés sur ces versions (en particulier les toutes dernières).

Il semble que pour certains ça fonctionne bien et pour d'autres non, alors peut-être qu'il faudrait voir du coté de vos configurations (en particulier les différents caches activés)

Share this post


Link to post
Share on other sites

Bonjour,

Au sujet du bloc de navigation à facettes,

Par défaut il y a le titre "catalogue" par défaut. Comment le modifier ?

Est-il possible de donner à un produit, plusieurs valeurs d'un même attribut ?

 

Aussi, je ne sais pourquoi mais la liste des couleurs qui étaient représentées par une palette est présentée avec des boutons à cocher maintenant, savez-vous comment rétablir l'affichage d'origine des couleurs ?

 

Merci

Share this post


Link to post
Share on other sites

@amoric69,

 

Bonjour,

 

Le titre du bloc navigation a facettes reste le même partout sur le site, mais il peut être modifié en le traduisant. Dans le back office, traduction des modules installés (traduire pour chaque langue utilisée, même l'anglais...)

 

Donner à un produit plusieurs valeurs d'un même attribut, c'est le principe même des attributs/déclinaisons ! (d'ailleurs la couleur est un attribut...) Par contre ce n'est pas du tout le même principe que les caractéristiques, chaque valeur d'attribut représente un produit à part entière. Pour bien appréhender ça Il faut potasser la doc de Prestashop : v1.4 & v1.5

 

Pour la représentation des couleurs qui a changé, je ne sais pas du tout d’où ça peut venir... Mais en tout cas, pas de cette modification !

 

Ceci dit, la navigation à facettes n'est pas vraiment le sujet ici... ;)

Share this post

<