mardi 17 septembre 2013

Prestashop 1.5 --> redirection htaccess www

problématique du jour :

La boutique en question est accessible sans les www.
http://domaine.extension

Classique, presta génère son htaccess en prévoyant le cas de figure, c'est bon.
Hé ben non.

Ca génère du 404 à la volée pour tous les appels www

Hé bien..puisque nous n'avons pas accès (en un temps acceptable, merci les agences de com') à la gestion DNS, on va régler le problème via htaccess

RewriteCond %{REQUEST_URI} !^/fr/
RewriteRule ^(en|es|it|de)/(.*)$ http://domaine.extension/fr/$2 [QSA,R=301,L]
RewriteCond %{HTTP_HOST} !^domaine\.extension$ [NC]
RewriteCond %{REQUEST_URI} ^/fr/
RewriteRule ^(.*)$ http://domaine.extension/$1 [QSA,R=301,L]
RewriteCond %{HTTP_HOST} !^domaine\.extension$ [NC]
RewriteCond %{REQUEST_URI} ^/$
RewriteRule ^(.*)$ http://domaine.extension/$1 [QSA,R=301,L]

A y'est, tout le traffic www rebascule bien sur le domaine sans générer de 404.

vendredi 28 juin 2013

Prestashop 1.4.10 : conserver filtre manufacturer sur tout le site

Problème du jour :
- Site avec quelques fournisseurs et 5 catégories ---> conserver le filtre "fournisseur" quand on change de catégorie.
Donc, les catégories deviennent dynamiquement :
- catégorie1 fournisseur1

Le truc, donc, c'est de récupérer l'id_manufacturer et de la déployer dans les requêtes SQL et la génération des liens.

On commence par :
le listing produit.
classes/Category.php

Nous modifions public function getProducts
ligne 535
$id_supplier = (int)(Tools::getValue('id_supplier'));
en dessous :
$id_manufacturer = (int)(Tools::getValue('id_manufacturer'));

Pour le nombre d eproduits correspondant au filtre fournisseur :
Dans la requête if ($getTotal) (ligne 541)
WHERE cp.`id_category` = '.(int)($this->id).($active ? ' AND p.`active` = 1' : '').'
'.($id_supplier ? 'AND p.id_supplier = '.(int)($id_supplier) : ''));

on rajoute le test d'existence du manufacturer

WHERE cp.`id_category` = '.(int)($this->id).($active ? ' AND p.`active` = 1' : '').'
'.($id_manufacturer ? 'AND p.id_manufacturer = '.(int)$id_manufacturer : '').'
'.($id_supplier ? 'AND p.id_supplier = '.(int)($id_supplier) : ''));

idem dans la requete du dessous
A la ligne 567 :
WHERE cp.`id_category` = '.(int)($this->id).($active ? ' AND p.`active` = 1' : '').'
'.($id_manufacturer ? 'AND p.id_manufacturer = '.(int)$id_manufacturer : '').'
'.($id_supplier ? 'AND p.id_supplier = '.(int)$id_supplier : '');

On va désormais dans controllers/CategoryController.php
Et on va assigner au template smarty le nom du manufacturer (histoire de bien préciser, dans l'entete du listing produit, qu'on affiche les résultats correspondants à un fabriquant bien spécifique)

ligne 173, on rajoute :
$id_manufacturer = (int)(Tools::getValue('id_manufacturer'));
$name2 = Manufacturer::getNameById($id_manufacturer);
self::$smarty->assign('namemanu', $name2);
namemanu devient donc la variable smarty qui affichera le nom du fabriquant

Le tpl category-count.tpl
ligne 30, à la fin (après le {/if}, on rajoute : de la marque {$namemanu}
Ca donnera un truc du genre :
categorie1 il y a 16 produits de la marque xxxxx

Bon.
Désormais, il va falloir :
ajouter l'id_manufacturer aux liens produits (pour que le filtre soit conservé tout le temps)
ajouter le nom du fabriquant aux item de menu principal (histoire de bien expliquer qu'on est dans une boutique filtrée par fabriquant)

classes/Link.php
on modifie public function getProductLink
sous global $cookie;

on rajoute

$id_manufacturer = (int)(Tools::getValue('id_manufacturer'));


toutes les occurences

$link .= (_PS_BASE_URL_.__PS_BASE_URI__.'product.php?id_product='.(int)$id_product->id
deviennent :

$link .= (_PS_BASE_URL_.__PS_BASE_URI__.'product.php?id_product='.(int)$id_product->id.''.($id_manufacturer ? '&id_manufacturer='.(Tools::getValue('id_manufacturer')) : ''));


pour le menu :
Bon, là, ca dépend du mofule utilisé, mais généralement, on retrouve toujours une fonction getCategory
avec généralement le 
$name = $categorie->name;
En dessous, on rajoute :
  $id_manufacturer = (Tools::getValue('id_manufacturer'));
   $name2 = Manufacturer::getNameById($id_manufacturer);
    $this->_menu .= ''.$name.'
'.$name2.'
';

Voili voilou


jeudi 6 juin 2013

Virtuemart 2 - facebox is not defined

Comme le dit le sage : Virtuemart a l'art et la manière de rendre compliquées les aspects les plus simples du ecommerce.

Voyons cela avec la popup "ajouter au panier"

Si vous êtes sur cette page, c'est que ça plante, forcément.
Votre profiler de script vous indique "facebox is not defined" et ça énerve. ouais, je sais, ça m'a énervé aussi.

Tout ça à cause de jquery, comme d'hab.

Solution :
components/com_virtuemart/assets/js/facebox.js

Juste avant ligne 70
 (function($) {

On rajoute
jQuery(document).ready(function() {

Et tout à la fin, on rajoute :
});

Et hop ! il est enfin defined.


jeudi 27 décembre 2012

prestashop : afficher les mots clés recherchés dans GoogleAnalytics

La problématique :
"Arrgghh !! Dans GoogleAnalytics, contenu / recherche sur site, y'a rien !!! mes mots clés, ben, y sont pas suivis !! et pourtant, j'ai bien dit "search_query" dans le filtre !!"

La solution
 Voyons, petit padawan, prestashop, c'est si intelligement pensé que les mots recherchés passent en POST, donc invisibles pour googleAnalytics.
Alors, on va creuser un ch'tit peu.
Et modifier carrément le code de suivi.

modules ---> ganalytics ----> ganalytics.php

ligne 157, tu as :

function hookHeader($params)
{
// Better way to check which file / controller name is loaded
if (!($file = basename(Tools::getValue('controller'))))
$file = str_replace(array('.php', '-'), '', basename($_SERVER['SCRIPT_NAME']));

Juste en dessous, tu vas ajouter ceci :

if($file == "category" ||
$file == "product" ||
$file == "search" ||
$file == "cms" ||
$file == "index") {
$file = $_SERVER["REQUEST_URI"];
}

Et voilà, désormais, tu récupères les termes recherchés sous prestashop dans ton analytics.

Précision :
si tu n'axs pas activé la ré-écriture des url (genre, parce que tu as une architecture complexe et que le module de ré-écriture de base te fout la zone), le code ci-dessous permettra un suivi pointu des catégories par id et des produits.
Si tu as juste besoin du "search", tu peux supprimer des conditions.



mercredi 27 juin 2012

Prestashop : enregistrer une commande sans passer par prestashop

Bon.

Tordue, comme idée, hein ?
Mais bon, il se peut que vous avez envie de développer des opérations bien personnalisées qui ne nécessitent pas le processus complet de commande d'un presta : genre, une page produit qui enregistre directement une commande à partir des données saisies sur cette page.

C'est parti.
Volontairement, à l'arrache avec des requêtes basiques et simples, que tout le monde comprenne bien le processus. Adaptez à votre sauce après...

Je traiterai juste des requêtes, pas de la construction du controller spécifique et de sa page tpl qui va avec : si ce sujet vous intéresse, c'est que vous avez déjà un niveau technique suffisant...

Une commande, c'est d'abord un panier. Un panier, c'est d'abord un produit.

$id_product=$_POST['id_product'];
   $req = "INSERT INTO ps_cart (id_cart, id_carrier,id_lang,id_address_delivery,id_address_invoice,id_currency,id_customer,id_guest,date_add) VALUES('','0','2','0','0','1','".$_POST['id_customer']."','','".$nowtime."')";
  mysql_query($req);

   $idcart = mysql_insert_id();

   $req2 = "INSERT INTO ps_cart_product (id_cart,id_product,id_product_attribute,quantity,date_add) VALUES('".$idcart."','".$id_product."','".$attribu."','".$_POST['qty']."','".$nowtime."')";
  mysql_query($req2);

Allez, on rend les choses plus complexes : y'a une eprsonnalisation !!!

           $req3 = "INSERT INTO ps_customization (id_customization,id_product_attribute, id_cart,id_product,quantity) VALUES('','".$attribu."', '".$idcart."','".$id_product."','".$_POST['qty']."')";
  mysql_query($req3);
$idcusto = mysql_insert_id();
 
 
       $req4 = "INSERT INTO ps_customized_data (`id_customization`,`type`,`index`,`value`) VALUES ('".$idcusto."','1','1','".$_POST['textField1']."')";
  mysql_query($req4);

  $totprdoducts= $_POST['prixx']*$_POST['qty'];
  $totprdoductswt= ($_POST['prixx']*$_POST['qty'])*1.196;

//tarif livraison
 $ship='11.96'; 


 $adddr = "SELECT `id_address` FROM `ps_address` WHERE `id_customer`='".$_POST['id_customer']."' LIMIT 0,1";
 $reqadd = mysql_query($adddr);
 $adresse = mysql_fetch_assoc($reqadd);


 $totpaid= $totprdoductswt+$ship;

         $req5 = "INSERT INTO ps_orders (`id_order`,`id_carrier`,`id_lang`,`id_customer`,`id_cart`,`id_currency`,`id_address_delivery`,`id_address_invoice`,`payment`,`module`,`total_paid`,`total_paid_real`,`total_products`,`total_products_wt`,`total_shipping`,`carrier_tax_rate`,`delivery_date`,`valid`,`date_add`,`date_upd`) VALUES ('','4','2','".$_POST['id_customer']."','".$idcart."','1','".$adresse['id_address']."','".$adresse['id_address']."','Comptant à la livraison','cashondelivery','".$totpaid."','0','".$totprdoducts."','".$totprdoductswt."','".$ship."','19.600','".$nowtime."','1','".$nowtime."','".$nowtime."')";
  mysql_query($req5);
  $idord = mysql_insert_id();

  //on recupere la ref produit
$refere = $_POST['reff'];

           $req6 = "INSERT INTO ps_order_detail (`id_order_detail`,`id_order`,`product_id`,`product_attribute_id`,`product_name`,`product_quantity`,`product_price`,`product_reference`,`product_weight`,`tax_name`,`tax_rate`) VALUES ('','". $idord."','".$id_product."','".$attribu."', '".$this->product->name."','".$_POST['qty']."','".$_POST['prixx']."','".$refere."','".$wei."','TVA FR 19.6%','19.600')";
  mysql_query($req6);

             $req7 = "INSERT INTO ps_order_history (`id_order_history`,`id_employee`,`id_order`,`id_order_state`,`date_add`) VALUES ('','0','".$idord."','11','".$nowtime."')";
  mysql_query($req7);

         Et voilà, la commande est dans le manager de prestashop. Sans passer par prestashop.


jeudi 31 mai 2012

Prestashop : onglet traduction Fatal error: Maximum execution time of 30 seconds exceeded

Alors.
Y vient de mettre des nouveaux modules, qu'il veut traduire, tu penses bien.

Mais voilà, paf ! Une page blanche.
L'angoisse.
Vite, on affiche les erreurs :
config/config.inc.php
@ini_set('display_errors', 'on');

Et là, nouvelle angoisse :

Fatal error: Maximum execution time of 30 seconds exceeded

No paniq, take it easy.

Une petite règle dans le .htaccess va vous épargner de devoir toucher au php.ini
php_value max_execution_time 120 (pour 120 sec)

Et voilà !!! la page traduction s'affiche.


Prestashop - theme matrice - lien CGV fancybox ne s'ouvre pas

Ouhh la la la !!
Catastrophe !!

(lire)

Et paf ! voilà que le lien ne s'ouvre pas.
Pas de panique.
C'est tout simple.

Il suffit de remplacer 3 fichiers js dans themes/matrice/js par les fichiers originaux themes/prestashop/js
tools.js (je pense qu'en remplaçant juste celui-ci, tous les pbs seront réglés : il manque juste une fonction dans celui de matrice)
cart-summary.js
order-address.js

Et hop ! fancybox.

J'en entends déjà qui se lamentent :
"méééhhhh, c'est pas au bon format, c'est tout coupé !!!"

petite modif css :
themes/matrice/css/global.css

ligne 242 (chez moi)

div.cms {width:970px; margin-top:1.8em; float:right; padding-bottom:2em}

devient

div.cms {width:auto; margin-top:1.8em; float:right; padding-bottom:2em}

Voili, voilou