jeudi 11 décembre 2014

Du e-commerce et du jquery == de la personnalisation en ligne

Une fois n'est pas coutume, une petite présentation d'un travail.

La boutique en question : enseignes en ligne http://mon-enseigne.fr

Le moteur : une base e-commerce. (oscss, pour changer de prestashop, tiens)

Le plug-in jquery utilisé : Fancy Product Designer, chez envato
http://codecanyon.net/item/fancy-product-designer-jquery-plugin/3581183?WT.mc_id=item_update_email&utm_content=sysemail&utm_keyword=sysemail&utm_medium=sysemail&utm_source=sysemail&utm_term=sysemail

Le but ; personnalisation du plugin + intégration au processus de commande.


jeudi 9 octobre 2014

Prestashop 1.5 : afficher les messages des commandes dans le BO

Yop yop yop

Alors comme ça, les messages que l'on envoie aux clients ne sont plus affichés dans le détail des commandes du BO ?

classes/Message.php

ligne 91

On remplace la fonction getMessagesByOrderId par celle ci :

public static function getMessagesByOrderId($id_order, $private = false, Context $context = null)
{
   if (!Validate::isBool($private))
    die(Tools::displayError());
  if (!$context)
   $context = Context::getContext();
  $m = Db::getInstance()->executeS('
   SELECT m.*, c.`firstname` AS cfirstname, c.`lastname` AS clastname, e.`firstname` AS efirstname, e.`lastname` AS elastname,
   (COUNT(mr.id_message) = 0 AND m.id_customer != 0) AS is_new_for_me
   FROM `'._DB_PREFIX_.'message` m
   LEFT JOIN `'._DB_PREFIX_.'customer` c ON m.`id_customer` = c.`id_customer`
   LEFT JOIN `'._DB_PREFIX_.'message_readed` mr
    ON mr.`id_message` = m.`id_message`
    AND mr.`id_employee` = '.(isset($context->employee) ? (int)$context->employee->id : '\'\'').'
   LEFT OUTER JOIN `'._DB_PREFIX_.'employee` e ON e.`id_employee` = m.`id_employee`
   WHERE m.`id_order` = '.(int)$id_order.'
   '.(!$private ? ' AND m.`private` = 0' : '').'
   GROUP BY m.id_message
   ORDER BY m.date_add DESC
  ');

  $o = Db::getInstance()->executeS('
   SELECT ct.*, m.*, e.`firstname` AS efirstname, e.`lastname` AS elastname
   FROM `'._DB_PREFIX_.'customer_thread` ct
   LEFT JOIN `'._DB_PREFIX_.'customer_message` m ON m.`id_customer_thread` = ct.`id_customer_thread`
   LEFT OUTER JOIN `'._DB_PREFIX_.'employee` e ON e.`id_employee` = m.`id_employee`
   WHERE ct.`id_order` = '.(int)$id_order.'
   ORDER BY ct.`date_add` DESC'
  );

  return array_merge($o,$m);

}

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.