Owebia_Shipping_2 - Version 2.4.6

Version Notes

[2.4.6 - 19 janvier 2012]
Correction d'un bug dans l'utilisation de la fonction {table ... in ...} : lorsque la variable de référence est indéfinie, le résultat était invalide (valeur précédente de la variable $replacement)
Correction d'un problème avec les produits packagés (bundle product) : les produits 'bundle' et les produits 'simple' étaient tous deux récupérés ce qui faussait les résultats
Support des sets d'attributs
product.attribute_set dans les conditions de boucle foreach
{product.attribute_set} et {product.attribute_set.id} comme variables dans les boucles foreach
product.attribute_set, product.attribute_set.id dans les conditions des opérations sum, count, min et max
Optimisation du chargement de certaines valeurs (catégories, attribute set, ...)
Correction d'un problème avec les castings successifs (string), (float) qui posent problème lorsque la locale utilise la virgule comme séparateur de décimales

Download this release

Release Info

Developer Magento Core Team
Extension Owebia_Shipping_2
Version 2.4.6
Comparing to
See all releases


Code changes from version 2.4.5 to 2.4.6

app/code/community/Owebia/Shipping2/Model/Carrier/AbstractOwebiaShipping.php CHANGED
@@ -24,18 +24,38 @@ if (file_exists(dirname(__FILE__).'/Owebia_Shipping2_includes_OwebiaShippingHelp
24
  else include_once Mage::getBaseDir('code').'/community/Owebia/Shipping2/includes/OwebiaShippingHelper.php';
25
 
26
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  class Magento_Category implements OS_Category {
28
  private $id;
29
  private $loaded_category;
30
  public function __construct($id) {
31
  $this->id = (int)$id;
32
  }
33
-
34
  private function _loadCategory() {
35
  if (!isset($this->loaded_category)) $this->loaded_category = Mage::getModel('catalog/category')->load($this->id);
36
  return $this->loaded_category;
37
  }
38
-
39
  public function getId() {
40
  return $this->id;
41
  }
@@ -46,7 +66,6 @@ class Magento_Category implements OS_Category {
46
  public function toString() {
47
  return $this->getName().' (id:'.$this->getId().', url_key:'.$this->_loadCategory()->getUrlKey().')';
48
  }
49
-
50
  }
51
 
52
  class Magento_Product implements OS_Product {
@@ -54,15 +73,18 @@ class Magento_Product implements OS_Product {
54
  private $cart_item;
55
  private $cart_product;
56
  private $loaded_product;
 
57
  private $quantity;
58
  private $options;
59
  private $categories;
60
 
61
  public function __construct($cart_item, $parent_cart_item) {
62
  $this->cart_item = $cart_item;
63
- $this->cart_product = $cart_item->getProduct();
64
  $this->parent_cart_item = $parent_cart_item;
65
- $this->quantity = isset($parent_cart_item) ? $parent_cart_item->getQty() : $cart_item->getQty();
 
 
 
66
  }
67
 
68
  private function getProductOptions() {
@@ -120,6 +142,12 @@ class Magento_Product implements OS_Product {
120
  return $this->cart_item['price_incl_tax'];
121
  //return Mage::helper('checkout')->getPriceInclTax($this->cart_item);
122
  }
 
 
 
 
 
 
123
  $attribute = $product->getResource()->getAttribute($attribute_name);
124
  if ($attribute) {
125
  $input_type = $attribute->getFrontend()->getInputType();
@@ -156,6 +184,14 @@ class Magento_Product implements OS_Product {
156
  return $this->cart_product->getId();
157
  }
158
 
 
 
 
 
 
 
 
 
159
  public function getCategory() {
160
  $categories = $this->getCategories();
161
  return $categories ? $categories[0] : null;
@@ -210,6 +246,8 @@ abstract class Owebia_Shipping2_Model_Carrier_AbstractOwebiaShipping extends Mag
210
  * @return Mage_Shipping_Model_Rate_Result
211
  */
212
  public function collectRates(Mage_Shipping_Model_Rate_Request $request) {
 
 
213
  // skip if not enabled
214
  if (!$this->__getConfigData('active')) return false;
215
 
@@ -263,7 +301,7 @@ abstract class Owebia_Shipping2_Model_Carrier_AbstractOwebiaShipping extends Mag
263
  $process['data']['cart.weight.for-charge'] = $process['data']['cart.weight'];
264
 
265
  foreach ($cart_items as $item) {
266
- if ($item->getProduct()->getTypeId()!='configurable') {
267
  $parent_item_id = $item->getParentItemId();
268
  $magento_product = new Magento_Product($item, isset($cart_items[$parent_item_id]) ? $cart_items[$parent_item_id] : null);
269
  $process['cart.products'][] = $magento_product;
24
  else include_once Mage::getBaseDir('code').'/community/Owebia/Shipping2/includes/OwebiaShippingHelper.php';
25
 
26
 
27
+ class Magento_AttributeSet implements OS_AttributeSet {
28
+ private $id;
29
+ private $loaded_attribute_set;
30
+ public function __construct($id) {
31
+ $this->id = (int)$id;
32
+ }
33
+ private function _loadAttributeSet() {
34
+ if (!isset($this->loaded_attribute_set)) $this->loaded_attribute_set = Mage::getModel('eav/entity_attribute_set')->load($this->id);
35
+ return $this->loaded_attribute_set;
36
+ }
37
+ public function getId() {
38
+ return $this->id;
39
+ }
40
+ public function getName() {
41
+ $attribute_set = $this->_loadAttributeSet();
42
+ return $attribute_set->getAttributeSetName();
43
+ }
44
+ public function toString() {
45
+ return $this->getName().' (id:'.$this->getId().')';
46
+ }
47
+ }
48
+
49
  class Magento_Category implements OS_Category {
50
  private $id;
51
  private $loaded_category;
52
  public function __construct($id) {
53
  $this->id = (int)$id;
54
  }
 
55
  private function _loadCategory() {
56
  if (!isset($this->loaded_category)) $this->loaded_category = Mage::getModel('catalog/category')->load($this->id);
57
  return $this->loaded_category;
58
  }
 
59
  public function getId() {
60
  return $this->id;
61
  }
66
  public function toString() {
67
  return $this->getName().' (id:'.$this->getId().', url_key:'.$this->_loadCategory()->getUrlKey().')';
68
  }
 
69
  }
70
 
71
  class Magento_Product implements OS_Product {
73
  private $cart_item;
74
  private $cart_product;
75
  private $loaded_product;
76
+ private $type;
77
  private $quantity;
78
  private $options;
79
  private $categories;
80
 
81
  public function __construct($cart_item, $parent_cart_item) {
82
  $this->cart_item = $cart_item;
 
83
  $this->parent_cart_item = $parent_cart_item;
84
+ $this->type = $parent_cart_item ? $parent_cart_item->getProduct()->getTypeId() : $cart_item->getProduct()->getTypeId();
85
+ $this->quantity = $parent_cart_item ? $parent_cart_item->getQty() : $cart_item->getQty();
86
+ if ($this->type=='bundle') $this->cart_product = $parent_cart_item->getProduct();
87
+ else $this->cart_product = $cart_item->getProduct();
88
  }
89
 
90
  private function getProductOptions() {
142
  return $this->cart_item['price_incl_tax'];
143
  //return Mage::helper('checkout')->getPriceInclTax($this->cart_item);
144
  }
145
+ // Dynamic weight for bundle product
146
+ if ($this->type=='bundle' && $attribute_name=='weight' && $product->getData('weight_type')==0) {
147
+ // !!! Use cart_product and not product
148
+ return $this->cart_product->getTypeInstance(true)->getWeight($this->cart_product);
149
+ }
150
+
151
  $attribute = $product->getResource()->getAttribute($attribute_name);
152
  if ($attribute) {
153
  $input_type = $attribute->getFrontend()->getInputType();
184
  return $this->cart_product->getId();
185
  }
186
 
187
+ public function getAttributeSet() {
188
+ if (!isset($this->attribute_set)) {
189
+ $product = $this->_loadProduct();
190
+ $this->attribute_set = new Magento_AttributeSet($product->getAttributeSetId());
191
+ }
192
+ return $this->attribute_set;
193
+ }
194
+
195
  public function getCategory() {
196
  $categories = $this->getCategories();
197
  return $categories ? $categories[0] : null;
246
  * @return Mage_Shipping_Model_Rate_Result
247
  */
248
  public function collectRates(Mage_Shipping_Model_Rate_Request $request) {
249
+ //setlocale(LC_NUMERIC, 'fr_FR');
250
+
251
  // skip if not enabled
252
  if (!$this->__getConfigData('active')) return false;
253
 
301
  $process['data']['cart.weight.for-charge'] = $process['data']['cart.weight'];
302
 
303
  foreach ($cart_items as $item) {
304
+ if ($item->getProduct()->getTypeId()!='configurable' && $item->getProduct()->getTypeId()!='bundle') {
305
  $parent_item_id = $item->getParentItemId();
306
  $magento_product = new Magento_Product($item, isset($cart_items[$parent_item_id]) ? $cart_items[$parent_item_id] : null);
307
  $process['cart.products'][] = $magento_product;
app/code/community/Owebia/Shipping2/changelog CHANGED
@@ -1,3 +1,13 @@
 
 
 
 
 
 
 
 
 
 
1
  [2.4.5 - 12 janvier 2012]
2
  Ajout de la fonction switch
3
  Ajout d'une syntaxe pour auto-�chapper les cha�nes de caract�res (ex: {{cart.coupon}} donnera null ou 'test' en fonction de la valeur de la variable)
1
+ [2.4.6 - 19 janvier 2012]
2
+ Correction d'un bug dans l'utilisation de la fonction {table ... in ...} : lorsque la variable de r�f�rence est ind�finie, le r�sultat �tait invalide (valeur pr�c�dente de la variable $replacement)
3
+ Correction d'un probl�me avec les produits packag�s (bundle product) : les produits 'bundle' et les produits 'simple' �taient tous deux r�cup�r�s ce qui faussait les r�sultats
4
+ Support des sets d'attributs
5
+ product.attribute_set dans les conditions de boucle foreach
6
+ {product.attribute_set} et {product.attribute_set.id} comme variables dans les boucles foreach
7
+ product.attribute_set, product.attribute_set.id dans les conditions des op�rations sum, count, min et max
8
+ Optimisation du chargement de certaines valeurs (cat�gories, attribute set, ...)
9
+ Correction d'un probl�me avec les castings successifs (string), (float) qui posent probl�me lorsque la locale utilise la virgule comme s�parateur de d�cimales
10
+
11
  [2.4.5 - 12 janvier 2012]
12
  Ajout de la fonction switch
13
  Ajout d'une syntaxe pour auto-�chapper les cha�nes de caract�res (ex: {{cart.coupon}} donnera null ou 'test' en fonction de la valeur de la variable)
app/code/community/Owebia/Shipping2/includes/OwebiaShippingHelper.php CHANGED
@@ -24,6 +24,7 @@ class OwebiaShippingHelper
24
  const PRODUCT_REGEX = '(?:product|p)';
25
  const ATTRIBUTE_REGEX = '(?:attribute|attr|a)';
26
  const OPTION_REGEX = '(?:option|opt|o)';
 
27
  const CATEGORIES_REGEX = '(?:categories)';
28
  const CATEGORY_REGEX = '(?:category)';
29
  const FLOAT_REGEX = '[-]?\d+(?:[.]\d+)?';
@@ -50,6 +51,13 @@ class OwebiaShippingHelper
50
  '{s.',
51
  );
52
 
 
 
 
 
 
 
 
53
  public static function parseSize($size) {
54
  $size = trim($size);
55
  $last = strtolower($size[strlen($size)-1]);
@@ -58,12 +66,12 @@ class OwebiaShippingHelper
58
  case 'm': $size *= 1024;
59
  case 'k': $size *= 1024;
60
  }
61
- return $size;
62
  }
63
 
64
  public static function formatSize($size) {
65
  $unit = array('B', 'KB', 'MB', 'GB', 'TB', 'PB');
66
- return @round($size/pow(1024, ($i=floor(log($size, 1024)))), 2).' '.$unit[$i];
67
  }
68
 
69
  public static function getDefaultProcessData() {
@@ -162,7 +170,7 @@ class OwebiaShippingHelper
162
  public function initDebug($code, $data) {
163
  $header = 'DEBUG OwebiaShippingHelper.php<br/>';
164
  foreach ($data as $key => $data) {
165
- $header .= ' <span class="osh-key">'.str_replace('.', '</span>.<span class="osh-key">', $key).'</span> = <span class="osh-formula">'.$this->_toString($data).'</span><br/>';
166
  }
167
  $this->debug_code = $code;
168
  $this->debug_header = $header;
@@ -299,7 +307,7 @@ class OwebiaShippingHelper
299
  if (isset($fees)) {
300
  $result = $this->_processFormula($process, $row, 'fees', $fees, $is_checking);
301
  if (!$result->success) return $result;
302
- $this->debug(' &raquo; <span class="osh-info">result</span> = <span class="osh-formula">'.$this->_toString($result->result).'</span>');
303
  return new OS_Result(true, (float)$result->result);
304
  }
305
  return new OS_Result(false);
@@ -315,7 +323,7 @@ class OwebiaShippingHelper
315
  if (isset($row[$key]['value'])) {
316
  $property = $row[$key]['value'];
317
  $output = $property;
318
- $this->debug(' get <span class="osh-key">'.$row['*code'].'</span>.<span class="osh-key">'.$key.'</span> = <span class="osh-formula">'.$this->_toString($property).'</span>');
319
  preg_match_all('/{([a-z0-9_]+)\.([a-z0-9_]+)}/i', $output, $result_set, PREG_SET_ORDER);
320
  foreach ($result_set as $result) {
321
  list($original, $ref_code, $ref_key) = $result;
@@ -343,18 +351,12 @@ class OwebiaShippingHelper
343
  return $output;
344
  }
345
 
346
- protected function _toString($value) {
347
- if (!isset($value)) return 'null';
348
- else if (is_bool($value)) return $value ? 'true' : 'false';
349
- else return $value;
350
- }
351
-
352
  protected function replace($from, $to, $input) {
353
  if ($from===$to) return $input;
354
- if (strpos($input, $from)===false) return $input;
355
- $to = $this->_toString($to);
356
  $to = preg_replace('/[\r\n\t]+/', ' ', $to);
357
- $this->debug(' replace <span class="osh-replacement">'.$this->_toString($from).'</span> by <span class="osh-replacement">'.$to.'</span> =&gt; <span class="osh-formula">'.str_replace($from, '<span class="osh-replacement">'.$to.'</span>', $input).'</span>');
358
  return str_replace($from, $to, $input);
359
  }
360
 
@@ -401,14 +403,19 @@ class OwebiaShippingHelper
401
  protected function setCache($expression, $value) {
402
  if ($value instanceof OS_Result) {
403
  $this->_formula_cache[$expression] = $value;
404
- $this->debug(' cache <span class="osh-replacement">'.$expression.'</span> = <span class="osh-formula">'.$this->_toString($this->_formula_cache[$expression]).'</span>');
405
  } else {
406
- $value = $this->_toString($value);
407
- $this->_expression_cache[$expression] = $value;
408
- $this->debug(' cache <span class="osh-replacement">'.$expression.'</span> = <span class="osh-formula">'.$value.'</span>');
409
  }
410
  }
411
 
 
 
 
 
 
 
412
  protected function _prepare_regexp($regexp) {
413
  if (!isset($this->constants)) {
414
  $reflector = new ReflectionClass(get_class($this));
@@ -431,12 +438,25 @@ class OwebiaShippingHelper
431
  if ($debug) $this->debug(' preg_match_all <span class="osh-replacement">'.$regexp.'</span>');
432
  $return = preg_match_all($regexp, $input, $result, PREG_SET_ORDER);
433
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
434
 
435
  protected function _prepareFormula($process, $row, $property_key, $formula_string, $is_checking, $use_cache=true)
436
  {
437
  if ($use_cache && isset($this->_formula_cache[$formula_string])) {
438
  $result = $this->_formula_cache[$formula_string];
439
- $this->debug(' get cached formula <span class="osh-replacement">'.$formula_string.'</span> = <span class="osh-formula">'.$this->_toString($result->result).'</span>');
440
  return $result;
441
  }
442
 
@@ -444,11 +464,10 @@ class OwebiaShippingHelper
444
  //$this->debug(' formula = <span class="osh-formula">'.$formula.'</span>');
445
 
446
  // foreach
447
- while ($this->_preg_match("#{foreach {PRODUCT_REGEX}\.((?:{ATTRIBUTE_REGEX}|{OPTION_REGEX})\.(?:[a-z0-9_]+)|{CATEGORIES_REGEX})}(.*){/foreach}#i", $formula, $result)) {
448
  $original = $result[0];
449
- if ($use_cache && isset($this->_expression_cache[$original])) {
450
- $replacement = $this->_expression_cache[$original];
451
- $this->debug(' get cached expression <span class="osh-replacement">'.$original.'</span> = <span class="osh-formula">'.$replacement.'</span>');
452
  } else {
453
  $replacement = 0;
454
  if ($result[1]=='categories') {
@@ -460,7 +479,7 @@ class OwebiaShippingHelper
460
  $categories_names = array();
461
  foreach ($categories as $category) {
462
  $key = $category->toString();
463
- $categories_names[] = $this->_toString($key);
464
  $sel = isset($selections[$key]) ? $selections[$key] : null;
465
  $selections[$key]['products'][] = $product;
466
  $selections[$key]['weight'] = (isset($sel['weight']) ? $sel['weight'] : 0)+$product->getAttribute('weight')*$product->getQuantity();
@@ -469,6 +488,20 @@ class OwebiaShippingHelper
469
  $this->debug(' products[<span class="osh-formula">'.$product->toString().'</span>].<span class="osh-key">categories</span> = array(<span class="osh-formula">'.join('</span>, <span class="osh-formula">', $categories_names).'</span>)');
470
  }
471
  $this->removeDebugIndent();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
472
  } else {
473
  list($filter_property_type, $filter_property_name) = explode('.', $result[1]);
474
  $selections = array();
@@ -476,7 +509,7 @@ class OwebiaShippingHelper
476
  $this->addDebugIndent();
477
  foreach ($process['cart.products'] as $product) {
478
  $tmp_value = $this->_getProductProperty($product, $filter_property_type, $filter_property_name, $get_by_id=false);
479
- $this->debug(' products[<span class="osh-formula">'.$product->toString().'</span>].<span class="osh-key">'.$filter_property_type.'</span>.<span class="osh-key">'.$filter_property_name.'</span> = <span class="osh-formula">'.$this->_toString($tmp_value).'</span>');
480
  $key = 'val_'.$tmp_value;
481
  $sel = isset($selections[$key]) ? $selections[$key] : null;
482
  $selections[$key]['products'][] = $product;
@@ -496,7 +529,7 @@ class OwebiaShippingHelper
496
  $process2['data']['selection.weight'] = $selection['weight'];
497
  $process_result = $this->_processFormula($process2, $row, $property_key, $result[2], $is_checking, $tmp_use_cache=false);
498
  $replacement += $process_result->result;
499
- $this->debug(' &raquo; <span class="osh-info">foreach sum result</span> = <span class="osh-formula">'.$replacement.'</span>');
500
  $this->removeDebugIndent();
501
  }
502
  $this->removeDebugIndent();
@@ -516,18 +549,14 @@ class OwebiaShippingHelper
516
  $first_product = isset($process['cart.products'][0]) ? $process['cart.products'][0] : null;
517
  if (!isset($process['data']['selection.weight'])) $process['data']['selection.weight'] = $process['data']['cart.weight'];
518
  if (!isset($process['data']['selection.quantity'])) $process['data']['selection.quantity'] = $process['data']['cart.quantity'];
 
 
519
  $process['data']['product.weight'] = 0;
520
  $process['data']['product.quantity'] = 0;
521
  $process['data']['product.category'] = null;
522
  $process['data']['product.category.id'] = null;
523
- if (isset($first_product)) {
524
- $process['data']['product.weight'] = $first_product->getAttribute('weight');
525
- $process['data']['product.quantity'] = $first_product->getQuantity();
526
- if ($category = $first_product->getCategory()) {
527
- $process['data']['product.category'] = $category->getName();
528
- $process['data']['product.category.id'] = $category->getId();
529
- }
530
- }
531
 
532
  $aliases = array(
533
  'p.' => 'product.',
@@ -535,16 +564,27 @@ class OwebiaShippingHelper
535
  's.' => 'selection.',
536
  );
537
  foreach ($process['data'] as $original => $replacement) {
538
- // With strings auto-escape
539
- $formula = $this->replace('{{'.$original.'}}', $this->_autoEscapeStrings($replacement), $formula);
540
- // Without strings auto-escape
541
- $formula = $this->replace('{'.$original.'}', $replacement, $formula);
 
 
 
 
 
542
  foreach ($aliases as $from => $to) {
543
- if (substr($original, 0, strlen($to))==$to) {
544
- // With strings auto-escape
545
- $formula = $this->replace('{{'.$from.substr($original, strlen($to), strlen($original)).'}}', $this->_autoEscapeStrings($replacement), $formula);
546
- // Without strings auto-escape
547
- $formula = $this->replace('{'.$from.substr($original, strlen($to), strlen($original)).'}', $replacement, $formula);
 
 
 
 
 
 
548
  }
549
  }
550
  }
@@ -570,9 +610,8 @@ class OwebiaShippingHelper
570
  || $this->_preg_match("/{(sum|min|max|count distinct) {PRODUCT_REGEX}\.(quantity)()(?: where ([^}]+))?}/i", $formula, $result)
571
  ) {
572
  $original = $result[0];
573
- if ($use_cache && isset($this->_expression_cache[$original])) {
574
- $replacement = $this->_expression_cache[$original];
575
- $this->debug(' get cached expression <span class="osh-replacement">'.$original.'</span> = <span class="osh-formula">'.$replacement.'</span>');
576
  } else {
577
  $replacement = $this->_processProductProperty($process['cart.products'], $result);
578
  if ($use_cache) $this->setCache($result[0], $replacement);
@@ -583,9 +622,8 @@ class OwebiaShippingHelper
583
  // switch
584
  while (preg_match("/{switch ([^}]+) in ([^}]+)}/i", $formula, $result)) {
585
  $original = $result[0];
586
- if ($use_cache && isset($this->_expression_cache[$original])) {
587
- $replacement = $this->_expression_cache[$original];
588
- $this->debug(' get cached expression <span class="osh-replacement">'.$original.'</span> = <span class="osh-formula">'.$replacement.'</span>');
589
  } else {
590
  $reference_value = $this->_evalFormula($result[1]);
591
  $fees_table_string = $result[2];
@@ -609,12 +647,12 @@ class OwebiaShippingHelper
609
 
610
  if ($value=='*' || $reference_value===$value) {
611
  $replacement = $fee;
612
- $this->debug(' compare <span class="osh-formula">'.$this->_toString($reference_value).'</span> and <span class="osh-formula">'.$this->_toString($value).'</span> = equals');
613
  break;
614
  }
615
- $this->debug(' compare <span class="osh-formula">'.$this->_toString($reference_value).'</span> and <span class="osh-formula">'.$this->_toString($value).'</span> = not equals');
616
  }
617
- $replacement = $this->_toString($replacement);
618
  if ($use_cache) $this->setCache($original, $replacement);
619
  }
620
  $formula = $this->replace($original, $replacement, $formula);
@@ -623,11 +661,11 @@ class OwebiaShippingHelper
623
  // range table
624
  while (preg_match("/{table ([^}]+) in ([0-9\.:,\*\[\] ]+)}/i", $formula, $result)) {
625
  $original = $result[0];
626
- if ($use_cache && isset($this->_expression_cache[$original])) {
627
- $replacement = $this->_expression_cache[$original];
628
- $this->debug(' get cached expression <span class="osh-replacement">'.$original.'</span> = <span class="osh-formula">'.$replacement.'</span>');
629
  } else {
630
  $reference_value = $this->_evalFormula($result[1]);
 
631
  if (isset($reference_value)) {
632
  $fees_table_string = $result[2];
633
 
@@ -638,8 +676,6 @@ class OwebiaShippingHelper
638
  return $result;
639
  }
640
  $fees_table = explode(',', $fees_table_string);
641
-
642
- $replacement = null;
643
  foreach ($fees_table as $item) {
644
  $fee_data = explode(':', $item);
645
 
@@ -659,7 +695,7 @@ class OwebiaShippingHelper
659
  }
660
  }
661
  }
662
- $replacement = $this->_toString($replacement);
663
  if ($use_cache) $this->setCache($original, $replacement);
664
  }
665
  $formula = $this->replace($original, $replacement, $formula);
@@ -694,7 +730,7 @@ class OwebiaShippingHelper
694
  );
695
  $eval_result = null;
696
  @eval('$eval_result = ('.$formula.');');
697
- $this->debug(' evaluate <span class="osh-formula">'.$formula.'</span> = <span class="osh-replacement">'.$this->_toString($eval_result).'</span>');
698
  return $eval_result;
699
  }
700
 
@@ -1257,7 +1293,7 @@ class OwebiaShippingHelper
1257
  } else if (mb_substr($code, 0, 1)=='/' && mb_substr($code, mb_strlen($code)-1, 1)=='/' && @preg_match($code, $address['postcode'])) {
1258
  $this->debug(' postcode <span class="osh-replacement">'.$address['postcode'].'</span> matches <span class="osh-formula">'.htmlentities($code).'</span>');
1259
  $in_array = true;
1260
- } else if (strpos($code, '*')!==false && preg_match('/^'.str_replace('*', '(?:.*)', $code).'$/', $address['postcode'])) {
1261
  $this->debug(' postcode <span class="osh-replacement">'.$address['postcode'].'</span> matches <span class="osh-formula">'.htmlentities($code).'</span>');
1262
  $in_array = true;
1263
  }
@@ -1296,11 +1332,11 @@ class OwebiaShippingHelper
1296
  if (is_array($input)) {
1297
  $items = array();
1298
  foreach ($input as $v) {
1299
- $items[] = !isset($v) ? 'null' : (is_string($v) || empty($v) ? "'".$v."'" : $v);
1300
  }
1301
  return 'array('.join(',', $items).')';
1302
  } else {
1303
- return !isset($input) ? 'null' : (is_string($input) || empty($input) ? "'".$input."'" : $input);
1304
  }
1305
  }
1306
 
@@ -1353,6 +1389,12 @@ class OwebiaShippingHelper
1353
  $property_regex_result[1] = 'categories';
1354
  if (!isset($properties[$key])) $properties[$key] = $property_regex_result;
1355
  }
 
 
 
 
 
 
1356
  $this->_preg_match_all('/{PRODUCT_REGEX}\.(quantity)/i', $conditions, $properties_regex_result);
1357
  foreach ($properties_regex_result as $property_regex_result) {
1358
  $key = $property_regex_result[0];
@@ -1369,6 +1411,11 @@ class OwebiaShippingHelper
1369
  case 'quantity':
1370
  $value = $product->getQuantity();
1371
  break;
 
 
 
 
 
1372
  case 'category':
1373
  $get_by_id = isset($property[2]) && $property[2]=='id';
1374
  $category = $product->getCategory();
@@ -1442,6 +1489,12 @@ class OwebiaShippingHelper
1442
 
1443
  }
1444
 
 
 
 
 
 
 
1445
  interface OS_Category {
1446
  public function getName();
1447
  public function getId();
@@ -1487,7 +1540,7 @@ class OS_Result {
1487
  }
1488
 
1489
  public function __toString() {
1490
- return is_bool($this->result) ? ($this->result ? 'true' : 'false') : (string)$this->result;
1491
  }
1492
  }
1493
 
24
  const PRODUCT_REGEX = '(?:product|p)';
25
  const ATTRIBUTE_REGEX = '(?:attribute|attr|a)';
26
  const OPTION_REGEX = '(?:option|opt|o)';
27
+ const ATTRIBUTE_SET_REGEX = '(?:attribute_set)';
28
  const CATEGORIES_REGEX = '(?:categories)';
29
  const CATEGORY_REGEX = '(?:category)';
30
  const FLOAT_REGEX = '[-]?\d+(?:[.]\d+)?';
51
  '{s.',
52
  );
53
 
54
+ public function toString($value) {
55
+ if (!isset($value)) return 'null';
56
+ else if (is_bool($value)) return $value ? 'true' : 'false';
57
+ else if (is_float($value)) return str_replace(',', '.', (string)$value); // To avoid locale problems
58
+ else return $value;
59
+ }
60
+
61
  public static function parseSize($size) {
62
  $size = trim($size);
63
  $last = strtolower($size[strlen($size)-1]);
66
  case 'm': $size *= 1024;
67
  case 'k': $size *= 1024;
68
  }
69
+ return (float)$size;
70
  }
71
 
72
  public static function formatSize($size) {
73
  $unit = array('B', 'KB', 'MB', 'GB', 'TB', 'PB');
74
+ return self::toString(@round($size/pow(1024, ($i=floor(log($size, 1024)))), 2)).' '.$unit[$i];
75
  }
76
 
77
  public static function getDefaultProcessData() {
170
  public function initDebug($code, $data) {
171
  $header = 'DEBUG OwebiaShippingHelper.php<br/>';
172
  foreach ($data as $key => $data) {
173
+ $header .= ' <span class="osh-key">'.str_replace('.', '</span>.<span class="osh-key">', $key).'</span> = <span class="osh-formula">'.self::toString($data).'</span> ('.gettype($data).')<br/>';
174
  }
175
  $this->debug_code = $code;
176
  $this->debug_header = $header;
307
  if (isset($fees)) {
308
  $result = $this->_processFormula($process, $row, 'fees', $fees, $is_checking);
309
  if (!$result->success) return $result;
310
+ $this->debug(' &raquo; <span class="osh-info">result</span> = <span class="osh-formula">'.self::toString($result->result).'</span>');
311
  return new OS_Result(true, (float)$result->result);
312
  }
313
  return new OS_Result(false);
323
  if (isset($row[$key]['value'])) {
324
  $property = $row[$key]['value'];
325
  $output = $property;
326
+ $this->debug(' get <span class="osh-key">'.$row['*code'].'</span>.<span class="osh-key">'.$key.'</span> = <span class="osh-formula">'.self::toString($property).'</span>');
327
  preg_match_all('/{([a-z0-9_]+)\.([a-z0-9_]+)}/i', $output, $result_set, PREG_SET_ORDER);
328
  foreach ($result_set as $result) {
329
  list($original, $ref_code, $ref_key) = $result;
351
  return $output;
352
  }
353
 
 
 
 
 
 
 
354
  protected function replace($from, $to, $input) {
355
  if ($from===$to) return $input;
356
+ if (mb_strpos($input, $from)===false) return $input;
357
+ $to = self::toString($to);
358
  $to = preg_replace('/[\r\n\t]+/', ' ', $to);
359
+ $this->debug(' replace <span class="osh-replacement">'.self::toString($from).'</span> by <span class="osh-replacement">'.$to.'</span> =&gt; <span class="osh-formula">'.str_replace($from, '<span class="osh-replacement">'.$to.'</span>', $input).'</span>');
360
  return str_replace($from, $to, $input);
361
  }
362
 
403
  protected function setCache($expression, $value) {
404
  if ($value instanceof OS_Result) {
405
  $this->_formula_cache[$expression] = $value;
406
+ $this->debug(' cache <span class="osh-replacement">'.$expression.'</span> = <span class="osh-formula">'.self::toString($value->result).'</span> ('.gettype($value->result).')');
407
  } else {
408
+ $this->_expression_cache[$expression] = $value; //self::toString($value); // In order to make isset work
409
+ $this->debug(' cache <span class="osh-replacement">'.$expression.'</span> = <span class="osh-formula">'.self::toString($value).'</span> ('.gettype($value).')');
 
410
  }
411
  }
412
 
413
+ protected function _getCachedExpression($original) {
414
+ $replacement = $this->_expression_cache[$original];
415
+ $this->debug(' get cached expression <span class="osh-replacement">'.$original.'</span> = <span class="osh-formula">'.self::toString($replacement).'</span> ('.gettype($replacement).')');
416
+ return $replacement;
417
+ }
418
+
419
  protected function _prepare_regexp($regexp) {
420
  if (!isset($this->constants)) {
421
  $reflector = new ReflectionClass(get_class($this));
438
  if ($debug) $this->debug(' preg_match_all <span class="osh-replacement">'.$regexp.'</span>');
439
  $return = preg_match_all($regexp, $input, $result, PREG_SET_ORDER);
440
  }
441
+
442
+ protected function _loadValue($process, $key) {
443
+ $first_product = isset($process['cart.products'][0]) ? $process['cart.products'][0] : null;
444
+ switch ($key) {
445
+ case 'product.attribute_set.id': return $first_product ? $first_product->getAttributeSet()->getId() : null;
446
+ case 'product.attribute_set': return $first_product ? $first_product->getAttributeSet()->getName() : null;
447
+ case 'product.category.id': return $first_product && $first_product->getCategory() ? $first_product->getCategory()->getId() : null;
448
+ case 'product.category': return $first_product && $first_product->getCategory() ? $first_product->getCategory()->getName() : null;
449
+ case 'product.quantity': return $first_product ? $first_product->getQuantity() : null;
450
+ case 'product.weight': return $first_product ? $first_product->getAttribute('weight') : null;
451
+ }
452
+ return isset($process['data'][$key]) ? $process['data'][$key] : null;
453
+ }
454
 
455
  protected function _prepareFormula($process, $row, $property_key, $formula_string, $is_checking, $use_cache=true)
456
  {
457
  if ($use_cache && isset($this->_formula_cache[$formula_string])) {
458
  $result = $this->_formula_cache[$formula_string];
459
+ $this->debug(' get cached formula <span class="osh-replacement">'.$formula_string.'</span> = <span class="osh-formula">'.self::toString($result->result).'</span>');
460
  return $result;
461
  }
462
 
464
  //$this->debug(' formula = <span class="osh-formula">'.$formula.'</span>');
465
 
466
  // foreach
467
+ while ($this->_preg_match("#{foreach {PRODUCT_REGEX}\.((?:{ATTRIBUTE_REGEX}|{OPTION_REGEX})\.(?:[a-z0-9_]+)|{CATEGORIES_REGEX}|{ATTRIBUTE_SET_REGEX})}(.*){/foreach}#i", $formula, $result)) {
468
  $original = $result[0];
469
+ if ($use_cache && array_key_exists($original, $this->_expression_cache)) {
470
+ $replacement = $this->_getCachedExpression($original);
 
471
  } else {
472
  $replacement = 0;
473
  if ($result[1]=='categories') {
479
  $categories_names = array();
480
  foreach ($categories as $category) {
481
  $key = $category->toString();
482
+ $categories_names[] = self::toString($key);
483
  $sel = isset($selections[$key]) ? $selections[$key] : null;
484
  $selections[$key]['products'][] = $product;
485
  $selections[$key]['weight'] = (isset($sel['weight']) ? $sel['weight'] : 0)+$product->getAttribute('weight')*$product->getQuantity();
488
  $this->debug(' products[<span class="osh-formula">'.$product->toString().'</span>].<span class="osh-key">categories</span> = array(<span class="osh-formula">'.join('</span>, <span class="osh-formula">', $categories_names).'</span>)');
489
  }
490
  $this->removeDebugIndent();
491
+ } else if ($result[1]=='attribute_set') {
492
+ $selections = array();
493
+ $this->debug(' <span class="osh-loop">prepare foreach <span class="osh-key">attribute_set</span></span>');
494
+ $this->addDebugIndent();
495
+ foreach ($process['cart.products'] as $product) {
496
+ $attribute_set = $product->getAttributeSet();
497
+ $key = $attribute_set->toString();
498
+ $sel = isset($selections[$key]) ? $selections[$key] : null;
499
+ $selections[$key]['products'][] = $product;
500
+ $selections[$key]['weight'] = (isset($sel['weight']) ? $sel['weight'] : 0)+$product->getAttribute('weight')*$product->getQuantity();
501
+ $selections[$key]['quantity'] = (isset($sel['quantity']) ? $sel['quantity'] : 0)+$product->getQuantity();
502
+ $this->debug(' products[<span class="osh-formula">'.$product->toString().'</span>].<span class="osh-key">attribute_set</span> = <span class="osh-formula">'.$attribute_set->toString().'</span>');
503
+ }
504
+ $this->removeDebugIndent();
505
  } else {
506
  list($filter_property_type, $filter_property_name) = explode('.', $result[1]);
507
  $selections = array();
509
  $this->addDebugIndent();
510
  foreach ($process['cart.products'] as $product) {
511
  $tmp_value = $this->_getProductProperty($product, $filter_property_type, $filter_property_name, $get_by_id=false);
512
+ $this->debug(' products[<span class="osh-formula">'.$product->toString().'</span>].<span class="osh-key">'.$filter_property_type.'</span>.<span class="osh-key">'.$filter_property_name.'</span> = <span class="osh-formula">'.self::toString($tmp_value).'</span>');
513
  $key = 'val_'.$tmp_value;
514
  $sel = isset($selections[$key]) ? $selections[$key] : null;
515
  $selections[$key]['products'][] = $product;
529
  $process2['data']['selection.weight'] = $selection['weight'];
530
  $process_result = $this->_processFormula($process2, $row, $property_key, $result[2], $is_checking, $tmp_use_cache=false);
531
  $replacement += $process_result->result;
532
+ $this->debug(' &raquo; <span class="osh-info">foreach sum result</span> = <span class="osh-formula">'.self::toString($replacement).'</span>');
533
  $this->removeDebugIndent();
534
  }
535
  $this->removeDebugIndent();
549
  $first_product = isset($process['cart.products'][0]) ? $process['cart.products'][0] : null;
550
  if (!isset($process['data']['selection.weight'])) $process['data']['selection.weight'] = $process['data']['cart.weight'];
551
  if (!isset($process['data']['selection.quantity'])) $process['data']['selection.quantity'] = $process['data']['cart.quantity'];
552
+
553
+ // Values loaded only if needed
554
  $process['data']['product.weight'] = 0;
555
  $process['data']['product.quantity'] = 0;
556
  $process['data']['product.category'] = null;
557
  $process['data']['product.category.id'] = null;
558
+ $process['data']['product.attribute_set'] = null;
559
+ $process['data']['product.attribute_set.id'] = null;
 
 
 
 
 
 
560
 
561
  $aliases = array(
562
  'p.' => 'product.',
564
  's.' => 'selection.',
565
  );
566
  foreach ($process['data'] as $original => $replacement) {
567
+ if (mb_strpos($formula, '{'.$original.'}')!==false) {
568
+ // Load value only if needed
569
+ $replacement = $this->_loadValue($process, $original);
570
+
571
+ // With strings auto-escape
572
+ $formula = $this->replace('{{'.$original.'}}', $this->_autoEscapeStrings($replacement), $formula);
573
+ // Without strings auto-escape
574
+ $formula = $this->replace('{'.$original.'}', $replacement, $formula);
575
+ }
576
  foreach ($aliases as $from => $to) {
577
+ if (mb_substr($original, 0, mb_strlen($to))==$to) {
578
+ $original2 = $from.mb_substr($original, mb_strlen($to), mb_strlen($original));
579
+ if (mb_strpos($formula, '{'.$original2.'}')!==false) {
580
+ // Load value only if needed
581
+ $replacement = $this->_loadValue($process, $original);
582
+
583
+ // With strings auto-escape
584
+ $formula = $this->replace('{{'.$original2.'}}', $this->_autoEscapeStrings($replacement), $formula);
585
+ // Without strings auto-escape
586
+ $formula = $this->replace('{'.$original2.'}', $replacement, $formula);
587
+ }
588
  }
589
  }
590
  }
610
  || $this->_preg_match("/{(sum|min|max|count distinct) {PRODUCT_REGEX}\.(quantity)()(?: where ([^}]+))?}/i", $formula, $result)
611
  ) {
612
  $original = $result[0];
613
+ if ($use_cache && array_key_exists($original, $this->_expression_cache)) {
614
+ $replacement = $this->_getCachedExpression($original);
 
615
  } else {
616
  $replacement = $this->_processProductProperty($process['cart.products'], $result);
617
  if ($use_cache) $this->setCache($result[0], $replacement);
622
  // switch
623
  while (preg_match("/{switch ([^}]+) in ([^}]+)}/i", $formula, $result)) {
624
  $original = $result[0];
625
+ if ($use_cache && array_key_exists($original, $this->_expression_cache)) {
626
+ $replacement = $this->_getCachedExpression($original);
 
627
  } else {
628
  $reference_value = $this->_evalFormula($result[1]);
629
  $fees_table_string = $result[2];
647
 
648
  if ($value=='*' || $reference_value===$value) {
649
  $replacement = $fee;
650
+ $this->debug(' compare <span class="osh-formula">'.self::toString($reference_value).'</span> and <span class="osh-formula">'.self::toString($value).'</span> = equals');
651
  break;
652
  }
653
+ $this->debug(' compare <span class="osh-formula">'.self::toString($reference_value).'</span> and <span class="osh-formula">'.self::toString($value).'</span> = not equals');
654
  }
655
+ //$replacement = self::toString($replacement);
656
  if ($use_cache) $this->setCache($original, $replacement);
657
  }
658
  $formula = $this->replace($original, $replacement, $formula);
661
  // range table
662
  while (preg_match("/{table ([^}]+) in ([0-9\.:,\*\[\] ]+)}/i", $formula, $result)) {
663
  $original = $result[0];
664
+ if ($use_cache && array_key_exists($original, $this->_expression_cache)) {
665
+ $replacement = $this->_getCachedExpression($original);
 
666
  } else {
667
  $reference_value = $this->_evalFormula($result[1]);
668
+ $replacement = null;
669
  if (isset($reference_value)) {
670
  $fees_table_string = $result[2];
671
 
676
  return $result;
677
  }
678
  $fees_table = explode(',', $fees_table_string);
 
 
679
  foreach ($fees_table as $item) {
680
  $fee_data = explode(':', $item);
681
 
695
  }
696
  }
697
  }
698
+ //$replacement = self::toString($replacement);
699
  if ($use_cache) $this->setCache($original, $replacement);
700
  }
701
  $formula = $this->replace($original, $replacement, $formula);
730
  );
731
  $eval_result = null;
732
  @eval('$eval_result = ('.$formula.');');
733
+ $this->debug(' evaluate <span class="osh-formula">'.$formula.'</span> = <span class="osh-replacement">'.self::toString($eval_result).'</span>');
734
  return $eval_result;
735
  }
736
 
1293
  } else if (mb_substr($code, 0, 1)=='/' && mb_substr($code, mb_strlen($code)-1, 1)=='/' && @preg_match($code, $address['postcode'])) {
1294
  $this->debug(' postcode <span class="osh-replacement">'.$address['postcode'].'</span> matches <span class="osh-formula">'.htmlentities($code).'</span>');
1295
  $in_array = true;
1296
+ } else if (mb_strpos($code, '*')!==false && preg_match('/^'.str_replace('*', '(?:.*)', $code).'$/', $address['postcode'])) {
1297
  $this->debug(' postcode <span class="osh-replacement">'.$address['postcode'].'</span> matches <span class="osh-formula">'.htmlentities($code).'</span>');
1298
  $in_array = true;
1299
  }
1332
  if (is_array($input)) {
1333
  $items = array();
1334
  foreach ($input as $v) {
1335
+ $items[] = isset($v) && (is_string($v) || empty($v)) ? "'".$input."'" : self::toString($v);
1336
  }
1337
  return 'array('.join(',', $items).')';
1338
  } else {
1339
+ return isset($input) && (is_string($input) || empty($input)) ? "'".$input."'" : self::toString($input);
1340
  }
1341
  }
1342
 
1389
  $property_regex_result[1] = 'categories';
1390
  if (!isset($properties[$key])) $properties[$key] = $property_regex_result;
1391
  }
1392
+ $this->_preg_match_all('/{PRODUCT_REGEX}\.({ATTRIBUTE_SET_REGEX})(?:\.(id))?/i', $conditions, $properties_regex_result);
1393
+ foreach ($properties_regex_result as $property_regex_result) {
1394
+ $key = $property_regex_result[0];
1395
+ $property_regex_result[1] = 'attribute_set';
1396
+ if (!isset($properties[$key])) $properties[$key] = $property_regex_result;
1397
+ }
1398
  $this->_preg_match_all('/{PRODUCT_REGEX}\.(quantity)/i', $conditions, $properties_regex_result);
1399
  foreach ($properties_regex_result as $property_regex_result) {
1400
  $key = $property_regex_result[0];
1411
  case 'quantity':
1412
  $value = $product->getQuantity();
1413
  break;
1414
+ case 'attribute_set':
1415
+ $get_by_id = isset($property[2]) && $property[2]=='id';
1416
+ $attribute_set = $product->getAttributeSet();
1417
+ $value = $attribute_set ? ($get_by_id ? $attribute_set->getId() : $attribute_set->getName()) : null;
1418
+ break;
1419
  case 'category':
1420
  $get_by_id = isset($property[2]) && $property[2]=='id';
1421
  $category = $product->getCategory();
1489
 
1490
  }
1491
 
1492
+ interface OS_AttributeSet {
1493
+ public function getName();
1494
+ public function getId();
1495
+ public function toString();
1496
+ }
1497
+
1498
  interface OS_Category {
1499
  public function getName();
1500
  public function getId();
1540
  }
1541
 
1542
  public function __toString() {
1543
+ return OwebiaShippingHelper::toString($this->result);
1544
  }
1545
  }
1546
 
app/locale/en_US/Owebia_Shipping2.csv CHANGED
@@ -99,8 +99,9 @@
99
  "Owebia Shipping 2 extension help","Owebia Shipping 2 extension help"
100
  "{os2editor.help.summary}","
101
  <h4>Summary</h4>
102
- <p>
103
- The english version of the documentation is not up to date. If you can read french, please use the french version.
 
104
  </p>
105
  <div class=""table-of-contents"">
106
  <ul>
99
  "Owebia Shipping 2 extension help","Owebia Shipping 2 extension help"
100
  "{os2editor.help.summary}","
101
  <h4>Summary</h4>
102
+ <p style=""color:red;font-weight:bold;"">
103
+ The english version of the documentation is not up to date. If you can read french, please use the french version.<br/>
104
+ I have not enough time to translate the documentation in english. If somebody wants to translate the documentation in english or in an other language, please contact owebia.
105
  </p>
106
  <div class=""table-of-contents"">
107
  <ul>
app/locale/fr_FR/Owebia_Shipping2.csv CHANGED
@@ -115,8 +115,8 @@
115
  <li><a href=""#"" onclick=""os2editor.help('more.copy');"">Faire une copie d'une propriété d'une autre méthode</a></li>
116
  <li><a href=""#"" onclick=""os2editor.help('more.tables');"">Utilisation des tables de tarifs</a></li>
117
  <li class=""new""><a href=""#"" onclick=""os2editor.help('more.switch');"">Utilisation des ""switch"" (tables de correspondance)</a> (depuis la version 2.4.5)</li>
118
- <li><a href=""#"" onclick=""os2editor.help('more.attributes-options');"">Utilisation des attributs ou des options des produits (sum, count, min, max)</a></li>
119
- <li><a href=""#"" onclick=""os2editor.help('more.foreach');"">Utilisation des boucles foreach</a></li>
120
  <li class=""new""><a href=""#"" onclick=""os2editor.help('more.categories');"">Utilisation des catégories dans les boucles foreach ou dans les fonctions spéciales</a> (depuis la version 2.4.2)</li>
121
  <li><a href=""#"" onclick=""os2editor.help('more.custom-variables');"">Utilisation des variables personnalisées de Magento (Custom Variables)</a></li>
122
  </ul>
@@ -571,7 +571,11 @@ Liste des préfixes possibles :
571
  Liste des propriétés possibles :
572
  </p>
573
  <ul>
574
- <li class=""new""><b>product.quantity :</b> quantité de l'article dans le panier</li>
 
 
 
 
575
  <li><b>product.attribute.* :</b> attribut<br/>Liste d'attributs intéressants :
576
  <ul>
577
  <li><b>sku :</b> la référence</li>
@@ -641,6 +645,10 @@ conditions: <span class=""string"">""{count products where product.attribute.col
641
  <ul>
642
  <li><b>{product.weight}</b>: poids de l'article sélectionné</li>
643
  <li><b>{product.quantity}</b>: quantité de l'article sélectionné</li>
 
 
 
 
644
  <li><b>{product.attribute.*}</b>: attribut de l'article sélectionné<br/>
645
  <span class=""new"">Quelques pseudos-attributs sont également disponibles pour faciliter certains calculs :
646
  <ul>
115
  <li><a href=""#"" onclick=""os2editor.help('more.copy');"">Faire une copie d'une propriété d'une autre méthode</a></li>
116
  <li><a href=""#"" onclick=""os2editor.help('more.tables');"">Utilisation des tables de tarifs</a></li>
117
  <li class=""new""><a href=""#"" onclick=""os2editor.help('more.switch');"">Utilisation des ""switch"" (tables de correspondance)</a> (depuis la version 2.4.5)</li>
118
+ <li class=""new""><a href=""#"" onclick=""os2editor.help('more.attributes-options');"">Utilisation des attributs ou des options des produits (sum, count, min, max)</a> (support des jeux d'attributs depuis la version 2.4.6)</li>
119
+ <li class=""new""><a href=""#"" onclick=""os2editor.help('more.foreach');"">Utilisation des boucles foreach</a> (support des jeux d'attributs depuis la version 2.4.6)</li>
120
  <li class=""new""><a href=""#"" onclick=""os2editor.help('more.categories');"">Utilisation des catégories dans les boucles foreach ou dans les fonctions spéciales</a> (depuis la version 2.4.2)</li>
121
  <li><a href=""#"" onclick=""os2editor.help('more.custom-variables');"">Utilisation des variables personnalisées de Magento (Custom Variables)</a></li>
122
  </ul>
571
  Liste des propriétés possibles :
572
  </p>
573
  <ul>
574
+ <li><b>product.quantity :</b> quantité de l'article dans le panier</li>
575
+ <li><b>product.category :</b> nom de la première catégorie du produit</li>
576
+ <li><b>product.category.id :</b> id de la première catégorie du produit</li>
577
+ <li class=""new""><b>product.attribute_set :</b> nom du jeu d'attributs</li>
578
+ <li class=""new""><b>product.attribute_set.id :</b> id du jeu d'attributs</li>
579
  <li><b>product.attribute.* :</b> attribut<br/>Liste d'attributs intéressants :
580
  <ul>
581
  <li><b>sku :</b> la référence</li>
645
  <ul>
646
  <li><b>{product.weight}</b>: poids de l'article sélectionné</li>
647
  <li><b>{product.quantity}</b>: quantité de l'article sélectionné</li>
648
+ <li><b>{product.category}</b>: nom de la première catégorie du produit</li>
649
+ <li><b>{product.category.id}</b>: id de la première catégorie du produit</li>
650
+ <li class=""new""><b>{product.attribute_set}</b>: nom du jeu d'attributs</li>
651
+ <li class=""new""><b>{product.attribute_set.id}</b>: id du jeu d'attributs</li>
652
  <li><b>{product.attribute.*}</b>: attribut de l'article sélectionné<br/>
653
  <span class=""new"">Quelques pseudos-attributs sont également disponibles pour faciliter certains calculs :
654
  <ul>
package.xml CHANGED
@@ -1,7 +1,7 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Owebia_Shipping_2</name>
4
- <version>2.4.5</version>
5
  <stability>stable</stability>
6
  <license uri="http://www.opensource.org/licenses/MIT">The MIT License (MIT)</license>
7
  <channel>community</channel>
@@ -10,15 +10,19 @@
10
  <description>[EN] This module provides 3 shipping modes configurable with a very flexible syntax. The first method of delivery allows by default the management of Colissimo, Chronopost and Export 3J.
11
 
12
  [FR] Ce module met &#xE0; disposition 3 modes de livraison configurables avec une syntaxe tr&#xE8;s souple. Le premier mode de livraison permet par d&#xE9;faut la gestion des modes de livraison Colissimo, Chronopost et Export 3J.</description>
13
- <notes>[2.4.5 - 12 janvier 2012]
14
- Ajout de la fonction switch
15
- Ajout d'une syntaxe pour auto-&#xE9;chapper les cha&#xEE;nes de caract&#xE8;res (ex: {{cart.coupon}} donnera null ou 'test' en fonction de la valeur de la variable)
16
- Dans le cas d'un produit configurable avec option personnalisable, on r&#xE9;cup&#xE8;re les options du produit parent et pas celles du produit enfant
17
- Mise &#xE0; jour de la documentation</notes>
 
 
 
 
18
  <authors><author><name>owebia</name><user>auto-converted</user><email>antoine.lemoine@owebia.com</email></author></authors>
19
- <date>2012-01-12</date>
20
- <time>16:06:03</time>
21
- <contents><target name="magelocale"><dir name="en_US"><file name="Owebia_Shipping2.csv" hash="4267e8feae738a7e06d06eed97d414fc"/></dir><dir name="fr_FR"><file name="Owebia_Shipping2.csv" hash="78dc3ec0caf31f499300c3d938e8edbb"/></dir></target><target name="mage"><dir name="js"><dir name="owebia"><dir name="shipping2"><file name="os2editor.css" hash="56bf6537741dec42f2d23883477ad1b7"/><file name="os2editor.js" hash="83f8726e9d8dc2edf8f9f00bb29d9045"/></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Owebia_Shipping2.xml" hash="586171bce13c5fb46298a7033f62bab6"/><file name="Owebia_Shipping_2.xml" hash="2f84a53934b37c860e25bc0c6217467f"/></dir></target><target name="magecommunity"><dir name="Owebia"><dir name="Shipping2"><dir name="Block"><dir name="Adminhtml"><dir name="System"><dir name="Config"><dir name="Form"><dir name="Field"><file name="Config.php" hash="7b274b9050875d714274531a3d7f0f53"/></dir></dir></dir></dir></dir></dir><dir name="Controller"><file name="Abstract.php" hash="9ddc7de1f825a865765faac63b065308"/></dir><dir name="controllers"><dir name="Checkout"><file name="CartController.php" hash="8c6ee136298e0e2dd0052143887282ce"/></dir><file name="AjaxController.php" hash="d033c5b278d6cb8e6e774a3c9873a2be"/></dir><dir name="etc"><file name="adminhtml.xml" hash="be7b084254925764ad58959c953d1a84"/><file name="config.xml" hash="da4e7dbab55a40a740b15a6b3de7c560"/><file name="system.xml" hash="03b293e729e515687335fc0a2192a628"/></dir><dir name="includes"><dir name="cache"><file name="countries" hash="6b1a5494b6dddcc65f2946dbf0226c29"/></dir><file name="OS2_AddressFilter.php" hash="fc94ad7b41dcac2bece6ae32cf2d56f1"/><file name="OS2_CustomerGroup.php" hash="17e2ef78299cc3fef9233315cb6eb2a6"/><file name="OwebiaShippingHelper.php" hash="36a38364f3a89b7391f276f377795e92"/></dir><dir name="Model"><dir name="Carrier"><file name="AbstractOwebiaShipping.php" hash="e4884534bd4140e86019e7560b2085a6"/><file name="OwebiaShipping1.php" hash="72a7cf31f9341a186169667ed33c525f"/><file name="OwebiaShipping2.php" hash="cb61efb5d144bf20aada0ea9faebbcb5"/><file name="OwebiaShipping3.php" hash="8da3a9e93a85083fd0f7d050991539be"/></dir></dir><file name="changelog" hash="24c7485dcf384f68fa6852d890b6580b"/></dir></dir></target></contents>
22
  <compatible/>
23
  <dependencies/>
24
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Owebia_Shipping_2</name>
4
+ <version>2.4.6</version>
5
  <stability>stable</stability>
6
  <license uri="http://www.opensource.org/licenses/MIT">The MIT License (MIT)</license>
7
  <channel>community</channel>
10
  <description>[EN] This module provides 3 shipping modes configurable with a very flexible syntax. The first method of delivery allows by default the management of Colissimo, Chronopost and Export 3J.
11
 
12
  [FR] Ce module met &#xE0; disposition 3 modes de livraison configurables avec une syntaxe tr&#xE8;s souple. Le premier mode de livraison permet par d&#xE9;faut la gestion des modes de livraison Colissimo, Chronopost et Export 3J.</description>
13
+ <notes>[2.4.6 - 19 janvier 2012]
14
+ Correction d'un bug dans l'utilisation de la fonction {table ... in ...} : lorsque la variable de r&#xE9;f&#xE9;rence est ind&#xE9;finie, le r&#xE9;sultat &#xE9;tait invalide (valeur pr&#xE9;c&#xE9;dente de la variable $replacement)
15
+ Correction d'un probl&#xE8;me avec les produits packag&#xE9;s (bundle product) : les produits 'bundle' et les produits 'simple' &#xE9;taient tous deux r&#xE9;cup&#xE9;r&#xE9;s ce qui faussait les r&#xE9;sultats
16
+ Support des sets d'attributs
17
+ product.attribute_set dans les conditions de boucle foreach
18
+ {product.attribute_set} et {product.attribute_set.id} comme variables dans les boucles foreach
19
+ product.attribute_set, product.attribute_set.id dans les conditions des op&#xE9;rations sum, count, min et max
20
+ Optimisation du chargement de certaines valeurs (cat&#xE9;gories, attribute set, ...)
21
+ Correction d'un probl&#xE8;me avec les castings successifs (string), (float) qui posent probl&#xE8;me lorsque la locale utilise la virgule comme s&#xE9;parateur de d&#xE9;cimales</notes>
22
  <authors><author><name>owebia</name><user>auto-converted</user><email>antoine.lemoine@owebia.com</email></author></authors>
23
+ <date>2012-01-19</date>
24
+ <time>15:51:25</time>
25
+ <contents><target name="magelocale"><dir name="en_US"><file name="Owebia_Shipping2.csv" hash="4e8a3f8dafc61de2e0286ce81ea57c0c"/></dir><dir name="fr_FR"><file name="Owebia_Shipping2.csv" hash="f42f7e4b27b254a18ea11799cea6aac6"/></dir></target><target name="mage"><dir name="js"><dir name="owebia"><dir name="shipping2"><file name="os2editor.css" hash="56bf6537741dec42f2d23883477ad1b7"/><file name="os2editor.js" hash="83f8726e9d8dc2edf8f9f00bb29d9045"/></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Owebia_Shipping2.xml" hash="586171bce13c5fb46298a7033f62bab6"/><file name="Owebia_Shipping_2.xml" hash="2f84a53934b37c860e25bc0c6217467f"/></dir></target><target name="magecommunity"><dir name="Owebia"><dir name="Shipping2"><dir name="Block"><dir name="Adminhtml"><dir name="System"><dir name="Config"><dir name="Form"><dir name="Field"><file name="Config.php" hash="7b274b9050875d714274531a3d7f0f53"/></dir></dir></dir></dir></dir></dir><dir name="Controller"><file name="Abstract.php" hash="9ddc7de1f825a865765faac63b065308"/></dir><dir name="controllers"><dir name="Checkout"><file name="CartController.php" hash="8c6ee136298e0e2dd0052143887282ce"/></dir><file name="AjaxController.php" hash="d033c5b278d6cb8e6e774a3c9873a2be"/></dir><dir name="etc"><file name="adminhtml.xml" hash="be7b084254925764ad58959c953d1a84"/><file name="config.xml" hash="da4e7dbab55a40a740b15a6b3de7c560"/><file name="system.xml" hash="03b293e729e515687335fc0a2192a628"/></dir><dir name="includes"><dir name="cache"><file name="countries" hash="6b1a5494b6dddcc65f2946dbf0226c29"/></dir><file name="OS2_AddressFilter.php" hash="fc94ad7b41dcac2bece6ae32cf2d56f1"/><file name="OS2_CustomerGroup.php" hash="17e2ef78299cc3fef9233315cb6eb2a6"/><file name="OwebiaShippingHelper.php" hash="ce0871c59c7424d0a4132ea3bb419531"/></dir><dir name="Model"><dir name="Carrier"><file name="AbstractOwebiaShipping.php" hash="c2ba9bbfa304229c830ecd0f2f3c1770"/><file name="OwebiaShipping1.php" hash="72a7cf31f9341a186169667ed33c525f"/><file name="OwebiaShipping2.php" hash="cb61efb5d144bf20aada0ea9faebbcb5"/><file name="OwebiaShipping3.php" hash="8da3a9e93a85083fd0f7d050991539be"/></dir></dir><file name="changelog" hash="ca18abfd6c265094b53bc60f88e4da83"/></dir></dir></target></contents>
26
  <compatible/>
27
  <dependencies/>
28
  </package>