Recevoir un email lorsqu’un commentaire est déposé sur la boutique

Si comme moi vous utilisez le module productComment livré par défaut avec prestashop vous avez sans doute constaté que rien n’était prévu pour être averti lorsqu’un commentaire était déposé sur la boutique. Je trouve cela particulièrement dommage car cela implique de venir régulièrement ouvrir le module pour vérifier si un nouveau commentaire a été posté.

Voici donc une solution pour faire en sorte qu’un email vous soit automatiquement envoyé lorsque l’un de vos clients dépose un commentaire.

Dans le fichier « modules/productcomments/controllers/front/defaut.php » repérez le code suivant (ligne 120 environ):


if (count(Tools::getValue('criterion')) >= 1)
				{
					$comment->grade = $grade_sum / count(Tools::getValue('criterion'));
					// Update Grade average of comment
					$comment->save();				
				}

Et ajoutez ceci à la suite:


//send mail
$donnees = array('{texte}' => "nouveau commentaire sur la boutique");
Mail::Send((int)Context::getContext()->language->id,
	'newcomment',
	'nouveau commentaire',
	$donnees,
	Configuration::get('PS_SHOP_EMAIL'),
	null,
	null,
	null,
	null,
	null,
	dirname(__FILE__).'/../../mails/');

Créez ensuite un dossier « modules/productcomments/mails/ » et ajoutez y un sous dossier par langue de votre boutique. Chaque dossier doit utiliser le code ISO de la langue c’est à dire « fr » pour « français », « en » pour « english », etc.
Créez ensuite les fichiers « newcomment.html » et « newcomment.txt », placez-les dans les dossier de langue que vous venez de créer et ajoutez y le code suivant (dans les deux fichiers html et txt):


{texte}

Voila désormais lorsqu’un utilisateur déposera un commentaire sur votre boutique vous en serez averti.

Ps: cette modification touche directement au fichier du module, cela signifie qu’éventuellement lors d’une mise à jour vos modifications seront écrasées.

Ps2: J’ai fait cette modification sur une version 1.5.4.1 de Prestashop.

La solution est alors de faire un override des fichiers php du module. Ceci n’est pour l’instant pas prévu par Prestashop il faut utiliser cette solution

/*** edit 09/07/13 ***/

Devnet m’a suggéré une petite amélioration via le forum de Prestashop.
Je vous la met donc ci-dessous:
Dans le fichier « defaut.php » remplacez le code suivant:


$donnees = array('{texte}' => "nouveau commentaire sur la boutique");

par :


$donnees = array(
    '{texte}' => $module_instance->l('New comment available'),
    '{content}' => $comment->content,
    '{id_product}' => $comment->id_product,
    '{id_customer}' => $comment->id_customer,
    '{customer_name}' => $comment->customer_name,
    '{title}' => $comment->title,
    '{grade}' => $comment->grade
   );

et dans les fichiers newcomment.html et newcomment.txt remplacez:


{texte}

par


{texte}
{content}
{id_product}
{id_customer}
{customer_name}
{title}
{grade}

Vous récupérerez ainsi le contenu du commentaire et des infos sur le client, merci Devnet !

*** EDIT 09/08/13 ***
Apparemment plsuieurs personnes n’arrivent pas à ajouter le code où il faut donc voici ce que cela donne une fois modifié:


if (count(Tools::getValue('criterion')) >= 1)
				{
					$comment->grade = $grade_sum / count(Tools::getValue('criterion'));
					// Update Grade average of comment
					$comment->save();
				}
				//send mail
				$donnees = array(
					'{texte}' => $module_instance->l('New comment available'),
					'{content}' => $comment->content,
					'{id_product}' => $comment->id_product,
					'{id_customer}' => $comment->id_customer,
					'{customer_name}' => $comment->customer_name,
					'{title}' => $comment->title,
					'{grade}' => $comment->grade
				);				
				Mail::Send((int)Context::getContext()->language->id,
						'newcomment',
						'nouveau commentaire',
						$donnees,
						Configuration::get('PS_SHOP_EMAIL'),
						null,
						null,
						null,
						null,
						null,
						dirname(__FILE__).'/../../mails/');
				
				$result = true;

Retrouvez deux autres améliorations pour ce module ci-dessous:
Alerte email lorsqu’un commentaire est déposé
5 Etoiles par défaut sur vos commentaires

Ne pas ajouter de cadre blanc autour de vos images sous Prestashop

Lorsqu’on upload une image produit (ou autre) dans prestashop, ce dernier la redimensionne selon les différents formats spécifiés dans « préférences/images ». C’est très pratique mais malheureusement prestashop ajoute systématiquement un fond blanc autour de l’image si cette dernière n’est pas exactement proportionnelle aux différents formats (ce qui arrive la plupart du temps).
Voici une solution pour que le fond soit transparent plutôt que blanc, vous pourrez ainsi le gérer plus facilement vos règles CSS.

Il suffit pour cela de faire un override de la méthode « resize » de la classe « ImageManager ».

Créez un fichier nommé « imageManager.php » dans le dossier « override/classes » et ajoutez-y le code suivant:


<?php
class ImageManager extends ImageManagerCore
{

	/**
	 * Resize, cut and optimize image
	 *
	 * @param string $src_file Image object from $_FILE
	 * @param string $dst_file Destination filename
	 * @param integer $dst_width Desired width (optional)
	 * @param integer $dst_height Desired height (optional)
	 * @param string $file_type
	 * @return boolean Operation result
	 */
	public static function resize($src_file, $dst_file, $dst_width = null, $dst_height = null, $file_type = 'jpg', $force_type = false)
	{
		if (PHP_VERSION_ID < 50300)
			clearstatcache();
		else
			clearstatcache(true, $src_file);
		
		if (!file_exists($src_file) || !filesize($src_file))
			return false;
		list($src_width, $src_height, $type) = getimagesize($src_file);

		// If PS_IMAGE_QUALITY is activated, the generated image will be a PNG with .jpg as a file extension.
		// This allow for higher quality and for transparency. JPG source files will also benefit from a higher quality
		// because JPG reencoding by GD, even with max quality setting, degrades the image.
		if (Configuration::get('PS_IMAGE_QUALITY') == 'png_all'
			|| (Configuration::get('PS_IMAGE_QUALITY') == 'png' && $type == IMAGETYPE_PNG) && !$force_type)
			$file_type = 'png';

		if (!$src_width)
			return false;
		if (!$dst_width)
			$dst_width = $src_width;
		if (!$dst_height)
			$dst_height = $src_height;

		$src_image = ImageManager::create($type, $src_file);

		$width_diff = $dst_width / $src_width;
		$height_diff = $dst_height / $src_height;

		if ($width_diff > 1 && $height_diff > 1)
		{
			$next_width = $src_width;
			$next_height = $src_height;
		}
		else
		{
			if (Configuration::get('PS_IMAGE_GENERATION_METHOD') == 2 || (!Configuration::get('PS_IMAGE_GENERATION_METHOD') && $width_diff > $height_diff))
			{
				$next_height = $dst_height;
				$next_width = round(($src_width * $next_height) / $src_height);
				$dst_width = (int)(!Configuration::get('PS_IMAGE_GENERATION_METHOD') ? $dst_width : $next_width);
			}
			else
			{
				$next_width = $dst_width;
				$next_height = round($src_height * $dst_width / $src_width);
				$dst_height = (int)(!Configuration::get('PS_IMAGE_GENERATION_METHOD') ? $dst_height : $next_height);
			}
		}

		if (!ImageManager::checkImageMemoryLimit($src_file))
			return false;
		
		$dest_image = imagecreatetruecolor($dst_width, $dst_height);

		//ici on applique un fond transparent quelque soit le type de fichier.
		imagealphablending($dest_image, false);
		imagesavealpha($dest_image, true);
		$transparent = imagecolorallocatealpha($dest_image, 255, 255, 255, 127);
		imagefilledrectangle($dest_image, 0, 0, $dst_width, $dst_height, $transparent);

		imagecopyresampled($dest_image, $src_image, (int)(($dst_width - $next_width) / 2), (int)(($dst_height - $next_height) / 2), 0, 0, $next_width, $next_height, $src_width, $src_height);
		return (ImageManager::write($file_type, $dest_image, $dst_file));
	}
}


Si jamais votre override ne s’applique pas pensez à supprimer le fichier « class_index.php » qui se trouve dans le dossier « cache » à la racine de votre boutique.

Comment créer un helper sous prestashop

Si vous développez des modules pour prestashop et que vos modules génèrent et utilisent des onglets vous avez sans doute dû être étonné de voir qu’aucun helper n’existe pour créer des checkbox.
C’est à mon avis un oubli de la team Ps, mais on va y remédier. Au passage vous allez en plus apprendre comment créer un helper ce qui vous permettra à l’avenir de créer des formulaires avancés pour vos modules.
Continuer la lecture de « Comment créer un helper sous prestashop »

Impossible d’ajouter du javascript dans vos descriptions de produit

Si vous utilisez la version 1.5.5 de Prestashop vous avez peut-être rencontré le message d’erreur suivant en essayant d’ajouter du javascript dans vos descriptions de produits:

Le champ description (Français (French)) est invalide.

Ce problème est dû à une sécurité ajoutée sur prestashop 1.5.5. C’est en soit une bonne chose, mais pour ceux qui comme moi ont parfois besoin d’ajouter des codes javascript c’est très gênant et il aurait été plus judicieux d’ajouter un réglage dans les préférences de la boutique permettant d’activer ou pas cette protection.

En attendant voici ce que vous pouvez faire pour à nouveau avoir l’autorisation d’ajouter du javascript dans vos descriptions:

– Créez un fichier « Product.php » dans le dossier « override/classes » de votre boutique et ajoutez-y le code suivant:


<?php

class Product extends ProductCore
{

public static $definition = array(
'table' => 'product',
'primary' => 'id_product',
'multilang' => true,
'multilang_shop' => true,
'fields' => array(
// Classic fields
'id_shop_default' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'),
'id_manufacturer' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'),
'id_supplier' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'),
'reference' => array('type' => self::TYPE_STRING, 'validate' => 'isReference', 'size' => 32),
'supplier_reference' => array('type' => self::TYPE_STRING, 'validate' => 'isReference', 'size' => 32),
'location' => array('type' => self::TYPE_STRING, 'validate' => 'isReference', 'size' => 64),
'width' => array('type' => self::TYPE_FLOAT, 'validate' => 'isUnsignedFloat'),
'height' => array('type' => self::TYPE_FLOAT, 'validate' => 'isUnsignedFloat'),
'depth' => array('type' => self::TYPE_FLOAT, 'validate' => 'isUnsignedFloat'),
'weight' => array('type' => self::TYPE_FLOAT, 'validate' => 'isUnsignedFloat'),
'quantity_discount' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'),
'ean13' => array('type' => self::TYPE_STRING, 'validate' => 'isEan13', 'size' => 13),
'upc' => array('type' => self::TYPE_STRING, 'validate' => 'isUpc', 'size' => 12),
'cache_is_pack' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'),
'cache_has_attachments' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'),
'is_virtual' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'),

/* Shop fields */
'id_category_default' => array('type' => self::TYPE_INT, 'shop' => true, 'validate' => 'isUnsignedId'),
'id_tax_rules_group' => array('type' => self::TYPE_INT, 'shop' => true, 'validate' => 'isUnsignedId'),
'on_sale' => array('type' => self::TYPE_BOOL, 'shop' => true, 'validate' => 'isBool'),
'online_only' => array('type' => self::TYPE_BOOL, 'shop' => true, 'validate' => 'isBool'),
'ecotax' => array('type' => self::TYPE_FLOAT, 'shop' => true, 'validate' => 'isPrice'),
'minimal_quantity' => array('type' => self::TYPE_INT, 'shop' => true, 'validate' => 'isUnsignedInt'),
'price' => array('type' => self::TYPE_FLOAT, 'shop' => true, 'validate' => 'isPrice', 'required' => true),
'wholesale_price' => array('type' => self::TYPE_FLOAT, 'shop' => true, 'validate' => 'isPrice'),
'unity' => array('type' => self::TYPE_STRING, 'shop' => true, 'validate' => 'isString'),
'unit_price_ratio' => array('type' => self::TYPE_FLOAT, 'shop' => true),
'additional_shipping_cost' => array('type' => self::TYPE_FLOAT, 'shop' => true, 'validate' => 'isPrice'),
'customizable' => array('type' => self::TYPE_INT, 'shop' => true, 'validate' => 'isUnsignedInt'),
'text_fields' => array('type' => self::TYPE_INT, 'shop' => true, 'validate' => 'isUnsignedInt'),
'uploadable_files' => array('type' => self::TYPE_INT, 'shop' => true, 'validate' => 'isUnsignedInt'),
'active' => array('type' => self::TYPE_BOOL, 'shop' => true, 'validate' => 'isBool'),
'redirect_type' => array('type' => self::TYPE_STRING, 'shop' => true, 'validate' => 'isString'),
'id_product_redirected' => array('type' => self::TYPE_INT, 'shop' => true, 'validate' => 'isUnsignedId'),
'available_for_order' => array('type' => self::TYPE_BOOL, 'shop' => true, 'validate' => 'isBool'),
'available_date' => array('type' => self::TYPE_DATE, 'shop' => true, 'validate' => 'isDateFormat'),
'condition' => array('type' => self::TYPE_STRING, 'shop' => true, 'validate' => 'isGenericName', 'values' => array('new', 'used', 'refurbished'), 'default' => 'new'),
'show_price' => array('type' => self::TYPE_BOOL, 'shop' => true, 'validate' => 'isBool'),
'indexed' => array('type' => self::TYPE_BOOL, 'shop' => true, 'validate' => 'isBool'),
'visibility' => array('type' => self::TYPE_STRING, 'shop' => true, 'validate' => 'isProductVisibility', 'values' => array('both', 'catalog', 'search', 'none'), 'default' => 'both'),
'cache_default_attribute' => array('type' => self::TYPE_INT, 'shop' => true),
'advanced_stock_management' => array('type' => self::TYPE_BOOL, 'shop' => true, 'validate' => 'isBool'),
'date_add' => array('type' => self::TYPE_DATE, 'shop' => true, 'validate' => 'isDateFormat'),
'date_upd' => array('type' => self::TYPE_DATE, 'shop' => true, 'validate' => 'isDateFormat'),

/* Lang fields */
'meta_description' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'size' => 255),
'meta_keywords' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'size' => 255),
'meta_title' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'size' => 128),
'link_rewrite' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isLinkRewrite', 'required' => true, 'size' => 128),
'name' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isCatalogName', 'required' => true, 'size' => 128),
'description' => array('type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isString'),
'description_short' => array('type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isString'),
'available_now' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'size' => 255),
'available_later' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'IsGenericName', 'size' => 255),
),
'associations' => array(
'manufacturer' => array('type' => self::HAS_ONE),
'supplier' => array('type' => self::HAS_ONE),
'default_category' => array('type' => self::HAS_ONE, 'field' => 'id_category_default', 'object' => 'Category'),
'tax_rules_group' => array('type' => self::HAS_ONE),
'categories' => array('type' => self::HAS_MANY, 'field' => 'id_category', 'object' => 'Category', 'association' => 'category_product'),
'stock_availables' => array('type' => self::HAS_MANY, 'field' => 'id_stock_available', 'object' => 'StockAvailable', 'association' => 'stock_availables'),
),
);
}

Cela aura pour effet de remplacer le type de sécurité appliquée « isCleanHtml » par « isString » aux champs description et description_short des produits.

Vous pouvez rencontrer le même problème sur les pages CMS, vous trouverez ici la solution.

Mémo prestashop

Je suis toujours à la recherche de « trucs » très simples mais difficiles à mémoriser si on ne les utilise pas souvent. Donc au lieu de chercher à chaque fois sur le net je me suis dit qu’il serait utile de les centraliser à un même endroit. Voici donc diverses astuces pour ceux qui font de la programmation, intégration ou tout simplement qui utilisent Prestashop.
Continuer la lecture de « Mémo prestashop »