PEEL Shopping
Open source ecommerce : PEEL Shopping
Product.php
Go to the documentation of this file.
1 <?php
2 // This file should be in UTF8 without BOM - Accents examples: éèê
3 // +----------------------------------------------------------------------+
4 // | Copyright (c) 2004-2015 Advisto SAS, service PEEL - contact@peel.fr |
5 // +----------------------------------------------------------------------+
6 // | This file is part of PEEL Shopping 8.0.0, which is subject to an |
7 // | opensource GPL license: you are allowed to customize the code |
8 // | for your own needs, but must keep your changes under GPL |
9 // | More information: https://www.peel.fr/lire/licence-gpl-70.html |
10 // +----------------------------------------------------------------------+
11 // | Author: Advisto SAS, RCS 479 205 452, France, https://www.peel.fr/ |
12 // +----------------------------------------------------------------------+
13 // $Id: Product.php 47025 2015-09-24 19:23:45Z sdelaporte $
14 if (!defined('IN_PEEL')) {
15  die();
16 }
17 
28 class Product {
29  var $id = null;
30  var $technical_code = null;
31  var $name = null;
32  var $descriptif = null;
33  var $description = null;
34  var $meta_titre = null;
35  var $meta_desc = null;
36  var $meta_key = null;
37  var $lang = null;
38  var $poids = null;
39  var $volume = null;
40  var $position = null;
42  var $prix_barre = null;
43  var $prix_barre_ht = null;
44  var $prix = null;
45  var $prix_ht = null;
46  var $prix_achat = null;
47  var $reference = null;
48  var $ean_code = null;
49  var $etat = null;
50  var $on_estimate = null;
51  // prix_revendeur is the price for resellers : it is stored with taxes included, even if we will usually display it without taxes
52  var $prix_revendeur = null;
53  var $promotion = null;
54  var $prix_promo = null;
55  var $tva = null;
56  var $points = null;
57  var $default_image = null;
58  var $image1 = null;
59  var $image2 = null;
60  var $image3 = null;
61  var $image4 = null;
62  var $image5 = null;
63  var $image6 = null;
64  var $image7 = null;
65  var $image8 = null;
66  var $image9 = null;
67  var $image10 = null;
68  var $image11 = null;
69  var $image12 = null;
70  var $image13 = null;
71  var $image14 = null;
72  var $image15 = null;
73  var $image16 = null;
74  var $image17 = null;
75  var $image18 = null;
76  var $image19 = null;
77  var $image20 = null;
78  var $image21 = null;
79  var $image22 = null;
80  var $image23 = null;
81  var $image24 = null;
82  var $image25 = null;
83  var $image26 = null;
84  var $image27 = null;
85  var $image28 = null;
86  var $image29 = null;
87  var $image30 = null;
88  var $zip = null;
89  var $youtube_code = null;
90  var $on_stock = null;
91  var $comments = null;
92  var $delai_stock = null;
93  var $etat_stock = null;
94  var $affiche_stock = null;
95  var $on_special = null;
96  var $on_rupture = null;
97  var $on_flash = null;
98  var $on_gift = null;
99  var $on_gift_points = null;
100  var $flash_start = null;
101  var $flash_end = null;
102  var $prix_flash = null;
103  var $extrait = null;
104  var $on_download = null;
105  var $on_check = null;
106  var $on_reseller = null;
107  var $id_marque = null;
108  var $default_color_id = null;
109  var $display_tab = null;
110  // categorie_id is the id of one of the categories the products belongs to.
111  var $categorie_id = null;
112  // categorie is the name of one of the categories of the product
113  var $categorie = null;
114  var $id_ecotaxe = null;
115  var $ecotaxe_ttc = null;
116  var $ecotaxe_ht = null;
117  // Configuration du produit
126  // Id du fournisseur
127  var $id_utilisateur = null;
128  var $vat_applicable = null;
129  var $extra_link = null;
130  var $unit_per_pallet = null;
131  var $conditionnement = null;
133  var $date_maj = null;
135  var $paiement = null;
146  function Product($id, $product_infos = null, $user_only_product_infos = false, $lang = null, $show_all_etat_if_admin = true, $vat_applicable = true, $show_all = false)
147  {
148  if (empty($lang)) {
149  $lang = $_SESSION['session_langue'];
150  }
151  if (is_object($product_infos)) {
152  $product_infos = get_object_vars($product_infos);
153  }
154  $this->lang = $lang;
155  $lang_items = array('name' => 'nom_'.(!empty($GLOBALS['site_parameters']['product_name_forced_lang'])?$GLOBALS['site_parameters']['product_name_forced_lang']:$lang), 'descriptif' => 'descriptif_' . $lang, 'description' => 'description_' . (!empty($GLOBALS['site_parameters']['product_description_forced_lang'])?$GLOBALS['site_parameters']['product_description_forced_lang']:$lang), 'meta_titre' => 'meta_titre_' . $lang, 'meta_desc' => 'meta_desc_' . $lang, 'meta_key' => 'meta_key_' . $lang);
156  if (empty($id)) {
157  $this->id = vn($product_infos['id']);
158  } else {
159  if(!is_numeric($id)) {
160  $sql = "SELECT p.id
161  FROM peel_produits p
162  WHERE p.technical_code = '" . real_escape_string($id) . "' AND " . get_filter_site_cond('produits', 'p') . "
163  LIMIT 1";
164  $query = query($sql);
165  if($result = fetch_assoc($query)) {
166  $this->id = $result['id'];
167  } else {
168  $this->id = false;
169  }
170  } else {
171  $this->id = $id;
172  }
173  }
174  if (!empty($product_infos)) {
175  // Faster than making an SQL request if we have data already available
176  foreach(array_keys(get_object_vars($this)) as $this_item) {
177  if (isset($product_infos[$this_item]) && !in_array($this_item, array('id', 'lang'))) {
178  $this->$this_item = $product_infos[$this_item];
179  } elseif (!empty($lang_items[$this_item]) && isset($product_infos[$lang_items[$this_item]])) {
180  $this->$this_item = $product_infos[$lang_items[$this_item]];
181  }
182  }
183  }
184  if (!$user_only_product_infos) {
185  if(empty($GLOBALS['site_parameters']['use_ads_as_products'])) {
186  $sql = "SELECT
187  p.id
188  , p.technical_code
189  , p.reference
190  , p.ean_code
191  , p.nom_".(!empty($GLOBALS['site_parameters']['product_name_forced_lang'])?$GLOBALS['site_parameters']['product_name_forced_lang']:$lang)." AS name
192  , p.descriptif_" . $lang . " AS descriptif
193  , p.description_" . (!empty($GLOBALS['site_parameters']['product_description_forced_lang'])?$GLOBALS['site_parameters']['product_description_forced_lang']:$lang) . " AS description
194  , p.meta_titre_" . $lang . " AS meta_titre
195  , p.meta_desc_" . $lang . " AS meta_desc
196  , p.meta_key_" . $lang . " AS meta_key
197  , p.on_estimate
198  , p.prix
199  , p.prix_achat
200  , p.prix_revendeur
201  , p.tva
202  , p.etat
203  , p.prix_promo
204  , p.promotion
205  , p.points
206  , p.default_image
207  , p.image1
208  , p.image2
209  , p.image3
210  , p.image4
211  , p.image5
212  , p.image6
213  , p.image7
214  , p.image8
215  , p.image9
216  , p.image10
217  , p.zip
218  , p.id_utilisateur
219  , p.youtube_code
220  , p.on_stock
221  , p.comments
222  , p.delai_stock
223  , p.etat_stock
224  , p.affiche_stock
225  , p.on_special
226  , p.on_gift
227  , p.on_gift_points
228  , p.on_rupture
229  , p.on_flash
230  , p.flash_start
231  , p.flash_end
232  , p.prix_flash
233  , p.extrait
234  , p.on_download
235  , p.on_check
236  , p.on_reseller
237  , p.id_marque
238  , p.default_color_id
239  , p.display_price_by_weight
240  , p.id_ecotaxe
241  , p.display_tab
242  , p.poids
243  , p.volume
244  , p.position
245  , p.extra_link
246  , p.paiement
247  , IF(c.id IS NOT NULL, c.id, 0) AS categorie_id
248  , IF(c.nom_" . $lang . " IS NOT NULL, c.nom_" . $lang . ", 0) AS categorie";
249  if (check_if_module_active('conditionnement')) {
250  $sql .= ", p.unit_per_pallet";
251  $sql .= ", p.conditionnement";
252  }
253  if (!empty($GLOBALS['site_parameters']['enable_categorie_sentence_displayed_on_product'])) {
254  $sql .= ", c.sentence_displayed_on_product_" . $lang . " AS categorie_sentence_displayed_on_product";
255  }
256  if (!empty($GLOBALS['site_parameters']['products_table_additionnal_fields'])) {
257  $sql .= ','.implode(',', array_keys($GLOBALS['site_parameters']['products_table_additionnal_fields'])).'';
258  }
259  // Les chèques cadeaux n'ont pas de catégorie associée, donc il faut modifier la requête SQL de cette classe en conséquence pour ne pas faire de jointure INNER sur les catégories (même effet que la variable global allow_products_without_category)
260  $sql .= " FROM peel_produits p
261  " . (!empty($GLOBALS['site_parameters']['allow_products_without_category']) || $this->on_check == 1 ? 'LEFT' : 'INNER') . " JOIN peel_produits_categories pc ON pc.produit_id=p.id
262  " . (!empty($GLOBALS['site_parameters']['allow_products_without_category']) || $this->on_check == 1 ? 'LEFT' : 'INNER') . " JOIN peel_categories c ON c.id = pc.categorie_id AND " . get_filter_site_cond('categories', 'c') . "
263  WHERE p.id = '" . intval($this->id) . "' AND " . get_filter_site_cond('produits', 'p') . " " . (empty($show_all)?($show_all_etat_if_admin && a_priv("admin_products", false)?'AND p.etat IN ("1","0")':'AND p.etat = "1"') :'') . "
264  LIMIT 1";
265  // Le limit 1 est nécessaire car le produit peut être associé à plusieurs catégories => on ne récupère que la première catégorie trouvée
266  $query = query($sql);
268  } else {
269  $ad_object = new Annonce($this->id);
270  $product_infos = $ad_object->get_product_infos_object();
271  unset($ad_object);
272  }
273  if (!empty($product_infos)) {
274  foreach($product_infos as $this_item => $this_value) {
275  if ($this->$this_item === null) {
276  $this->$this_item = $this_value;
277  }
278  }
279  } else {
280  // If the product does not exist, its id is put to 0 even if $id is not 0
281  $this->id = 0;
282  }
283  }
284  // Initialisation de variables non présentes dans peel_produits
285  // L'écotaxe est gérée par l'appel au hook "product_init_post" si le module est présent
286  $this->ecotaxe_ht = 0;
287  $this->ecotaxe_ttc = 0;
288  if (!empty($GLOBALS['site_parameters']['specific_categorie_used_for_product_array'])) {
289  // Cette variable de configuration permet de spécifier une catégorie différente de l'association en back office. Cela permet par exemple de choisir la catégorie avec laquelle l'url du produit sera générée, dans le cas où plusieurs catégories sont associées au produit.
290  // Il est possible de créer une règle qui s'applique à tous les produits en définissant le paramètre comme ceci : '*'=>'id_de_categorie'
291  // On peut aussi définir une règle différente produit par produit : 'id_de_produit1'=>'id_de_categorie1','id_de_produit2'=>'id_de_categorie2','id_de_produit3'=>'id_de_categorie3'
292  // faire un mélange des deux, la priorité est faite sur la configuration spécifique à un produit : '*'=>'id_de_categorie','id_de_produit1'=>'id_de_categorie1', 'id_de_produit2'=>'id_de_categorie2'
293  // Cette configuration est incompatible avec allow_multiplie_product_url_with_categorie === true.
294  if (!empty($GLOBALS['site_parameters']['specific_categorie_used_for_product_array'][$this->id])) {
295  // une règle est défini pour ce produit, il faut spécifier la catégorie choisie
296  $this->categorie_id = $GLOBALS['site_parameters']['specific_categorie_used_for_product_array'][$this->id];
297  $this->categorie = get_category_name($GLOBALS['site_parameters']['specific_categorie_used_for_product_array'][$this->id]);
298  } elseif(!empty($GLOBALS['site_parameters']['specific_categorie_used_for_product_array']['*'])) {
299  // une règle général s'applique
300  $this->categorie_id = $GLOBALS['site_parameters']['specific_categorie_used_for_product_array']['*'];
301  $this->categorie = get_category_name($GLOBALS['site_parameters']['specific_categorie_used_for_product_array']['*']);
302  }
303  }
304  $this->name = String::html_entity_decode_if_needed($this->name);
305  $this->descriptif = String::html_entity_decode_if_needed($this->descriptif);
306  $extra_description = '';
307  if(function_exists('get_product_description')) {
308  $extra_description .= get_product_description($this);
309  }
310  $possible_attributes_with_single_options = $this->get_possible_attributs('infos', false, get_current_user_promotion_percentage(), display_prices_with_taxes_active(), check_if_module_active('reseller') && is_reseller(), true, true, false, true);
311  foreach($possible_attributes_with_single_options as $this_nom_attribut_id => $this_options_array) {
312  foreach($this_options_array as $this_attribut_id => $this_options_infos) {
313  if($this_attribut_id && empty($this_options_infos['texte_libre']) && empty($this_options_infos['upload'])) {
314  // Ceci n'est pas un attribut texte ou upload
315  if (empty($GLOBALS['site_parameters']['disable_display_attributes_with_single_options_on_product_description'])) {
316  $extra_description .= $this_options_infos['nom'] . $GLOBALS['STR_BEFORE_TWO_POINTS'] . ': ' . $this_options_infos['descriptif'] . '<br />';
317  }
318  $this->attributes_with_single_options_array[$this_options_infos['technical_code']] = array('nom'=>$this_options_infos['nom'],'descriptif'=>$this_options_infos['descriptif']);
319  }
320  }
321  }
322  if (empty($GLOBALS['site_parameters']['display_extra_product_description_mode']) || $GLOBALS['site_parameters']['display_extra_product_description_mode']=='after') {
323  $this->description = String::html_entity_decode_if_needed($this->description) . $extra_description;
324  } elseif ($GLOBALS['site_parameters']['display_extra_product_description_mode']=='before') {
325  $this->description = $extra_description . String::html_entity_decode_if_needed($this->description);
326  }
327  correct_output($this->descriptif, true, 'html', $lang);
328  correct_output($this->description, true, 'html', $lang);
329  // On ajoute à la description les attributs à options uniques, puisque ces attributs ne seront pas sélectionnables par ailleurs (car rien à sélectionner)
330  if(empty($this->descriptif) && !empty($GLOBALS['site_parameters']['product_short_description_generate_if_empty'])) {
331  $this->descriptif = String::str_shorten(String::strip_tags($this->description), 500);
332  }
333  $this->categorie = String::html_entity_decode_if_needed(vb($this->categorie));
334  $this->poids = floatval($this->poids);
335  $this->volume = floatval($this->volume);
336  $this->prix_ht = $this->prix / (1 + $this->tva / 100);
337  // On exécute des fonctions de modules qui permettent de compléter le prix, de calculer certaines propriétés de l'objet, ...
338  call_module_hook('product_init_post', array('this' => $this, 'user_only_product_infos' => $user_only_product_infos, 'product_infos' => $product_infos));
339  $this->vat_applicable = $vat_applicable;
340  if (empty($vat_applicable)) {
341  $this->ecotaxe_ttc = $this->ecotaxe_ht;
342  $this->prix = $this->prix_ht;
343  }else {
344  $this->prix = $this->prix_ht * (1 + $this->tva / 100);
345  }
346  if(!empty($GLOBALS['site_parameters']['price_hide_if_not_loggued']) && (!est_identifie() || (!a_priv('util') && !a_priv('admin*') && !a_priv('reve'))) && !check_if_module_active('devis')) {
347  $this->on_estimate = 1;
348  }
349  }
350 
362  function set_configuration($color_id = null, $size_id = null, $attributs_list = null, $reseller_mode = false, $format_attribut_description_for_database = false)
363  {
364  // Color has no impact on price
365  $this->configuration_color_id = $color_id;
366  if ($this->configuration_size_id !== $size_id) {
367  // Size can have an impact on price
368  $this->configuration_size_id = $size_id;
369  $size_array = $this->get_size('infos', 0, false, $reseller_mode, false, false);
370  $this->configuration_size_name = vb($size_array['name']);
371  $this->configuration_size_price_ht = vn($size_array['row_original_price']);
372  $this->configuration_overweight = vn($size_array['poids']);
373  }
374  call_module_hook('product_set_configuration', array('this' => $this, 'attributs_list' => $attributs_list, 'reseller_mode' => $reseller_mode));
375  }
376 
384  function get_product_url($add_get_suffixe = false, $html_encode = false)
385  {
386  if(empty($GLOBALS['site_parameters']['use_ads_as_products'])) {
387  if ($this->categorie_id === null || $this->categorie === null) {
388  $query = query("SELECT p.nom_".(!empty($GLOBALS['site_parameters']['product_name_forced_lang'])?$GLOBALS['site_parameters']['product_name_forced_lang']:$this->lang)." AS name, pc.categorie_id, r.nom_" . $this->lang . " AS categorie
389  FROM peel_produits p
390  " . (!empty($GLOBALS['site_parameters']['allow_products_without_category']) || $this->on_check == 1 ? 'LEFT' : 'INNER') . " JOIN peel_produits_categories pc ON p.id = pc.produit_id
391  " . (!empty($GLOBALS['site_parameters']['allow_products_without_category']) || $this->on_check == 1 ? 'LEFT' : 'INNER') . " JOIN peel_categories r ON r.id = pc.categorie_id AND " . get_filter_site_cond('categories', 'r') . "
392  WHERE p.id ='" . intval($this->id) . "' AND " . get_filter_site_cond('produits', 'p') . "
393  LIMIT 1");
394  if ($prod = fetch_assoc($query)) {
395  $this->categorie_id = $prod['categorie_id'];
396  $this->categorie = $prod['categorie'];
397  if(empty($this->name)) {
398  $this->name = $prod['name'];
399  }
400  }
401  }
402  if(!empty($GLOBALS['site_parameters']['product_check_specific_link_column'])) {
403  $column = $GLOBALS['site_parameters']['product_check_specific_link_column'];
404  $GLOBALS['product_current_specific_link'] = $this->$column;
405  }
406  if (!empty($this->categorie_id)) {
407  return get_product_url($this->id, $this->name, $this->categorie_id, $this->categorie, $add_get_suffixe, $html_encode);
408  } else {
409  return get_product_url($this->id, $this->name, 0, null, $add_get_suffixe, $html_encode);
410  }
411  } else {
412  $ad_object = new Annonce($this->id);
413  $url = $ad_object->get_annonce_url();
414  unset($ad_object);
415  return $url;
416  }
417  }
418 
424  function get_color()
425  {
426  $colors_array = $this->get_possible_colors();
427  if (!empty($colors_array[$this->configuration_color_id])) {
428  return $colors_array[$this->configuration_color_id];
429  } else {
430  return null;
431  }
432  }
433 
440  {
441  static $possible_colors;
442  $cache_id = $this->id . '-' . $this->lang;
443  // Utilisation de array_keys car isset($possible_colors[$cache_id]) renvoie faux si c'est défini mais vaut null.
444  if(empty($possible_colors) || !in_array($cache_id, array_keys($possible_colors))){
445  $possible_colors[$cache_id] = array();
446  $query = query('SELECT pc.couleur_id, c.nom_' . $this->lang . '
447  FROM peel_produits_couleurs pc
448  INNER JOIN peel_couleurs c ON c.id = pc.couleur_id AND ' . get_filter_site_cond('couleurs', 'c') . '
449  WHERE pc.produit_id = "' . intval($this->id) . '"
450  ORDER BY c.position ASC, c.nom_' . $this->lang . ' ASC');
451  while ($result = fetch_assoc($query)) {
452  $possible_colors[$cache_id][$result['couleur_id']] = $result['nom_' . $this->lang];
453  }
454  }
455  return $possible_colors[$cache_id];
456  }
457 
469  function get_size($return_mode = 'name', $user_promotion_percentage = 0, $with_taxes = true, $reseller_mode = false, $format = false, $add_tax_type_text = false)
470  {
471  $sizes_array = $this->get_possible_sizes($return_mode, $user_promotion_percentage, $with_taxes, $reseller_mode, $format, $add_tax_type_text);
472  if (!empty($sizes_array[$this->configuration_size_id])) {
473  return $sizes_array[$this->configuration_size_id];
474  } else {
475  return null;
476  }
477  }
478 
490  function get_possible_sizes($return_mode = 'name', $user_promotion_percentage = 0, $with_taxes = true, $reseller_mode = false, $format = false, $add_tax_type_text = false)
491  {
492  static $possible_sizes;
493  $sizes_array = array();
494  // Utilisation de array_keys car isset($possible_sizes[$this->id . '-' . $this->lang]) renvoie faux si c'est défini mais vaut null.
495  if(empty($possible_sizes) || !in_array($this->id . '-' . $this->lang, array_keys($possible_sizes))){
496  $possible_sizes[$this->id . '-' . $this->lang] = array();
497  $query = query('SELECT t.*, pt.taille_id
498  FROM peel_produits_tailles pt
499  INNER JOIN peel_tailles t ON t.id=pt.taille_id AND ' . get_filter_site_cond('tailles', 't') . '
500  WHERE pt.produit_id="' . intval($this->id) . '"
501  ORDER BY t.position ASC, t.prix ASC, t.nom_' . $this->lang . ' ASC');
502  while ($result = fetch_assoc($query)) {
503  $possible_sizes[$this->id . '-' . $this->lang][] = $result;
504  }
505  }
506  if (!empty($possible_sizes) && !empty($possible_sizes[$this->id . '-' . $this->lang])) {
507  foreach($possible_sizes[$this->id . '-' . $this->lang] as $result) {
508  if ($return_mode == 'name') {
509  $sizes_array[$result['taille_id']] = $result['nom_' . $this->lang];
510  } elseif ($return_mode == 'export') {
511  $sizes_array[$result['taille_id']] = $result['nom_' . $this->lang];
512  if($result['prix']!=0 || $result['prix_revendeur']!=0) {
513  // Ajout d'informations sur le prix si adapté
514  $sizes_array[$result['taille_id']] .= '§'.$taille['prix'].'§'.$taille['prix_revendeur'];
515  }
516  } else {
517  if ($reseller_mode && a_priv('reve') && $result["prix_revendeur"] != 0) {
518  $original_price = $result["prix_revendeur"] / (1 + $this->tva / 100);
519  } else {
520  $original_price = $result["prix"] / (1 + $this->tva / 100);
521  }
522  $final_price = $original_price * (1 - $this->get_all_promotions_percentage($reseller_mode, $user_promotion_percentage) / 100);
523  $result['name'] = $result['nom_' . $this->lang];
524  $result['row_original_price'] = $this->format_prices($original_price, $with_taxes, false, false, false);
525  $result['row_final_price'] = $this->format_prices($final_price, $with_taxes, false, false, false);
526  $result['final_price_formatted'] = $this->format_prices($final_price, $with_taxes, false, $format, $add_tax_type_text);
527  $sizes_array[$result['taille_id']] = $result;
528  }
529  }
530  }
531  return $sizes_array;
532  }
533 
549  function get_possible_attributs($return_mode = 'name', $get_configuration_results_only = false, $user_promotion_percentage = 0, $with_taxes = true, $reseller_mode = false, $format = false, $add_tax_type_text = false, $get_attributes_with_multiple_options_only = true, $get_attributes_with_single_options_only = false, $filter_technical_code = null)
550  {
551  static $attributs_array;
552  if (!check_if_module_active('attributs')) {
553  return array();
554  }
555  $cache_id = md5(serialize(array($return_mode, $get_configuration_results_only, $user_promotion_percentage, $with_taxes, $reseller_mode, $format, $add_tax_type_text, $get_attributes_with_multiple_options_only, $get_attributes_with_single_options_only, $filter_technical_code, $this->id, $this->configuration_attributs_list)));
556  // Utilisation de arra_keys car isset($attributs_array[$cache_id]) renvoie faux si c'est défini mais vaut null.
557  if(empty($attributs_array) || !in_array($cache_id, array_keys($attributs_array))){
558  if(!empty($this->id)) {
559  $attributs_array[$cache_id] = get_possible_attributs($this->id, ($return_mode=='infos'?'rough':$return_mode), $get_attributes_with_multiple_options_only, $get_attributes_with_single_options_only, ($get_configuration_results_only?$this->configuration_attributs_list:null));
560  } else {
561  $attributs_array[$cache_id] = array();
562  }
563  if (!empty($attributs_array[$cache_id]) && $return_mode == 'infos') {
564  foreach ($attributs_array[$cache_id] as $this_nom_attribut_id => $this_attribut_values_array) {
565  foreach ($this_attribut_values_array as $this_attribut_id => $result) {
566  if(!empty($filter_technical_code) && $result['technical_code'] == $filter_technical_code) {
567  continue;
568  }
569  if ($reseller_mode && a_priv('reve') && $result["prix_revendeur"] != 0) {
570  $original_price = $result["prix_revendeur"] / (1 + $this->tva / 100);
571  } else {
572  $original_price = $result["prix"] / (1 + $this->tva / 100);
573  }
574  $final_price = $original_price * (1 - $this->get_all_promotions_percentage($reseller_mode, $user_promotion_percentage) / 100);
575  $result['name'] = $result['nom'];
576  $result['row_original_price'] = $this->format_prices($original_price, $with_taxes, false, false, false);
577  $result['row_final_price'] = $this->format_prices($final_price, $with_taxes, false, false, false);
578  $result['final_price_formatted'] = $this->format_prices($final_price, $with_taxes, false, $format, $add_tax_type_text);
579  $attributs_array[$cache_id][$this_nom_attribut_id][$this_attribut_id] = $result;
580  }
581  }
582  }
583  }
584  return $attributs_array[$cache_id];
585  }
586 
593  {
594  $references_array = array();
595  $sql = 'SELECT ppr.reference_id
596  FROM peel_produits_references ppr
597  WHERE ppr.produit_id="' . intval($this->id) . '"';
598  $query = query($sql);
599  while ($result = fetch_assoc($query)) {
600  $references_array[] = $result['reference_id'];
601  }
602  return $references_array;
603  }
604 
611  function get_product_brands($return_array = true)
612  {
613  static $brands_array;
614  $cache_id = $this->id . '_' . $this->lang;
615  if(empty($brands_array) || !in_array($cache_id, array_keys($brands_array))){
616  $brands_array[$cache_id] = array();
617  $query = query("SELECT pm.nom_" . $this->lang . "
618  FROM peel_marques pm
619  WHERE pm.id='" . intval($this->id_marque) . "' AND " . get_filter_site_cond('marques', 'pm'));
620  while ($result = fetch_assoc($query)) {
621  $brands_array[$cache_id][$this->id_marque] = $result['nom_' . $this->lang];
622  }
623  if(empty($brands_array[$cache_id]) && !empty($this->marque)) {
624  $brands_array[$cache_id][] = $this->marque;
625  }
626  }
627  if($return_array) {
628  return $brands_array[$cache_id];
629  } else {
630  return implode(', ', $brands_array[$cache_id]);
631  }
632  }
633 
640  {
641  return call_module_hook('product_get_options', array('id_or_technical_code' => $this->id, 'lang' => $this->lang, 'return_mode' => 'value'), 'array');
642  }
643 
652  function get_product_main_picture($display_pdf = false, $force_id_couleur = null)
653  {
654  $product_images = $this->get_product_pictures($display_pdf, $force_id_couleur, true);
655  if (!empty($product_images)) {
656  return $product_images[0];
657  } else {
658  return false;
659  }
660  }
670  function get_product_pictures($display_pdf = false, $force_id_couleur = null, $only_return_first_picture = false)
671  {
672  static $product_images;
673  $cache_id = md5(serialize(array($this->id, $this->configuration_color_id, $this->default_color_id, $display_pdf, $force_id_couleur, $only_return_first_picture)));
674  if(empty($product_images) || !in_array($cache_id, array_keys($product_images))){
675  if(empty($GLOBALS['site_parameters']['use_ads_as_products'])) {
676  if (!empty($force_id_couleur)) {
677  $this_color = $force_id_couleur;
678  } elseif (!empty($this->configuration_color_id)) {
679  $this_color = $this->configuration_color_id;
680  } else {
681  // Si il n'y a pas de couleur choisie, on sélectionne la couleur par défaut choisie par l'admin
682  $this_color = $this->default_color_id;
683  }
684  if(!empty($this_color) && empty($GLOBALS['site_parameters']['disable_product_colors'])) {
685  $sql_condition = ' AND couleur_id="' . intval($this_color) . '"';
686  $sql = 'SELECT *
687  FROM peel_produits_couleurs
688  WHERE produit_id="' . intval($this->id) . '" ' . $sql_condition . '
689  LIMIT 1';
690  $q = query($sql);
691  if ($result = fetch_assoc($q)) {
692  // On commence par l'image par défaut pour que ce soit le premier élément du tableau
693  if (!empty($result['default_image']) && is_numeric($result['default_image']) && !empty($result['image' . $result['default_image']]) && ($display_pdf || pathinfo($result['image' . $result['default_image']], PATHINFO_EXTENSION) != 'pdf')) {
694  $product_images[$cache_id][] = $result['image' . $result['default_image']];
695  }
696  for($i = 1;$i <= 5;$i++) {
697  if (!empty($result['image' . $i]) && $i != $result['default_image'] && (!$only_return_first_picture || empty($product_images[$cache_id])) && ($display_pdf || pathinfo($result['image' . $i], PATHINFO_EXTENSION) != 'pdf')) {
698  $product_images[$cache_id][] = $result['image' . $i];
699  }
700  }
701  }
702  }
703  if($this->default_image === null) {
704  // Produit chargé à partir de données transmises de l'extérieur => nécessite de compléter les informations
705  $sql = 'SELECT default_image, image1, image2, image3, image4, image5, image6, image7, image8, image9, image10
706  FROM peel_produits
707  WHERE id=' . intval($this->id). " AND " . get_filter_site_cond('produits') . "";
708  $q = query($sql);
709  if ($result = fetch_assoc($q)) {
710  foreach($result as $this_item => $this_value) {
711  $this->$this_item = $this_value;
712  }
713  }
714  }
715  // On commence par l'image par défaut pour que ce soit le premier élément du tableau
716  $this_image_item = 'image' . $this->default_image;
717  if (!empty($this->default_image) && is_numeric($this->default_image) && !empty($this->$this_image_item) && (!$only_return_first_picture || empty($product_images[$cache_id])) && ($display_pdf || pathinfo($this->$this_image_item, PATHINFO_EXTENSION) != 'pdf')) {
718  $product_images[$cache_id][] = $this->$this_image_item;
719  }
720  for($i = 1;$i <= 10;$i++) {
721  $this_image_item = 'image' . $i;
722  if (!empty($this->$this_image_item) && $i != $this->default_image && (!$only_return_first_picture || empty($product_images[$cache_id])) && ($display_pdf || pathinfo($this->$this_image_item, PATHINFO_EXTENSION) != 'pdf')) {
723  $product_images[$cache_id][] = $this->$this_image_item;
724  }
725  }
726  if (!empty($GLOBALS['site_parameters']['products_table_additionnal_fields'])) {
727  foreach($GLOBALS['site_parameters']['products_table_additionnal_fields'] as $this_key => $this_value) {
728  if (strpos($this_key, 'image') === 0) {
729  // Prise en compte des images complémentaires
730  $i++;
731  $this_image_item = $this_key;
732  if (!empty($this->$this_image_item) && $i != $this->default_image && (!$only_return_first_picture || empty($product_images[$cache_id])) && ($display_pdf || pathinfo($this->$this_image_item, PATHINFO_EXTENSION) != 'pdf')) {
733  $product_images[$cache_id][] = $this->$this_image_item;
734  }
735  }
736  }
737  }
738  } else {
739  $ad_object = new Annonce($this->id);
740  $product_images[$cache_id][] = $ad_object->get_annonce_picture();
741  unset($ad_object);
742  }
743  if (empty($product_images[$cache_id])) {
744  $product_images[$cache_id] = false;
745  }
746  }
747  return $product_images[$cache_id];
748  }
749 
760  function get_supplier_price($with_taxes = true, $format = false, $add_tax_type_text = false, $add_ecotax = true, $quantity = 1)
761  {
762  if (isset($this->prix_achat)) {
763  $prix_achat_ht = $this->prix_achat / (1 + $this->tva / 100);
764  return $this->format_prices($prix_achat_ht, $with_taxes, (!empty($add_ecotax)?$quantity:false), $format, $add_tax_type_text);
765  } else {
766  return null;
767  }
768  }
769 
782  function get_original_price($with_taxes = true, $reseller_mode = false, $format = false, $add_tax_type_text = false, $add_ecotax = true, $get_price_for_this_configuration = true, $quantity = 1, $prices_whole_site_rebate_percentage = true)
783  {
784  if ($reseller_mode && a_priv('reve') && $this->prix_revendeur != 0) {
785  $price_ht = $this->prix_revendeur / (1 + $this->tva / 100);
786  } else {
787  $price_ht = $this->prix_ht;
788  }
789  if ($get_price_for_this_configuration) {
791  if (check_if_module_active('attributs')) {
793  }
794  }
795  if(!empty($GLOBALS['site_parameters']['prices_whole_site_rebate_percentage'])) {
796  $price_ht = $price_ht * (1 - $GLOBALS['site_parameters']['prices_whole_site_rebate_percentage']/100);
797  }
798  $price_ht = $price_ht * $quantity;
799  return $this->format_prices($price_ht, $with_taxes, (!empty($add_ecotax)?$quantity:false), $format, $add_tax_type_text);
800  }
801 
817  function get_final_price($user_promotion_percentage = 0, $with_taxes = true, $reseller_mode = false, $format = false, $add_tax_type_text = false, $quantity = 1, $add_ecotax = true, $get_price_for_this_configuration = true, $add_rdfa_properties = false, $quantity_all_products_in_category = null)
818  {
819  if($quantity_all_products_in_category === null) {
820  $quantity_all_products_in_category = $quantity;
821  }
822  // Choix entre prix revendeur et prix public
823  if ($reseller_mode) {
824  // The reseller price is never affected by flash prices
825  $price_ht = $this->get_original_price(false, true, false, false, false, false, $quantity, false) / $quantity;
826  } elseif ($this->is_price_flash($reseller_mode)) {
827  $price_ht = $this->prix_flash / (1 + $this->tva / 100);
828  } else {
829  $price_ht = $this->get_original_price(false, false, false, false, false, false, $quantity, false) / $quantity;
830  }
831  // Récupération du prix modifié par d'éventuels modules (par exemple module "lot" pour donner le prix réduit pour une quantité donnée)
832  $call_module_hook = call_module_hook('product_get_final_price', array('quantity' => $quantity, 'reseller_mode' => $reseller_mode, 'price_ht' => $price_ht, 'this' => $this), 'min');
833  if ($call_module_hook !== null) {
834  // un prix a été défini par le hook. Si la valeur est null, c'est qu'aucun hook est appelé par la fonction call_module_hook
835  $price_ht = min($price_ht, $call_module_hook);
836  }
837  if ($get_price_for_this_configuration) {
839  if (check_if_module_active('attributs')) {
841  }
842  }
843  if (!$this->is_price_flash($reseller_mode)) {
844  if (!$reseller_mode) {
845  // Pour les revendeurs, on n'applique pas d'autre réduction que le pourcentage de réduction explicite pour cet utilisateur
846  $promotion_devises = 0;
847  if (check_if_module_active('category_promotion')) {
848  $cat = get_category_promotion_by_product($this->id, $quantity_all_products_in_category);
849  if (!empty($cat) && $cat['promotion_devises'] > 0) {
850  // Réduction par marque en valeur et non pas en pourcentage
851  $promotion_devises = max($promotion_devises, $cat['promotion_devises']);
852  }
853  }
854  if (!empty($this->id_marque) && check_if_module_active('marques_promotion')) {
855  $marque = get_marque_promotion($this->id_marque);
856  if (!empty($marque) && $marque['promotion_devises'] > 0) {
857  // Réduction par marque en valeur et non pas en pourcentage
858  // Si on veut cumuler les réductions par produit, par marque et par catégorie, changer la ligne ci-dessous
859  $promotion_devises = max($promotion_devises, $marque['promotion_devises']);
860  }
861  }
862  $get_promotion_by_user_offer_object = $this->get_promotion_by_user_offer($quantity);
863  if(!empty($get_promotion_by_user_offer_object) && $get_promotion_by_user_offer_object->prix>0) {
864  $price_ht = min($price_ht, $get_promotion_by_user_offer_object->prix / (1 + $this->tva / 100));
865  }
866  // Application des réductions automatique en fonction de mots clés dans la description ou la référence du produit
867  $promotion_by_product_filter_object = $this->get_promotion_by_product_filter();
868  if(!empty($promotion_by_product_filter_object)) {
869  $promotion_devises = max($promotion_devises, $promotion_by_product_filter_object->remise_valeur);
870  }
871  $price_ht = max($price_ht - $promotion_devises / (1 + $this->tva / 100), 0);
872  }
873  // Application des réductions en pourcentages
874  $price_ht = $price_ht * (1 - $this->get_all_promotions_percentage($reseller_mode, $user_promotion_percentage, false, $quantity, $quantity_all_products_in_category) / 100) ;
875  } else {
876  // Si c'est un prix flash, on n'applique pas les réductions en pourcentage ni en valeur
877  // (mais sur les options, les pourcentages seront quand même appliqués - pas gérés ici)
878  $price_ht = $price_ht * (1 - $user_promotion_percentage / 100) ;
879  }
880  if(!empty($GLOBALS['site_parameters']['all_prices_rebate_percentage'])) {
881  $price_ht = $price_ht * (1 - $GLOBALS['site_parameters']['all_prices_rebate_percentage']/100);
882  }
883  $price_ht = $price_ht * $quantity;
884  return $this->format_prices($price_ht, $with_taxes, (!empty($add_ecotax)?$quantity:false), $format, $add_tax_type_text, $add_rdfa_properties);
885  }
886 
893  function is_price_flash($reseller_mode = false)
894  {
895  return (!$reseller_mode && $this->prix_flash > 0 && $this->flash_start < date('Y-m-d H:i:s', time()) && $this->flash_end > date('Y-m-d H:i:s', time()) && is_flash_active_on_site());
896  }
897 
906  function is_code_promo_applicable($id_categorie, $product_filter, &$found_cat, $cat_not_apply_code_promo = null)
907  {
908  $apply_code_on_this_product = true;
909  if (!empty($id_categorie) || !empty($cat_not_apply_code_promo)) {
910  $q_get_product_cat = query('SELECT categorie_id
911  FROM peel_produits_categories ppc
912  WHERE ppc.produit_id = "' . intval($this->id) . '"' .
913  (!empty($id_categorie) ? 'AND ppc.categorie_id IN ("' . implode('","', nohtml_real_escape_string(get_category_tree_and_itself($id_categorie, 'sons'))) . '")' : '' ) .
914  (!empty($cat_not_apply_code_promo) ? 'AND ppc.categorie_id NOT IN (' . str_replace(' ', '', implode(',', nohtml_real_escape_string(get_category_tree_and_itself($cat_not_apply_code_promo, 'sons')))) . ')' : '' ) .
915  'LIMIT 1');
916  if ($r_get_product_cat = fetch_assoc($q_get_product_cat)) {
917  $found_cat = true;
918  } else {
919  $found_cat = false;
920  }
921  if(!$found_cat) {
922  $apply_code_on_this_product = false;
923  }
924  }
925  if (!empty($product_filter)) {
926  $found_product = false;
927  foreach(array('description', 'reference') as $this_item) {
928  if(String::strpos(String::strtolower($this->$this_item), String::strtolower($product_filter)) !== false) {
929  $found_product = true;
930  break;
931  }
932  }
933  if(!$found_product) {
934  $apply_code_on_this_product = false;
935  }
936  }
937  return $apply_code_on_this_product;
938  }
939 
947  function get_promotion_by_product_filter($reseller_mode = false)
948  {
949  static $promotion_by_product_id_array;
950  if(empty($promotion_by_product_id_array) || !in_array($this->id, array_keys($promotion_by_product_id_array))){
951  $sql = 'SELECT *
952  FROM peel_codes_promos cp
953  WHERE ' . get_filter_site_cond('codes_promos', 'cp') . ' AND nom="" AND cp.etat = "1" AND ("' . date('Y-m-d', time()) . '" BETWEEN cp.date_debut AND cp.date_fin) AND ("' . nohtml_real_escape_string(trim(String::substr($this->description,0,1024))) . '" LIKE CONCAT("%", product_filter, "%") OR "' . nohtml_real_escape_string(trim($this->reference)) . '" LIKE CONCAT("%", product_filter, "%"))
954  ORDER BY remise_percent DESC
955  LIMIT 1';
956  $query = query($sql);
957  $promotion_by_product_id_array[$this->id] = fetch_object($query);
958  }
959  return $promotion_by_product_id_array[$this->id];
960  }
961 
968  function get_promotion_by_user_offer($quantity = 1)
969  {
970  static $promotion_by_user_offer_array;
971  if(!empty($GLOBALS['site_parameters']['user_offers_table_enable']) && !empty($_SESSION['session_utilisateur']['id_utilisateur'])) {
972  $quantity_total = 0;
973  $value_total = 0;
974  foreach ($_SESSION['session_caddie']->articles as $numero_ligne => $product_id) {
975  $product_object = new Product($product_id, null, false, null, true, $_SESSION['session_caddie']->apply_vat);
976  if(empty($quantity_by_brand['brand_'.$product_object->get_product_brands(false)]) || $product_object->get_product_brands(false) == '') {
977  $quantity_by_brand['brand_'.$product_object->get_product_brands(false)] = 0;
978  $total_by_brand['brand_'.$product_object->get_product_brands(false)] = 0;
979  }
980  $quantity_by_brand['brand_'.$product_object->get_product_brands(false)] += $_SESSION['session_caddie']->quantite[$numero_ligne];
981  $total_by_brand['brand_'.$product_object->get_product_brands(false)] += floatval($_SESSION['session_caddie']->quantite[$numero_ligne]*$product_object->prix_ht);
982  $quantity_total += $_SESSION['session_caddie']->quantite[$numero_ligne];
983  $value_total += floatval($_SESSION['session_caddie']->quantite[$numero_ligne]*$product_object->prix_ht);
984  unset($product_object);
985  }
986  $sql = "SELECT o.*
987  FROM peel_offres o
988  LEFT JOIN peel_utilisateurs_offres uo ON uo.id_utilisateur='" . intval(vn($_SESSION['session_utilisateur']['id_utilisateur'])) . "' AND o.id_offre=uo.id_offre
989  WHERE (o.id_offre=0 OR uo.id_offre IS NOT NULL) AND o.date_limite>='" . date('Y-m-d', time()) . "' AND (" . (!empty($this->reference)?"(o.ref='".real_escape_string($this->reference)."' AND o.qnte<='".intval($quantity)."' AND o.seuil<='".floatval(max($quantity*$this->prix_ht,vn($value_total)))."') OR ":"") . "(o.ref='' AND o.fournisseur IN ('".implode("','", real_escape_string($this->get_product_brands(true)))."') AND o.qnte<='".intval(max(vn($quantity_by_brand['brand_'.$this->get_product_brands(false)]), $quantity))."' AND o.seuil<='".floatval(max(vn($total_by_brand['brand_'.$this->get_product_brands(false)]), $quantity*$this->prix_ht, vn($value_total)))."') OR (o.ref='' AND o.fournisseur='' AND o.qnte<='".intval(max(vn($quantity_total), $quantity))."' AND o.seuil<='".floatval(max(vn($value_total), $quantity*$this->prix_ht))."'))
990  ORDER BY " . (floatval($this->prix_ht)>0 ? "IF(o.prix>0 AND o.remise_percent>0, LEAST(o.prix, o.remise_percent*'".floatval($this->prix_ht)."'), IF(o.remise_percent>0, o.remise_percent*'".floatval($this->prix_ht)."', o.prix))" : "o.prix") . " DESC, o.remise_percent DESC
991  LIMIT 1";
992  $cache_id = md5($sql);
993  if(empty($promotion_by_user_offer_array) || !in_array($cache_id, array_keys($promotion_by_user_offer_array))){
994  $query = query($sql);
995  $promotion_by_user_offer_array[$cache_id] = fetch_object($query);
996  }
997  return $promotion_by_user_offer_array[$cache_id];
998  } else {
999  return null;
1000  }
1001  }
1002 
1013  function get_all_promotions_percentage($reseller_mode = false, $user_promotion_percentage = 0, $format = false, $quantity = 1, $quantity_all_products_in_category = null)
1014  {
1015  if($quantity_all_products_in_category === null) {
1016  $quantity_all_products_in_category = $quantity;
1017  }
1018  $user_promotion_percentage = min($user_promotion_percentage, 100);
1019  if (!$reseller_mode) {
1020  // Pour les revendeurs, on n'applique pas d'autre réduction que le pourcentage de réduction explicite pour cet utilisateur
1021  if (check_if_module_active('category_promotion')) {
1022  $cat = get_category_promotion_by_product($this->id, $quantity_all_products_in_category);
1023  }
1024  if (empty($cat)) {
1025  $cat = array('nom' => '', 'promotion_devises' => 0, 'promotion_percent' => 0);
1026  }
1027  if (!empty($GLOBALS['site_parameters']['global_remise_percent'])) {
1028  if(is_array($GLOBALS['site_parameters']['global_remise_percent'])) {
1029  // Si c'est un tableau, on souhaite définir un seuil d'application du montant. On trie le tableau du plus petit seuil au seuil le plus important pour faire une boucle.
1030  ksort($GLOBALS['site_parameters']['global_remise_percent']);
1031  $total = 0;
1032  foreach($_SESSION['session_caddie']->articles as $numero_ligne => $id) {
1033  $product_object = new Product($id);
1034  // impossible d'utiliser directement $_SESSION['session_caddie']->total, puisqu'en la variable est en cours de calcul quand on la test
1035  if (empty($GLOBALS['site_parameters']['product_promotion_plurality_disable']) || (!empty($GLOBALS['site_parameters']['product_promotion_plurality_disable']) && $product_object->promotion==0)) {
1036  // On utilise que les produits sur lesquelles aucune réduction ne s'applique pour calculer le seuil.
1037  $total += $_SESSION['session_caddie']->prix_cat[$numero_ligne] * $_SESSION['session_caddie']->quantite[$numero_ligne];
1038  }
1039  unset($product_object);
1040  }
1041  foreach($GLOBALS['site_parameters']['global_remise_percent'] as $this_treshold => $this_percent) {
1042  if (vn($total) >= $this_treshold) {
1043  // On a dépassé le seuil, donc la valeur la plus proche est celle précédemment trouvée.
1044  $global_promotion = vn($this_percent);
1045  }
1046  }
1047  } else {
1048  $global_promotion = vn($GLOBALS['site_parameters']['global_remise_percent']);
1049  }
1050  } else {
1051  $global_promotion = 0;
1052  }
1053  if (!empty($this->id_marque) && check_if_module_active('marques_promotion')) {
1054  $marque = get_marque_promotion($this->id_marque);
1055  }
1056  if (empty($marque)) {
1057  $marque = array('nom' => '', 'promotion_devises' => 0, 'promotion_percent' => 0);
1058  }
1059  $get_promotion_by_user_offer_object = $this->get_promotion_by_user_offer($quantity);
1060  if(!empty($get_promotion_by_user_offer_object)) {
1061  $promotion_by_user_offer = $get_promotion_by_user_offer_object->remise_percent;
1062  } else {
1063  $promotion_by_user_offer = 0;
1064  }
1065  // Application des réductions automatique en fonction de mots clés dans la description ou la référence du produit
1066  $promotion_by_product_filter_object = $this->get_promotion_by_product_filter();
1067  if(!empty($promotion_by_product_filter_object)) {
1068  $promotion_by_product_filter = $promotion_by_product_filter_object->remise_percent;
1069  } else {
1070  $promotion_by_product_filter = 0;
1071  }
1072  // Calcul du pourcentage de réduction à partir du champ prix_promo. Ne s'applique pas si le prix est défini par les réductions par lot
1073  if ($this->prix_promo > 0 && $this->prix > 0 && empty($GLOBALS['cache']['lot_price_by_id'][$this->id])) {
1074  $prix_promo_percent = round(($this->prix - $this->prix_promo) * 100 / $this->prix, 2);
1075  } else {
1076  $prix_promo_percent = 0;
1077  }
1078  if (!empty($GLOBALS['site_parameters']['product_add_all_percent_discount'])) {
1079  // Si on veut cumuler les réductions par produit, par marque et par catégorie
1080  $rebate_coefficient = 1 - (1 - $user_promotion_percentage / 100) * (1 - $this->promotion / 100) * (1 - $cat['promotion_percent'] / 100) * (1 - $marque['promotion_percent'] / 100) * (1 - $global_promotion / 100) * (1 - $promotion_by_product_filter / 100) * (1 - $promotion_by_user_offer / 100);
1081  } else {
1082  // La réduction produit est le max de ce qui est indiqué dans le produit, la marque , la catégorie et la promotion générale
1083  $rebate_coefficient = 1 - (1 - $user_promotion_percentage / 100) * (1 - min(max($this->promotion, $cat['promotion_percent'], $marque['promotion_percent'], $global_promotion, $promotion_by_product_filter, $promotion_by_user_offer, $prix_promo_percent), 100) / 100);
1084  }
1085  } else {
1086  // Si on est revendeur, seule la promotion utilisateur est utilisée
1087  $rebate_coefficient = 1 - (1 - $user_promotion_percentage / 100);
1088  }
1089  $percentage = $rebate_coefficient * 100;
1090  if ($format) {
1091  return sprintf("%0.2f", $percentage) . '%';
1092  } else {
1093  return $percentage;
1094  }
1095  }
1096 
1103  function get_ecotax($with_taxes = true)
1104  {
1105  if ($with_taxes) {
1106  return $this->ecotaxe_ttc;
1107  } else {
1108  return $this->ecotaxe_ht;
1109  }
1110  }
1111 
1126  function affiche_prix($with_taxes = true, $reseller_mode = false, $return_mode = false, $display_with_measurement = false, $item_id = null, $display_ecotax = true, $display_old_price = true, $table_css_class = 'full_width', $display_old_price_inline = true, $add_rdfa_properties = false, $force_display_with_vat_symbol = null, $display_minimal_price = null)
1127  {
1128  $output = affiche_prix($this, $with_taxes, $reseller_mode, $return_mode, $display_with_measurement, $item_id, $display_ecotax, $display_old_price, $table_css_class, $display_old_price_inline, $force_display_with_vat_symbol, $add_rdfa_properties, $display_minimal_price);
1129 
1130  if ($return_mode) {
1131  return $output;
1132  } else {
1133  echo $output;
1134  }
1135  }
1136 
1148  function format_prices($value_without_taxes, $with_taxes = true, $ecotax_quantity = 1, $format = false, $add_tax_type_text = false, $add_rdfa_properties = false)
1149  {
1151  // On doit arrondir les valeurs tarifaires officielles qui sont en TTC
1152  $value_with_taxes = round($value_without_taxes * (1 + $this->tva / 100), 2);
1153  $value_without_taxes = $value_with_taxes / (1 + $this->tva / 100);
1154  } else {
1155  // On doit arrondir les valeurs tarifaires officielles qui sont en HT
1156  $value_without_taxes = round($value_without_taxes, 2);
1157  $value_with_taxes = $value_without_taxes * (1 + $this->tva / 100);
1158  }
1159  if (!empty($ecotax_quantity)) {
1160  $value_without_taxes += $this->get_ecotax(false) * $ecotax_quantity;
1161  $value_with_taxes += $this->get_ecotax(true) * $ecotax_quantity;
1162  }
1163  if ($with_taxes) {
1164  if (empty($this->vat_applicable)) {
1165  $value_with_taxes = $value_without_taxes;
1166  }
1167  if ($format) {
1168  $value_with_taxes = fprix($value_with_taxes, true, null, true, null, false, true, null, $add_rdfa_properties);
1169  if ($add_tax_type_text) {
1170  $value_with_taxes .= ' ' . $GLOBALS['STR_TTC'];
1171  }
1172  }
1173  return $value_with_taxes;
1174  } else {
1175  if ($format) {
1176  $value_without_taxes = fprix($value_without_taxes, true, null, true, null, false, true, null, $add_rdfa_properties);
1177  if ($add_tax_type_text) {
1178  $value_without_taxes .= ' ' . $GLOBALS['STR_HT'];
1179  }
1180  }
1181  return $value_without_taxes;
1182  }
1183  }
1184 
1191  {
1192  $user = get_user_information($this->id_utilisateur);
1193  if (!empty($user['societe'])) {
1194  return $user['societe'];
1195  } else {
1196  return false;
1197  }
1198  }
1199 
1206  function get_product_stock_state($product_stock_infos = null)
1207  {
1208  if (empty($product_stock_infos)) {
1209  $product_stock_infos = get_product_stock_infos($this->id, $this->configuration_size_id, $this->configuration_color_id);
1210  }
1211  $stock_remain_all = 0;
1212  foreach($product_stock_infos as $stock_infos) {
1213  $stock_remain_all += $stock_infos['stock_temp'];
1214  }
1215  return affiche_etat_stock($stock_remain_all, $this->on_rupture, true);
1216  }
1217 
1224  {
1225  $categories_array = array();
1226  $query = query('SELECT pc.categorie_id, c.nom_' . $this->lang . '
1227  FROM peel_produits_categories pc
1228  INNER JOIN peel_categories c ON c.id = pc.categorie_id AND ' . get_filter_site_cond('categories', 'c') . '
1229  WHERE pc.produit_id = "' . intval($this->id) . '"
1230  ORDER BY c.position ASC, c.nom_' . $this->lang . ' ASC');
1231  while ($result = fetch_assoc($query)) {
1232  $categories_array[$result['categorie_id']] = $result['nom_' . $this->lang];
1233  }
1234  return $categories_array;
1235  }
1236 
1243  {
1244  $query = query("SELECT COUNT(*) as count_opinion
1245  FROM peel_avis pa
1246  WHERE pa.id_produit = '" . intval($this->id) . "' AND etat=1");
1248  return vn($result['count_opinion']);
1249  }
1250 
1256  function qrcode_image_src()
1257  {
1258  return $GLOBALS['wwwroot'].'/qrcode.php?path='.urlencode(rawurldecode(str_replace($GLOBALS['wwwroot'], '', $this->get_product_url())));
1259  }
1260 
1267  {
1268  if(!empty($this->ean_code)) {
1269  return $GLOBALS['wwwroot'].'/qrcode.php?barcode='.urlencode($this->ean_code);
1270  } else {
1271  return false;
1272  }
1273  }
1280  {
1281  // recherche dans les prix par lot
1282  $sql = "SELECT MIN(prix) AS prix, MIN(prix_revendeur) AS prix_revendeur
1283  FROM peel_quantites
1284  WHERE produit_id = '" . intval($this->id) . "' AND " . get_filter_site_cond('quantites');
1285  $query = query($sql);
1286  $Qte = fetch_assoc($query);
1287  $price_Qte_ht = (check_if_module_active('reseller') && is_reseller() && $Qte['prix_revendeur'] != 0? $Qte['prix_revendeur'] / (1 + $this->tva / 100) : $Qte['prix'] / (1 + $this->tva / 100));
1288  $price_ht = $this->get_final_price(get_current_user_promotion_percentage(), false, check_if_module_active('reseller') && is_reseller());
1289  $minimal_price_array = array();
1290  if ($price_Qte_ht > 0) {
1291  $minimal_price_array[] = $price_Qte_ht;
1292  }
1293  if ($price_ht > 0) {
1294  $minimal_price_array[] = $price_ht;
1295  }
1296  $minimal_price = min ($minimal_price_array);
1297  return $this->format_prices($minimal_price, display_prices_with_taxes_active(), false, true, true);
1298  }
1299 }
$ean_code
Definition: Product.php:48
get_product_stock_state($product_stock_infos=null)
Renvoie l'état du stock pour ce produit sous forme de HTML.
Definition: Product.php:1206
$product_infos
$image13
Definition: Product.php:70
$categorie_sentence_displayed_on_product
Definition: Product.php:132
static strip_tags($string, $allowed_tags=null)
String::strip_tags()
Definition: String.php:548
get_size($return_mode= 'name', $user_promotion_percentage=0, $with_taxes=true, $reseller_mode=false, $format=false, $add_tax_type_text=false)
Product::get_size()
Definition: Product.php:469
$image26
Definition: Product.php:83
get_original_price($with_taxes=true, $reseller_mode=false, $format=false, $add_tax_type_text=false, $add_ecotax=true, $get_price_for_this_configuration=true, $quantity=1, $prices_whole_site_rebate_percentage=true)
Product::get_original_price()
Definition: Product.php:782
$result
$image24
Definition: Product.php:81
get_final_price($user_promotion_percentage=0, $with_taxes=true, $reseller_mode=false, $format=false, $add_tax_type_text=false, $quantity=1, $add_ecotax=true, $get_price_for_this_configuration=true, $add_rdfa_properties=false, $quantity_all_products_in_category=null)
Prix final après application des réductions diverses, pour la quantité demandée (on renvoie le prix t...
Definition: Product.php:817
$description
Definition: Product.php:33
$on_special
Definition: Product.php:95
get_user_information($user_id=null, $get_full_infos=false)
Chargement des détails de l'utilisateur.
Definition: user.php:906
get_possible_sizes($return_mode= 'name', $user_promotion_percentage=0, $with_taxes=true, $reseller_mode=false, $format=false, $add_tax_type_text=false)
Product::get_possible_sizes()
Definition: Product.php:490
get_product_brands($return_array=true)
Product::get_product_brands()
Definition: Product.php:611
static strpos($haystack, $needle, $offset=0)
Returns the numeric position of the first occurrence of needle in the haystack string.
Definition: String.php:54
$unit_per_pallet
Definition: Product.php:130
set_configuration($color_id=null, $size_id=null, $attributs_list=null, $reseller_mode=false, $format_attribut_description_for_database=false)
Définit la configuration du produit, en tenant compte du statut revendeur ou non de l'utilisateur afi...
Definition: Product.php:362
$prix_barre_ht
Definition: Product.php:43
$ecotaxe_ht
Definition: Product.php:116
$youtube_code
Definition: Product.php:89
$on_download
Definition: Product.php:104
$attributs_array
$image29
Definition: Product.php:86
$image30
Definition: Product.php:87
$attributes_with_single_options_array
Definition: Product.php:134
$prix_achat
Definition: Product.php:46
$id_utilisateur
Definition: Product.php:127
static html_entity_decode_if_needed($string)
String::html_entity_decode_if_needed()
Definition: String.php:533
$on_rupture
Definition: Product.php:96
$image10
Definition: Product.php:67
$position
Definition: Product.php:40
get_ecotax($with_taxes=true)
Product::get_ecotax()
Definition: Product.php:1103
$prix_promo
Definition: Product.php:54
$image15
Definition: Product.php:72
$image14
Definition: Product.php:71
get_supplier_price($with_taxes=true, $format=false, $add_tax_type_text=false, $add_ecotax=true, $quantity=1)
Product::get_supplier_price()
Definition: Product.php:760
format_prices($value_without_taxes, $with_taxes=true, $ecotax_quantity=1, $format=false, $add_tax_type_text=false, $add_rdfa_properties=false)
Product::format_prices()
Definition: Product.php:1148
$default_image
Definition: Product.php:57
$categorie
Definition: Product.php:113
static strtolower($string)
Returns string with all alphabetic characters converted to lowercase.
Definition: String.php:135
$prix_revendeur
Definition: Product.php:52
$descriptif
Definition: Product.php:32
nohtml_real_escape_string($value, $allowed_tags=null)
Protège les données pour insertion dans MySQL ET supprime les tags HTML pour protéger de toute sorte ...
Definition: database.php:400
$configuration_color_id
Definition: Product.php:118
$image16
Definition: Product.php:73
get_category_name($id)
Renvoie le nom d'une catégorie de produits.
Definition: fonctions.php:912
$affiche_stock
Definition: Product.php:94
is_code_promo_applicable($id_categorie, $product_filter, &$found_cat, $cat_not_apply_code_promo=null)
is_code_promo_applicable()
Definition: Product.php:906
$on_flash
Definition: Product.php:97
$configuration_size_name
Definition: Product.php:123
$prix_ht
Definition: Product.php:45
get_current_user_promotion_percentage()
Calcule la réduction générale applicable à un utilisateur et garde la valeur en session pour accélére...
Definition: user.php:939
if(empty($_GET['id'])) if(!empty($GLOBALS['site_parameters']['allow_multiple_product_url_with_category'])) $product_object
$ecotaxe_ttc
Definition: Product.php:115
real_escape_string($value)
real_escape_string()
Definition: database.php:374
get_supplier_name()
Retoune le nom du fournisseur connaissant son id.
Definition: Product.php:1190
$configuration_overweight
Definition: Product.php:124
get_product_references()
Product::get_product_references()
Definition: Product.php:592
$configuration_size_id
Definition: Product.php:119
$image11
Definition: Product.php:68
$reference
Definition: Product.php:47
Product($id, $product_infos=null, $user_only_product_infos=false, $lang=null, $show_all_etat_if_admin=true, $vat_applicable=true, $show_all=false)
Product::Product()
Definition: Product.php:146
get_filter_site_cond($table_technical_code, $table_alias=null, $use_strict_rights_if_in_admin=false, $specific_site_id=null, $exclude_public_items=false, $admin_force_multisite_if_allowed=false)
Retourne la condition SQL permettant de filtrer les données pour une table.
Definition: fonctions.php:4643
affiche_prix($with_taxes=true, $reseller_mode=false, $return_mode=false, $display_with_measurement=false, $item_id=null, $display_ecotax=true, $display_old_price=true, $table_css_class= 'full_width', $display_old_price_inline=true, $add_rdfa_properties=false, $force_display_with_vat_symbol=null, $display_minimal_price=null)
Product::affiche_prix()
Definition: Product.php:1126
$default_color_id
Definition: Product.php:108
get_category_tree_and_itself($id_or_ids_array, $mode= 'sons', $table_to_use= 'categories')
get_category_tree_and_itself()
Definition: fonctions.php:933
$image17
Definition: Product.php:74
$configuration_attributs_list
Definition: Product.php:120
if(!defined('IN_PEEL')) display_prices_with_taxes_active()
display_prices_with_taxes_active()
Definition: fonctions.php:23
query($query, $die_if_error=false, $database_object=null, $silent_if_error=false, $security_sql_filter=true)
The query() function is meant to be called anywhere you want to make a query.
Definition: database.php:158
$meta_key
Definition: Product.php:36
$technical_code
Definition: Product.php:30
if(!defined('IN_PEEL')) est_identifie()
Retourne true si l'utilisateur est identifié
Definition: user.php:23
$configuration_size_price_ht
Definition: Product.php:125
$on_gift
Definition: Product.php:98
vb(&$var, $default=null)
Variable blanche if $var n'est pas défini, retourne $default, sinon retourne $var.
Definition: format.php:97
$prix_barre
Definition: Product.php:42
$flash_start
Definition: Product.php:100
$conditionnement
Definition: Product.php:131
if(strlen($date2)== '10') if($type== 'users-by-age'&&a_priv('admin_users', true)) elseif($type== 'forums-count'&&a_priv('admin_content', true)) elseif($type== 'forums-categories'&&a_priv('admin_content', true)) elseif($type== 'users-count'&&a_priv('admin_users', true)) elseif($type== 'product-categories'&&a_priv('admin_products', true)) elseif($type== 'users-by-sex'&&a_priv('admin_users', true)) elseif($type== 'users-by-country'&&a_priv('admin_users', true)) elseif($type== 'sales'&&a_priv('admin_sales', true))
Definition: chart-data.php:160
$extra_link
Definition: Product.php:129
get_product_options()
Product::get_product_options()
Definition: Product.php:639
get_promotion_by_user_offer($quantity=1)
Product::get_promotion_by_user_offer()
Definition: Product.php:968
$vat_applicable
Definition: Product.php:128
fetch_object($query_result)
fetch_object()
Definition: database.php:302
get_product_url($add_get_suffixe=false, $html_encode=false)
Product::get_product_url()
Definition: Product.php:384
$delai_stock
Definition: Product.php:92
$image19
Definition: Product.php:76
get_all_promotions_percentage($reseller_mode=false, $user_promotion_percentage=0, $format=false, $quantity=1, $quantity_all_products_in_category=null)
Product::get_all_promotions_percentage()
Definition: Product.php:1013
$on_stock
Definition: Product.php:90
get_possible_categories()
Product::get_possible_categories()
Definition: Product.php:1223
fetch_assoc($query_result)
fetch_assoc()
Definition: database.php:283
$display_price_by_weight
Definition: Product.php:41
$configuration_total_original_price_attributs_ht
Definition: Product.php:121
call_module_hook($hook, $params, $mode= 'boolean')
Appelle la fonction correspondant au $hook pour chaque module installé La fonction doit s'appeler : [...
$image25
Definition: Product.php:82
$categorie_id
Definition: Product.php:111
$id_marque
Definition: Product.php:107
$meta_desc
Definition: Product.php:35
$id_ecotaxe
Definition: Product.php:114
$image28
Definition: Product.php:85
$prix_flash
Definition: Product.php:102
$image18
Definition: Product.php:75
get_promotion_by_product_filter($reseller_mode=false)
Récupère une éventuelle réduction définie dans la table code promo, avec nom vide (pour application a...
Definition: Product.php:947
get_product_main_picture($display_pdf=false, $force_id_couleur=null)
Check if a picture or a pdf exist in peel_produit_color and peel_produit and returns the first image ...
Definition: Product.php:652
$image12
Definition: Product.php:69
$GLOBALS['page_columns_count']
qrcode_image_src()
Récupère une image avec le QRCode.
Definition: Product.php:1256
$meta_titre
Definition: Product.php:34
get_minimal_price()
Retourne le prix d'appel du produit, toutes réductions inclue.
Definition: Product.php:1279
$on_reseller
Definition: Product.php:106
$etat_stock
Definition: Product.php:93
$total
vn(&$var, $default=0)
Variable nulle if $var n'est pas défini, retourne $default, sinon retourne $var.
Definition: format.php:110
$image22
Definition: Product.php:79
get_count_opinion()
permet de savoir le nombre d'avis pour le produit
Definition: Product.php:1242
a_priv($requested_priv, $demo_allowed=false, $site_configuration_modification=false, $user_id=null)
Renvoie true si l'utilisateur de la session a le privilège $requested_priv ou un droit supérieur Des ...
Definition: user.php:63
barcode_image_src()
Récupère une image avec le code barre au format EAN13.
Definition: Product.php:1266
get_possible_attributs($return_mode= 'name', $get_configuration_results_only=false, $user_promotion_percentage=0, $with_taxes=true, $reseller_mode=false, $format=false, $add_tax_type_text=false, $get_attributes_with_multiple_options_only=true, $get_attributes_with_single_options_only=false, $filter_technical_code=null)
Product::get_possible_attributs()
Definition: Product.php:549
$comments
Definition: Product.php:91
$configuration_attributs_description
Definition: Product.php:122
$promotion
Definition: Product.php:53
$on_estimate
Definition: Product.php:50
$on_gift_points
Definition: Product.php:99
fprix($price, $display_currency=false, $currency_code_or_default=null, $convertion_needed_into_currency=true, $currency_rate=null, $display_iso_currency_code=false, $format=true, $force_format_separator=null, $add_rdfa_properties=false, $round_even_if_no_format=false)
fprix formatte le prix donné en le convertissant si nécessaire au préalable et en ajoutant éventuelle...
Definition: fonctions.php:242
$image21
Definition: Product.php:78
$image23
Definition: Product.php:80
static substr($string, $start, $length=null)
Returns the portion of string specified by the start and length parameters.
Definition: String.php:112
check_if_module_active($module_name, $specific_file_name=null)
Renvoie si un module est présent et activé ou non - Peut être appelé avant ou après le chargement d'u...
correct_output(&$output, $replace_template_tags=false, $format=null, $lang=null)
Corrige le contenu à afficher, notamment pour avoir du https même si http est stocké en BDD...
Definition: format.php:854
get_color()
Product::get_color()
Definition: Product.php:424
$image20
Definition: Product.php:77
get_possible_colors()
Product::get_possible_colors()
Definition: Product.php:439
$display_tab
Definition: Product.php:109
$image27
Definition: Product.php:84
static str_shorten($string, $length_limit, $middle_separator= '', $ending_if_no_middle_separator= '...', $ideal_length_with_clean_cut_if_possible=null)
Raccourcit une chaine de caractère en insérant au milieu ou à la fin un séparateur.
Definition: String.php:233
get_product_pictures($display_pdf=false, $force_id_couleur=null, $only_return_first_picture=false)
Check if pictures or pdf files exist in peel_produit_color and peel_produit and returns the array of ...
Definition: Product.php:670
$flash_end
Definition: Product.php:101
is_price_flash($reseller_mode=false)
Product::is_price_flash()
Definition: Product.php:893
if(defined('IN_PEEL_ADMIN')||IN_INSTALLATION) $_SESSION['session_langue']

This documentation for Open ecommerce PEEL Shopping and PEEL.fr has been generated by Doxygen on Thu Oct 15 2015 14:30:07 - Peel ecommerce is a product of Agence web Advisto SAS. All rights reserved.