Techno-magis

Mes astuces pour PrestaShop 1.5

Mercredi 12 Mars 2014

Étant en ce moment sur PrestaShop depuis un peu plus d'une semaine, j'ai rencontré quelques difficultés lors de l'écriture de code pour modifier un module. J'ai fini par surmonter mes problèmes avec un peu d'aide trouver ici et là sur le Net (aide en ligne, blogs, forums) et avec la lecture du code même. Ce n'est jamais très compliqué une fois qu'on a compris.

Je mets ici quelques points qui m'ont semblé utiles. C'est peut-être aussi le premier d'une suite d'article, vu que j'ai eu à toucher à pas mal de choses en peu de temps : ajouter d'information dans la base, surcharge de classe, écriture de templète, injection dans une complète, etc.

Récupérer le panier

Appeler le panier et son contenu depuis presque n'importe où. Ce qui peut être pratique quand il faut faire des modifications avant qu'il soit généré par le noyau :

CODE :

$context = Context::getContext();            // appel le context
$context->currency = new Currency();         // évite un warning (utilité ?)
$cart = new Cart($context->cookie->id_cart); // appel le panier
$summary = $cart->getSummaryDetails();       // récupère le contenu du panier

Sauvegarder un objet en base

Avec une « définition » de l'objet, il est facile de le sauvegarder en base sans ajouter aucune méthode. Dans l'exemple suivant, j'avais besoin de deux champs supplémentaires pour l'objet « Product » (article).

Voilà l'objet :

CODE :

class ProductExtend extends ObjectModel {
 
	const TABLE = 'product_extend';
 
	/** @var integer */
	public $id_product;
 
	/** @var integer */
	public $champ1;
 
	/** @var integer */
	public $champ2;
 
	/**
	 * @see ObjectModel::$definition
	 */
	public static $definition = array(
		'table'     => self::TABLE,
		'primary'   => 'id_product_extend',
		'multilang' => false,
		'fields'    => array(
			'id_product'   => array( 
				 'type' => self::TYPE_INT, 
				 'validate' => 'isUnsignedInt',  
				 'required' => TRUE 
			),
			'champ1'  => array( 
				 'type' => self::TYPE_INT,   
				 'validate' => 'isUnsignedInt' 
			),
			'champ2' => array( 
				 'type' => self::TYPE_INT,  
				 'validate' => 'isUnsignedInt' 
			)
		)
	);
}

Et son appel :

CODE :

// créer l'objet et avec l'Id permet de le récupérer en base s'il existe
$produitExt = new ProductExtend($id);
 
// remplir les champs
$produitExt->champ1 = 5;
$produitExt->champ2 = 10;
 
// sauvegarde ou mise à jour
$produitExt->save();

Mettre à jour le stock d'un produit

C'est tout bête, mais $product->quantity ne modifie pas le stock d'un produit à la sauvegarde, il faut faire de cette façon :

CODE :

StockAvailable::setQuantity((int)$id_product, 0, (int)$quantity); 

Mettre à jour les tags d'un produit

J'ai un peu galéré pour trouver cette solution. Pas super élégante comme façon de faire, mais je n'ai pas trouvé mieux pour l'instant. Je suis partie d'une méthode que j'ai trouvé dans le corps (TagCore::addTags) que j'ai pas mal modifiée... voyant que les appels à l'objet Tag (TagCore) foirent complètement pour une raison qui m'échappe.

CODE :

/**
 * Met jour la liste des tags d'un produit.
 * @param Product $produit id de l'article
 * @param string|array $tag_list liste des tags
 * @param int $id_lang id de langue
 * @param string $separator réparateur de tags (défaut ',')
 */
function saveTags(Product $produit, $tag_list, $id_lang, $separator = ',') {
 
	if (!Validate::isUnsignedId($id_lang))
		return false;
 
	if (!is_array($tag_list))
		$tag_list = array_filter(array_unique(array_map('trim', 
			preg_split('#\\'.$separator.'#', $tag_list, null, PREG_SPLIT_NO_EMPTY))));
 
 
	// Ajout des tags
	$list = array();
	if (is_array($tag_list)) {
		foreach ($tag_list as $tag) {
			if (Validate::isGenericName($tag)) {
				$tag = trim(Tools::substr($tag, 0, 
					TagCore::$definition['fields']['name']['size']));
				$row = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow('
					SELECT *
					FROM `'._DB_PREFIX_.'tag` t
					WHERE `name` LIKE \''.pSQL($tag).'\' 
						AND `id_lang` = '.(int)$id_lang);
 
				if (!$row) {
					$test = Db::getInstance()->execute('
						INSERT INTO `'._DB_PREFIX_.'tag` (`id_lang`, `name`)
						VALUES ('.(int)$id_lang.', "'.pSQL($tag).'")');
 
					$list[]['id'] = Db::getInstance()->Insert_ID();
				} else {
					$list[]['id'] = $row['id_tag'];
				}
			}
		}
	}
 
	$produit->setWsTags($list);
	if (!empty($list)) {
		$produit->update();
	}
 
}

Ces solutions sont issues d'une première approche avec l'environnement. Si je trouve mieux, je n’hésiterais pas à corriger et si vous avez mieux les commentaires sont là pour ça. ;)

Catégories :
Par Zéfling, le 12/03/2014 à 21:50:05
Le billet a été lue 855 fois, avec 2 commentaires publiés.
👍 0 👎 0

2 commentaires déposés

Par Charly, le 16/07/2014 à 11:38:44
Visiteur

Bonjour,

Je me permet de te demander comment utilises-tu la fonction :

CODE :

StockAvailable::setQuantity((int)$id_product, 0, (int)$quantity);

Je suis actuellement en train de développer une passerelle pour lier ma boutique en ligne avec mon ERP afin de mettre a jour en temps réel les stock des deux boutiques.

Merci de ta réponse.

Charly


Par Zéfling, le 16/07/2014 à 21:58:20
Avatar
Webmaster

Je l'avais utilisé dans le cadre de mon précédent job pour mettre à jour les stocks depuis webservice. J'appelais le webservice et les données retournées rendaient le stock réel du produit ou des produits à l'appel du panier ou suivant d'autres modalités. Le seul problème c'est qu'il faut avoir l'ID de produit, mais avec la référence ça se trouve très facilement. L'idée c'était que PrestaShop ne gère pas les stocks, mais une application boutique.

Je ne sais pas si ça peut t'aides...

Compared to French grammar, nothing is hard. (Rasmus Lerdorf)

Écrire un commentaire