Owebia_Shipping_2 - Version 2.4.5

Version Notes

[2.4.5 - 12 janvier 2012]
Ajout de la fonction switch
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)
Dans le cas d'un produit configurable avec option personnalisable, on récupère les options du produit parent et pas celles du produit enfant
Mise à jour de la documentation

Download this release

Release Info

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


Code changes from version 2.4.4 to 2.4.5

app/code/community/Owebia/Shipping2/Block/Adminhtml/System/Config/Form/Field/Config.php CHANGED
@@ -1,7 +1,7 @@
1
  <?php
2
 
3
  /**
4
- * Copyright (c) 2008-11 Owebia
5
  *
6
  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
7
  * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
1
  <?php
2
 
3
  /**
4
+ * Copyright (c) 2008-12 Owebia
5
  *
6
  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
7
  * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
app/code/community/Owebia/Shipping2/Controller/Abstract.php CHANGED
@@ -1,7 +1,7 @@
1
  <?php
2
 
3
  /**
4
- * Copyright (c) 2008-11 Owebia
5
  *
6
  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
7
  * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
1
  <?php
2
 
3
  /**
4
+ * Copyright (c) 2008-12 Owebia
5
  *
6
  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
7
  * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
app/code/community/Owebia/Shipping2/Model/Carrier/AbstractOwebiaShipping.php CHANGED
@@ -1,7 +1,7 @@
1
  <?php
2
 
3
  /**
4
- * Copyright (c) 2008-11 Owebia
5
  *
6
  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
7
  * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
@@ -67,7 +67,7 @@ class Magento_Product implements OS_Product {
67
 
68
  private function getProductOptions() {
69
  if (isset($this->options)) return $this->options;
70
- $item = $this->cart_item;
71
  $options = array();
72
  if ($optionIds = $item->getOptionByCode('option_ids')) {
73
  foreach (explode(',', $optionIds->getValue()) as $optionId) {
1
  <?php
2
 
3
  /**
4
+ * Copyright (c) 2008-12 Owebia
5
  *
6
  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
7
  * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
67
 
68
  private function getProductOptions() {
69
  if (isset($this->options)) return $this->options;
70
+ $item = isset($this->parent_cart_item) ? $this->parent_cart_item : $this->cart_item; // For configurable products with options
71
  $options = array();
72
  if ($optionIds = $item->getOptionByCode('option_ids')) {
73
  foreach (explode(',', $optionIds->getValue()) as $optionId) {
app/code/community/Owebia/Shipping2/Model/Carrier/OwebiaShipping1.php CHANGED
@@ -1,7 +1,7 @@
1
  <?php
2
 
3
  /**
4
- * Copyright (c) 2008-11 Owebia
5
  *
6
  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
7
  * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
1
  <?php
2
 
3
  /**
4
+ * Copyright (c) 2008-12 Owebia
5
  *
6
  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
7
  * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
app/code/community/Owebia/Shipping2/Model/Carrier/OwebiaShipping2.php CHANGED
@@ -1,7 +1,7 @@
1
  <?php
2
 
3
  /**
4
- * Copyright (c) 2008-11 Owebia
5
  *
6
  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
7
  * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
1
  <?php
2
 
3
  /**
4
+ * Copyright (c) 2008-12 Owebia
5
  *
6
  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
7
  * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
app/code/community/Owebia/Shipping2/Model/Carrier/OwebiaShipping3.php CHANGED
@@ -1,7 +1,7 @@
1
  <?php
2
 
3
  /**
4
- * Copyright (c) 2008-11 Owebia
5
  *
6
  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
7
  * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
1
  <?php
2
 
3
  /**
4
+ * Copyright (c) 2008-12 Owebia
5
  *
6
  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
7
  * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
app/code/community/Owebia/Shipping2/changelog CHANGED
@@ -1,3 +1,9 @@
 
 
 
 
 
 
1
  [2.4.4 - 30 novembre 2011]
2
  Correction d'un bug avec l'utilisation de product.category.id
3
  Ajout des valeurs memory_limit et memory_usage dans le debug
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)
4
+ Dans le cas d'un produit configurable avec option personnalisable, on r�cup�re les options du produit parent et pas celles du produit enfant
5
+ Mise � jour de la documentation
6
+
7
  [2.4.4 - 30 novembre 2011]
8
  Correction d'un bug avec l'utilisation de product.category.id
9
  Ajout des valeurs memory_limit et memory_usage dans le debug
app/code/community/Owebia/Shipping2/controllers/AjaxController.php CHANGED
@@ -1,7 +1,7 @@
1
  <?php
2
 
3
  /**
4
- * Copyright (c) 2008-11 Owebia
5
  *
6
  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
7
  * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
1
  <?php
2
 
3
  /**
4
+ * Copyright (c) 2008-12 Owebia
5
  *
6
  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
7
  * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
app/code/community/Owebia/Shipping2/etc/adminhtml.xml CHANGED
@@ -1,7 +1,7 @@
1
  <?xml version="1.0" ?>
2
  <!--
3
  /**
4
- * Copyright (c) 2008-11 Owebia
5
  *
6
  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
7
  * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
1
  <?xml version="1.0" ?>
2
  <!--
3
  /**
4
+ * Copyright (c) 2008-12 Owebia
5
  *
6
  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
7
  * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
app/code/community/Owebia/Shipping2/etc/config.xml CHANGED
@@ -1,7 +1,7 @@
1
  <?xml version="1.0"?>
2
  <!--
3
  /**
4
- * Copyright (c) 2008-11 Owebia
5
  *
6
  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
7
  * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
@@ -22,7 +22,7 @@
22
  <config>
23
  <modules>
24
  <Owebia_Shipping2>
25
- <version>2.4.4</version>
26
  <depends>
27
  <Mage_Shipping />
28
  </depends>
1
  <?xml version="1.0"?>
2
  <!--
3
  /**
4
+ * Copyright (c) 2008-12 Owebia
5
  *
6
  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
7
  * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
22
  <config>
23
  <modules>
24
  <Owebia_Shipping2>
25
+ <version>2.4.5</version>
26
  <depends>
27
  <Mage_Shipping />
28
  </depends>
app/code/community/Owebia/Shipping2/etc/system.xml CHANGED
@@ -1,7 +1,7 @@
1
  <?xml version="1.0"?>
2
  <!--
3
  /**
4
- * Copyright (c) 2008-11 Owebia
5
  *
6
  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
7
  * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
1
  <?xml version="1.0"?>
2
  <!--
3
  /**
4
+ * Copyright (c) 2008-12 Owebia
5
  *
6
  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
7
  * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
app/code/community/Owebia/Shipping2/includes/OS2_AddressFilter.php CHANGED
@@ -1,7 +1,7 @@
1
  <?php
2
 
3
  /**
4
- * Copyright (c) 2008-11 Owebia
5
  *
6
  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
7
  * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
1
  <?php
2
 
3
  /**
4
+ * Copyright (c) 2008-12 Owebia
5
  *
6
  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
7
  * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
app/code/community/Owebia/Shipping2/includes/OS2_CustomerGroup.php CHANGED
@@ -1,7 +1,7 @@
1
  <?php
2
 
3
  /**
4
- * Copyright (c) 2008-11 Owebia
5
  *
6
  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
7
  * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
1
  <?php
2
 
3
  /**
4
+ * Copyright (c) 2008-12 Owebia
5
  *
6
  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
7
  * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
app/code/community/Owebia/Shipping2/includes/OwebiaShippingHelper.php CHANGED
@@ -1,7 +1,7 @@
1
  <?php
2
 
3
  /**
4
- * Copyright (c) 2008-11 Owebia
5
  *
6
  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
7
  * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
@@ -62,8 +62,8 @@ class OwebiaShippingHelper
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() {
@@ -104,12 +104,12 @@ class OwebiaShippingHelper
104
  'store.address' => '',
105
  'store.phone' => '',
106
  'date.timestamp' => $timestamp,
107
- 'date.year' => (int)date('Y',$timestamp),
108
- 'date.month' => (int)date('m',$timestamp),
109
- 'date.day' => (int)date('d',$timestamp),
110
- 'date.hour' => (int)date('H',$timestamp),
111
- 'date.minute' => (int)date('i',$timestamp),
112
- 'date.second' => (int)date('s',$timestamp),
113
  );
114
  return $properties;
115
  }
@@ -162,7 +162,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;
@@ -178,7 +178,7 @@ class OwebiaShippingHelper
178
  return $messages;
179
  }
180
 
181
- public function formatConfig($compress,$keys_to_remove=array()) {
182
  $output = '';
183
  foreach ($this->_config as $code => $row) {
184
  if (!isset($row['lines'])) {
@@ -187,18 +187,18 @@ class OwebiaShippingHelper
187
  }
188
  $output .= '{'.($compress ? '' : "\n");
189
  foreach ($row as $key => $property) {
190
- if (substr($key,0,1)!='*' && !in_array($key,$keys_to_remove)) {
191
  $value = $property['value'];
192
  if (isset($property['comment'])) $output .= ($compress ? '' : "\t").'/* '.$property['comment'].' */'.($compress ? '' : "\n");
193
  $output .= ($compress ? '' : "\t").$key.':'.($compress ? '' : ' ');
194
  if (is_bool($value)) $output .= $value ? 'true' : 'false';
195
  else if ((string)((int)$value)==$value) $output .= $value;
196
  else if ((string)((float)$value)==$value) $output .= ($compress ? (float)$value : $value);
197
- else $output .= '"'.str_replace('"','\\"',$value).'"';
198
  $output .= ','.($compress ? '' : "\n");
199
  }
200
  }
201
- if ($compress) $output = preg_replace('/,$/','',$output);
202
  $output .= "}\n".($compress ? '' : "\n");
203
  } else {
204
  $output .= $row['lines']."\n";
@@ -216,9 +216,9 @@ class OwebiaShippingHelper
216
  'result' => null,
217
  );
218
  foreach ($this->_config as $code => &$row) {
219
- $this->processRow($process,$row,$check_all_conditions=true);
220
  foreach ($row as $property_key => $property_value) {
221
- if (substr($property_key,0,1)!='*') $this->getRowProperty($row,$property_key);
222
  }
223
  }
224
  }
@@ -229,55 +229,55 @@ class OwebiaShippingHelper
229
  $this->debug('process row <span class="osh-key">'.$row['*code'].'</span>');
230
  if (!isset($row['label']['value'])) $row['label']['value'] = '***';
231
 
232
- $enabled = $this->getRowProperty($row,'enabled');
233
  if (isset($enabled)) {
234
  if (!$is_checking && !$enabled) {
235
- $this->addMessage('info',$row,'enabled','Configuration disabled');
236
  return new OS_Result(false);
237
  }
238
  }
239
 
240
- $conditions = $this->getRowProperty($row,'conditions');
241
  if (isset($conditions)) {
242
- $result = $this->_processFormula($process,$row,'conditions',$conditions,$is_checking);
243
  if (!$is_checking) {
244
  if (!$result->success) return $result;
245
  if (!$result->result) {
246
- $this->addMessage('info',$row,'conditions',"The cart doesn't match conditions");
247
  return new OS_Result(false);
248
  }
249
  }
250
  }
251
 
252
- $destination = $this->getRowProperty($row,'destination');
253
  if (isset($destination)) {
254
- $destination_match = $this->_addressMatch($destination,array(
255
  'country_code' => $process['data']['destination.country.code'],
256
  'region_code' => $process['data']['destination.region.code'],
257
  'postcode' => $process['data']['destination.postcode']
258
  ));
259
  if (!$is_checking && !$destination_match) {
260
- $this->addMessage('info',$row,'destination',"The shipping method doesn't cover the zone");
261
  return new OS_Result(false);
262
  }
263
  }
264
 
265
- $origin = $this->getRowProperty($row,'origin');
266
  if (isset($origin)) {
267
- $origin_match = $this->_addressMatch($origin,array(
268
  'country_code' => $process['data']['origin.country.code'],
269
  'region_code' => $process['data']['origin.region.code'],
270
  'postcode' => $process['data']['origin.postcode']
271
  ));
272
  if (!$is_checking && !$origin_match) {
273
- $this->addMessage('info',$row,'origin',"The shipping method doesn't match to shipping origin");
274
  return new OS_Result(false);
275
  }
276
  }
277
 
278
- $customer_groups = $this->getRowProperty($row,'customer_groups');
279
  if (isset($customer_groups)) {
280
- $groups = explode(',',$customer_groups);
281
  $group_match = false;
282
  //$this->debug('code:'.$process['data']['customer.group.code'].', id:'.$process['data']['customer.group.id']);
283
  foreach ($groups as $group) {
@@ -290,17 +290,17 @@ class OwebiaShippingHelper
290
  }
291
  }
292
  if (!$is_checking && !$group_match) {
293
- $this->addMessage('info',$row,'customer_groups',"The shipping method doesn't match to customer group (%s)",$process['data']['customer.group.code']);
294
  return new OS_Result(false);
295
  }
296
  }
297
 
298
- $fees = $this->getRowProperty($row,'fees');
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);
306
  }
@@ -309,32 +309,32 @@ class OwebiaShippingHelper
309
  $property = null;
310
  $output = null;
311
  if (isset($original_row) && isset($original_key) && $original_row['*code']==$row['*code'] && $original_key==$key) {
312
- $this->addMessage('error',$row,$key,'Infinite loop %s',"<span class=\"code\">{".$row['*code'].'.'.$key."}</span>");
313
  return array('error' => 'Infinite loop');
314
  }
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;
322
- if (!in_array($ref_code,array('module','date','store','cart','product','selection','customvar'))) {
323
  if ($ref_code==$row['code']['value'] && $ref_key==$key) {
324
- $this->addMessage('error',$row,$key,'Infinite loop %s',"<span class=\"code\">".$original."</span>");
325
  return null;
326
  }
327
  if (isset($this->_config[$ref_code][$ref_key]['value'])) {
328
- $replacement = $this->getRowProperty($this->_config[$ref_code],$ref_key,
329
- isset($original_row) ? $original_row : $row,isset($original_key) ? $original_key : $key);
330
  if (is_array($replacement) && isset($replacement['error'])) {
331
  return isset($original_row) ? $replacement : 'false';
332
  }
333
  } else {
334
- //$this->addMessage('error',$row,$key,'Non-existent property %s',"<span class=\"code\">".$original."</span>");
335
  $replacement = $original;//'null';
336
  }
337
- $output = $this->replace($original,$replacement,$output);
338
  }
339
  }
340
  } else {
@@ -351,11 +351,11 @@ class OwebiaShippingHelper
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
 
361
  protected function _min() {
@@ -378,23 +378,23 @@ class OwebiaShippingHelper
378
 
379
  protected function _processFormula($process, &$row, $property_key, $formula_string, $is_checking, $use_cache=true)
380
  {
381
- $result = $this->_prepareFormula($process,$row,$property_key,$formula_string,$is_checking,$use_cache);
382
  if (!$result->success) return $result;
383
 
384
  $eval_result = $this->_evalFormula($result->result);
385
  if (!isset($eval_result)) {
386
- $this->addMessage('error',$row,$property_key,'Invalid formula');
387
  $result = new OS_Result(false);
388
- if ($use_cache) $this->setCache($formula_string,$result);
389
  return $result;
390
  }
391
- $result = new OS_Result(true,$eval_result);
392
- if ($use_cache) $this->setCache($formula_string,$result);
393
  return $result;
394
  }
395
 
396
  public function evalInput($process, $row, $property_key, $input) {
397
- $result = $this->_prepareFormula($process,$row,$property_key,$input,$is_checking=false,$use_cache=true);
398
  return $result->success ? $result->result : $input;
399
  }
400
 
@@ -470,12 +470,12 @@ class OwebiaShippingHelper
470
  }
471
  $this->removeDebugIndent();
472
  } else {
473
- list($filter_property_type,$filter_property_name) = explode('.',$result[1]);
474
  $selections = array();
475
  $this->debug(' foreach <span class="osh-key">'.$filter_property_type.'</span>.<span class="osh-key">'.$filter_property_name.'</span>');
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;
@@ -494,23 +494,23 @@ class OwebiaShippingHelper
494
  $process2['cart.products'] = $selection['products'];
495
  $process2['data']['selection.quantity'] = $selection['quantity'];
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();
503
  $this->debug(' <span class="osh-loop">end</span>');
504
- if ($use_cache) $this->setCache($original,$replacement);
505
  }
506
- $formula = $this->replace($original,$replacement,$formula);
507
  }
508
 
509
  // customvar, variables
510
  while ($this->_preg_match("#{customvar\.([a-z0-9_]+)}#i", $formula, $result)) {
511
  $original = $result[0];
512
  $replacement = isset($process['store_interface']) ? $process['store_interface']->getCustomVar($result[1]) : null;
513
- $formula = $this->replace($original,$replacement,$formula);
514
  }
515
 
516
  $first_product = isset($process['cart.products'][0]) ? $process['cart.products'][0] : null;
@@ -535,17 +535,32 @@ class OwebiaShippingHelper
535
  's.' => 'selection.',
536
  );
537
  foreach ($process['data'] as $original => $replacement) {
 
 
 
538
  $formula = $this->replace('{'.$original.'}', $replacement, $formula);
539
  foreach ($aliases as $from => $to) {
540
- if (substr($original,0,strlen($to))==$to) $formula = $this->replace('{'.$from.substr($original,strlen($to),strlen($original)).'}', $replacement, $formula);
 
 
 
 
 
541
  }
542
  }
543
 
544
  if (isset($first_product)) {
545
- while ($this->_preg_match("#{{PRODUCT_REGEX}\.({ATTRIBUTE_REGEX}|{OPTION_REGEX}|stock)\.([a-z0-9_+-]+)}#i",$formula,$result)) {
 
 
 
 
 
 
 
546
  $original = $result[0];
547
  $replacement = $this->_getProductProperty($first_product, $result[1], $result[2], $get_by_id=false);
548
- $formula = $this->replace($original,$replacement,$formula);
549
  }
550
  }
551
 
@@ -559,14 +574,54 @@ class OwebiaShippingHelper
559
  $replacement = $this->_expression_cache[$original];
560
  $this->debug(' get cached expression <span class="osh-replacement">'.$original.'</span> = <span class="osh-formula">'.$replacement.'</span>');
561
  } else {
562
- $replacement = $this->_processProductProperty($process['cart.products'],$result);
563
- if ($use_cache) $this->setCache($result[0],$replacement);
564
  }
565
- $formula = $this->replace($original,$replacement,$formula);
566
  }
567
 
568
- // table
569
- while (preg_match("/{table ([^}]+) in ([0-9\.:,\*\[\] ]+)}/i",$formula,$result)) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
570
  $original = $result[0];
571
  if ($use_cache && isset($this->_expression_cache[$original])) {
572
  $replacement = $this->_expression_cache[$original];
@@ -576,17 +631,17 @@ class OwebiaShippingHelper
576
  if (isset($reference_value)) {
577
  $fees_table_string = $result[2];
578
 
579
- if (!preg_match('#^'.self::COUPLE_REGEX.'(?:, *'.self::COUPLE_REGEX.')*$#',$fees_table_string)) {
580
- $this->addMessage('error',$row,$property_key,'Error in table %s','<span class="osh-formula">'.htmlentities($result[0]).'</span>');
581
  $result = new OS_Result(false);
582
- if ($use_cache) $this->setCache($formula_string,$result);
583
  return $result;
584
  }
585
- $fees_table = explode(',',$fees_table_string);
586
 
587
  $replacement = null;
588
  foreach ($fees_table as $item) {
589
- $fee_data = explode(':',$item);
590
 
591
  $fee = trim($fee_data[1]);
592
  $max_value = trim($fee_data[0]);
@@ -596,7 +651,7 @@ class OwebiaShippingHelper
596
  else if ($last_char==']') $including_max_value = true;
597
  else $including_max_value = true;
598
 
599
- $max_value = str_replace(array('[',']'),'',$max_value);
600
 
601
  if ($max_value=='*' || $including_max_value && $reference_value<=$max_value || !$including_max_value && $reference_value<$max_value) {
602
  $replacement = $fee;
@@ -605,11 +660,11 @@ class OwebiaShippingHelper
605
  }
606
  }
607
  $replacement = $this->_toString($replacement);
608
- if ($use_cache) $this->setCache($original,$replacement);
609
  }
610
- $formula = $this->replace($original,$replacement,$formula);
611
  }
612
- $result = new OS_Result(true,$formula);
613
  return $result;
614
  }
615
 
@@ -617,7 +672,7 @@ class OwebiaShippingHelper
617
  if (is_bool($formula)) return $formula;
618
  if (!preg_match('/^(?:E|floor|ceil|round|max|min|rand|pow|pi|sqrt|log|exp|abs|int|float|true|false|null|and|or|in|substr|strtolower'
619
  .'|in_array\((?:\'(?:[^\']*)\'|(?:[^\']*)), *array\( *(?:(?:\'(?:[^\']+)\'|(?:[^\']+)) *(?: *, *(?:\'(?:[^\']+)\'|(?:[^\']+)))* *)?\) *\)'
620
- .'|\'[^\']*\'|[0-9,\'\.\-\(\)\*\/\?\:\+\<\>\=\&\|%! ])*$/',$formula)) {
621
  $errors = array(
622
  PREG_NO_ERROR => 'PREG_NO_ERROR',
623
  PREG_INTERNAL_ERROR => 'PREG_INTERNAL_ERROR',
@@ -633,8 +688,8 @@ class OwebiaShippingHelper
633
  return null;
634
  }
635
  $formula = str_replace(
636
- array('min','max'),
637
- array('$this->_min','$this->_max'),
638
  $formula
639
  );
640
  $eval_result = null;
@@ -644,9 +699,9 @@ class OwebiaShippingHelper
644
  }
645
 
646
  protected function _getOptionsAndData($string) {
647
- if (preg_match('/^(\\s*\(\\s*([^\] ]*)\\s*\)\\s*)/',$string,$result)) {
648
  $options = $result[2];
649
- $data = str_replace($result[1],'',$string);
650
  } else {
651
  $options = '';
652
  $data = $string;
@@ -659,27 +714,27 @@ class OwebiaShippingHelper
659
 
660
  public function compress($input) {
661
  /*
662
- if (preg_match_all("/{table (.*) in (".self::COUPLE_REGEX."(?:, *".self::COUPLE_REGEX.")*)}/imsU",$input,$result,PREG_SET_ORDER)) {
663
  foreach ($result as $result_i) {
664
- $fees_table = explode(',',$result_i[2]);
665
  $value = null;
666
  foreach ($fees_table as $index => $item) {
667
- list($max_value,$fee) = explode(':',$item);
668
  $last_char = $max_value{strlen($max_value)-1};
669
- if (in_array($last_char,array('[',']'))) {
670
  $including_char = $last_char;
671
- $max_value = str_replace(array('[',']'),'',$max_value);
672
  } else $including_char = '';
673
  $fees_table[$index] = ((float)$max_value).$including_char.':'.((float)$fee);
674
  }
675
- $input = str_replace($result_i[2],implode(',',$fees_table),$input);
676
- $input = str_replace($result_i[1],trim($result_i[1]),$input);
677
  }
678
  }
679
- if (preg_match_all("#{foreach ([^}]*)}(.*){/foreach}#imsU",$input,$result,PREG_SET_ORDER)) {
680
  foreach ($result as $result_i) {
681
- $input = str_replace($result_i[1],trim($result_i[1]),$input);
682
- $input = str_replace($result_i[2],trim($result_i[2]),$input);
683
  }
684
  }
685
  */
@@ -696,37 +751,37 @@ class OwebiaShippingHelper
696
  }
697
 
698
  public function uncompress($input) {
699
- if (substr($input,0,4)=='gz64' && function_exists('gzuncompress') && function_exists('base64_decode')) {
700
- $input = gzuncompress(base64_decode(substr($input,4,strlen($input))));
701
  }
702
 
703
  /*
704
- if (preg_match_all("/{table (.*) in (".self::COUPLE_REGEX."(?:, *".self::COUPLE_REGEX.")*)}/iU",$input,$result,PREG_SET_ORDER)) {
705
  foreach ($result as $result_i) {
706
- $fees_table = explode(',',$result_i[2]);
707
  $value = null;
708
  foreach ($fees_table as $index => $item) {
709
- list($max_value,$fee) = explode(':',$item);
710
  $last_char = $max_value{strlen($max_value)-1};
711
- if (in_array($last_char,array('[',']'))) {
712
  $including_char = $last_char;
713
- $max_value = str_replace(array('[',']'),'',$max_value);
714
  } else $including_char = '';
715
  $max_value = (float)$max_value;
716
  $fee = (float)$fee;
717
- $new_max_value = number_format($max_value,2,'.','');
718
- $new_fee = number_format($fee,2,'.','');
719
  $fees_table[$index] = (((float)$new_max_value)==$max_value ? $new_max_value : $max_value).$including_char.':'
720
  .(((float)$new_fee)==$fee ? $new_fee : $fee);
721
  }
722
- $input = str_replace($result_i[2],implode(', ',$fees_table),$input);
723
- $input = str_replace($result_i[1],trim($result_i[1]),$input);
724
  }
725
  }
726
- if (preg_match_all("#{foreach ([^}]*)}(.*){/foreach}#iU",$input,$result,PREG_SET_ORDER)) {
727
  foreach ($result as $result_i) {
728
- $input = str_replace($result_i[1],trim($result_i[1]),$input);
729
- $input = str_replace($result_i[2],trim($result_i[2]),$input);
730
  }
731
  }
732
  */
@@ -738,76 +793,76 @@ class OwebiaShippingHelper
738
  }
739
 
740
  public function parseProperty($input) {
741
- $value = $input==='false' || $input==='true' ? $input=='true' : str_replace('\"','"',preg_replace('/^(?:"|\')(.*)(?:"|\')$/s','$1',$input));
742
  return $value==='' ? null : $value;
743
  }
744
 
745
  public function cleanProperty(&$row, $key) {
746
  $input = $row[$key]['value'];
747
  if (is_string($input)) {
748
- $input = str_replace(array("\n"),array(''),$input);
749
- while (preg_match('/({TABLE |{SUM |{COUNT | DISTINCT | IN )/',$input,$resi)) {
750
- $input = str_replace($resi[0],strtolower($resi[0]),$input);
751
  }
752
 
753
- while (preg_match('/{{customVar code=([a-zA-Z0-9_-]+)}}/',$input,$resi)) {
754
- $input = str_replace($resi[0],'{customvar.'.$resi[1].'}',$input);
755
  }
756
 
757
  $regex = "{(weight|products_quantity|price_including_tax|price_excluding_tax|country)}";
758
- if (preg_match('/'.$regex.'/',$input,$resi)) {
759
- $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
760
- while (preg_match('/'.$regex.'/',$input,$resi)) {
761
  switch ($resi[1]) {
762
  case 'price_including_tax':
763
  case 'price_excluding_tax':
764
  case 'weight':
765
- $input = str_replace($resi[0],"{cart.".$resi[1]."}",$input);
766
  break;
767
- case 'products_quantity': $input = str_replace($resi[0],"{cart.quantity}",$input); break;
768
- case 'country': $input = str_replace($resi[0],"{destination.country.name}",$input); break;
769
  }
770
  }
771
  }
772
 
773
  $regex1 = "{copy '([a-zA-Z0-9_]+)'\.'([a-zA-Z0-9_]+)'}";
774
- if (preg_match('/'.$regex1.'/',$input,$resi)) {
775
- $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
776
- while (preg_match('/'.$regex1.'/',$input,$resi)) $input = str_replace($resi[0],'{'.$resi[1].'.'.$resi[2].'}',$input);
777
  }
778
 
779
  $regex1 = "{(count|all|any) (attribute|option) '([^'\)]+)' ?((?:==|<=|>=|<|>|!=) ?(?:".self::FLOAT_REGEX."|true|false|'[^'\)]*'))}";
780
  $regex2 = "{(sum) (attribute|option) '([^'\)]+)'}";
781
- if (preg_match('/'.$regex1.'/',$input,$resi) || preg_match('/'.$regex2.'/',$input,$resi)) {
782
- $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
783
- while (preg_match('/'.$regex1.'/',$input,$resi) || preg_match('/'.$regex2.'/',$input,$resi)) {
784
  switch ($resi[1]) {
785
- case 'count': $input = str_replace($resi[0],"{count products where product.".$resi[2]."s.".$resi[3].$resi[4]."}",$input); break;
786
- case 'all': $input = str_replace($resi[0],"{count products where product.".$resi[2]."s.".$resi[3].$resi[4]."}=={products_quantity}",$input); break;
787
- case 'any': $input = str_replace($resi[0],"{count products where product.".$resi[2]."s.".$resi[3].$resi[4]."}>0",$input); break;
788
- case 'sum': $input = str_replace($resi[0],"{sum product.".$resi[2].".".$resi[3]."}",$input); break;
789
  }
790
  }
791
  }
792
 
793
  $regex = "((?:{| )product.(?:attribute|option))s.";
794
- if (preg_match('/'.$regex.'/',$input,$resi)) {
795
- $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
796
- while (preg_match('/'.$regex.'/',$input,$resi)) {
797
- $input = str_replace($resi[0],$resi[1].'.',$input);
798
  }
799
  }
800
 
801
  $regex = "{table '([^']+)' (".self::COUPLE_REGEX."(?:, *".self::COUPLE_REGEX.")*)}";
802
- if (preg_match('/'.$regex.'/',$input,$resi)) {
803
- $this->addMessage('warning',$row,$key,'Usage of deprecated syntax %s','<span class="osh-formula">'.$resi[0].'</span>');
804
- while (preg_match('/'.$regex.'/',$input,$resi)) {
805
  switch ($resi[1]) {
806
  case 'products_quantity':
807
- $input = str_replace($resi[0],"{table {cart.weight} in ".$resi[2]."}*{cart.quantity}",$input);
808
  break;
809
  default:
810
- $input = str_replace($resi[0],"{table {cart.".$resi[1]."} in ".$resi[2]."}",$input);
811
  break;
812
  }
813
  }
@@ -818,18 +873,18 @@ class OwebiaShippingHelper
818
 
819
  protected function _parseInput() {
820
  $config_string = str_replace(
821
- array('&gt;','&lt;','“','”',utf8_encode(chr(147)),utf8_encode(chr(148)),'&laquo;','&raquo;',"\r\n","\t"),
822
- array('>','<','"','"','"','"','"','"',"\n",' '),
823
  $this->_input
824
  );
825
 
826
- if (substr($config_string,0,2)=='$$') $config_string = $this->uncompress(substr($config_string,2,strlen($config_string)));
827
 
828
  //echo ini_get('pcre.backtrack_limit');
829
  //exit;
830
 
831
  $row_regex = ' *([a-z0-9_]+)\\s*:\\s*("(?:(?:[^"]|\\\\")*[^\\\\])?"|'.self::FLOAT_REGEX.'|false|true)\\s*(,)? *(?:\\n)?';
832
- if (!preg_match_all('/((?:#+[^{\\n]*\\s+)*)\\s*(#)?{\\s*('.$row_regex.')+\\s*}/i',$config_string,$result,PREG_SET_ORDER)) {
833
  $errors = array(
834
  PREG_NO_ERROR => 'PREG_NO_ERROR',
835
  PREG_INTERNAL_ERROR => 'PREG_INTERNAL_ERROR',
@@ -845,10 +900,10 @@ class OwebiaShippingHelper
845
 
846
  $this->_config = array();
847
  $available_keys = array(
848
- 'code','label','enabled','description','fees','conditions','destination','origin','customer_groups','tracking_url',
849
- 'fees_table','fees_formula','fixed_fees','reference_value',
850
- 'prices_range','weights_range','product_properties',
851
- 'free_shipping__fees_table','free_shipping__fees_formula','free_shipping__fixed_fees','free_shipping__label',
852
  );
853
 
854
  foreach ($result as $block) {
@@ -857,39 +912,39 @@ class OwebiaShippingHelper
857
  $missing_semicolon = array();
858
  $obsolete_disabling_method = array();
859
 
860
- //$before = strstr($config_string,$block[0],true); // Seulement compatible avec PHP 5.3.0
861
- list($before) = explode($block[0],$config_string,2);
862
  if ($before!==false && trim($before)!='') {
863
- $config_string = substr($config_string,strlen($before));
864
  $this->_addIgnoredLines(trim($before));
865
  $row = null;
866
- $this->addMessage('info',$row,null,'Ignored lines %s','<div class="code">'.trim($before).'</div>');
867
  }
868
 
869
  $config_string = str_replace($block[0], '', $config_string);
870
- preg_match_all('/'.$row_regex.'/i',$block[0],$result2,PREG_SET_ORDER);
871
  $block_string = $block[0];
872
 
873
  $row = array();
874
  $i = 1;
875
  foreach ($result2 as $data) {
876
  $key = $data[1];
877
- if (in_array($key,$available_keys) || substr($key,0,1)=='_') {
878
  $property = $this->parseProperty($data[2]);
879
  if (isset($property)) {
880
  $row[$key] = array('value' => $property, 'original_value' => $property);
881
- $this->cleanProperty($row,$key);
882
  }
883
  if ($i>2) {
884
- $block_string = str_replace($data[0],$i==3 ? "...\n" : '',$block_string);
885
  }
886
  if ($i!=count($result2) && !isset($data[3]) || isset($data[3]) && $data[3]!=',') {
887
- if (preg_match('/^("|\')(.{40})(.*)("|\')$/s',$data[2],$resultx))
888
- $missing_semicolon[] = trim(str_replace($data[2],$resultx[1].$resultx[2].' ...'.$resultx[4],$data[0]));
889
  else $missing_semicolon[] = trim($data[0]);
890
  }
891
  } else {
892
- if (!in_array($key,$unknown_properties)) $unknown_properties[] = $key;
893
  }
894
  $i++;
895
  }
@@ -906,17 +961,17 @@ class OwebiaShippingHelper
906
  if (count($formula_fields_to_check)>0) {
907
  foreach ($formula_fields_to_check as $property) {
908
  $property_value = $row[$property]['value'];
909
- if (preg_match('/{ +/',$property_value)) {
910
- $this->addMessage('warning',$row,$property,'There are unwanted spaces after char `%s`','{');
911
- $property_value = preg_replace('/{ +/','{',$property_value);
912
  }
913
- if (preg_match('/ +}/',$property_value)) {
914
- $this->addMessage('warning',$row,$property,'There are unwanted spaces before char `%s`','}');
915
- $property_value = preg_replace('/ +}/','}',$property_value);
916
  }
917
- if (preg_match('/ +/',$property_value)) {
918
- $this->addMessage('warning',$row,$property,'There are unwanted multiples spaces `%s`',preg_replace('/( +)/','<span class="osh-formula">*$1*</span>',$property_value));
919
- $property_value = preg_replace('/ +/',' ',$property_value);
920
  }
921
  $row[$property]['value'] = trim($property_value);
922
  }
@@ -925,31 +980,31 @@ class OwebiaShippingHelper
925
  $float_value_regex = '\\s*('.self::POSITIVE_FLOAT_REGEX.'|\*)\\s*';
926
  $conditions = array();
927
  if (isset($row['prices_range'])) {
928
- if (!in_array('prices_range',$deprecated_properties)) $deprecated_properties[] = 'prices_range';
929
 
930
  $result = $this->_getOptionsAndData($row['prices_range']['value']);
931
  $options = $result['options'];
932
  $prices_range = $result['data'];
933
 
934
- if (($options=='' || in_array($options,array('incl.tax','ttc')))
935
- && preg_match('/^\\s*(\[|\])?'.$float_value_regex.'=>'.$float_value_regex.'(\[|\])?\\s*$/',$prices_range,$result)) {
936
  $min_price_included = $result[1]=='[';
937
  $min_price = $result[2]=='*' ? -1 : (float)$result[2];
938
  $max_price = $result[3]=='*' ? -1 : (float)$result[3];
939
  $max_price_included = !isset($result[4]) || $result[4]==']' || $result[4]=='';
940
 
941
- $tax_included = $options!='' && in_array($options,array('incl.tax','ttc')) || isset($row['reference_value']) && $row['reference_value']['value']=='price_including_tax';
942
  $price = $tax_included ? '{cart.price_including_tax}' : '{cart.price_excluding_tax}';
943
 
944
  if ($min_price!=-1) $conditions[] = $price.'>'.($min_price_included ? '=' : '').$min_price;
945
  if ($max_price!=-1) $conditions[] = $price.'<'.($max_price_included ? '=' : '').$max_price;
946
  }
947
- else $this->addMessage('error',$row,null,'Unrecognized value of deprecated property %s %s','<span class="osh-key">prices_range</span>','<span class="osh-formula">'.$row['prices_range']['value'].'</span>');
948
  unset($row['prices_range']);
949
  }
950
  if (isset($row['weights_range'])) {
951
- if (!in_array('weights_range',$deprecated_properties)) $deprecated_properties[] = 'weights_range';
952
- if (preg_match('/^\\s*(\[|\])?'.$float_value_regex.'=>'.$float_value_regex.'(\[|\])?\\s*$/',$row['weights_range']['value'],$result)) {
953
  $min_weight_included = $result[1]=='[';
954
  $min_weight = $result[2]=='*' ? -1 : (float)$result[2];
955
  $max_weight = $result[3]=='*' ? -1 : (float)$result[3];
@@ -958,14 +1013,14 @@ class OwebiaShippingHelper
958
  if ($min_weight!=-1) $conditions[] = '{cart.weight}>'.($min_weight_included ? '=' : '').$min_weight;
959
  if ($max_weight!=-1) $conditions[] = '{cart.weight}<'.($max_weight_included ? '=' : '').$max_weight;
960
  }
961
- else $this->addMessage('error',$row,null,'Unrecognized value of deprecated property %s %s','<span class="osh-key">weights_range</span>','<span class="osh-formula">'.$row['weights_range']['value'].'</span>');
962
  unset($row['weights_range']);
963
  }
964
  if (isset($row['product_properties'])) {
965
- if (!in_array('product_properties',$deprecated_properties)) $deprecated_properties[] = 'product_properties';
966
  $product_property_regex = "\\s*(and|or)? *\((?:(all|any|sum) )?(attribute|option) '([^'\)]+)' ?(==|=|<=|>=|<|>|!=) ?(".self::FLOAT_REGEX."|true|false|'[^'\)]*')\)\\s*";
967
- if (preg_match('/^('.$product_property_regex.')+$/',$row['product_properties']['value'],$result)) {
968
- preg_match_all('/'.$product_property_regex.'/',$row['product_properties']['value'],$results,PREG_SET_ORDER);
969
  $product_properties_condition = '';
970
  foreach ($results as $result) {
971
  $and_or = $result[1];
@@ -993,106 +1048,106 @@ class OwebiaShippingHelper
993
  }
994
  if ($product_properties_condition!='') $conditions[] = $product_properties_condition;
995
  }
996
- else $this->addMessage('error',$row,null,'Unrecognized value of deprecated property %s %s','<span class="osh-key">product_properties</span>','<span class="osh-formula">'.$row['product_properties']['value'].'</span>');
997
  unset($row['product_properties']);
998
  }
999
- if (count($conditions)>0) $row['conditions'] = array('value' => count($conditions)==1 ? $conditions[0] : '('.implode(') && (',$conditions).')');
1000
 
1001
  $fees = array();
1002
  if (isset($row['fees_table'])) {
1003
- if (!in_array('fees_table',$deprecated_properties)) $deprecated_properties[] = 'fees_table';
1004
  $options_and_data = $this->_getOptionsAndData($row['fees_table']['value']);
1005
  $options = $options_and_data['options'];
1006
  $fees_table_string = $options_and_data['data'];
1007
 
1008
  $var = null;
1009
  if ($options=='') $var = (isset($row['reference_value']) ? $row['reference_value']['value'] : 'weight');
1010
- else if (in_array($options,array('incl.tax','ttc'))) $var = 'price_including_tax';
1011
- else if (in_array($options,array('excl.tax','ht'))) $var = 'price_excluding_tax';
1012
 
1013
  if (isset($var)) {
1014
  if ($var=='price') $var = 'price_excluding_tax';
1015
  if ($var=='products_quantity') $var = 'quantity';
1016
- if (preg_match('/^[[:space:]]*\*[[:space:]]*:[[:space:]]*('.$float_value_regex.')[[:space:]]*$/s',$fees_table_string,$result)) $fees[] = $result[1];
1017
- else $fees[] = "{table {cart.".$var."} in ".str_replace(' ','',$fees_table_string)."}".($var=='quantity' ? '*{cart.quantity}' : '');
1018
  }
1019
- else $this->addMessage('error',$row,null,'Unrecognized value of deprecated property %s %s','<span class="osh-key">fees_table</span>','<span class="osh-formula">'.$row['fees_table']['value'].'</span>');
1020
  unset($row['fees_table']);
1021
  }
1022
  if (isset($row['fees_formula'])) {
1023
- if (!in_array('fees_formula',$deprecated_properties)) $deprecated_properties[] = 'fees_formula';
1024
- $fees[] = str_replace(' ','',$row['fees_formula']['value']);
1025
  unset($row['fees_formula']);
1026
  }
1027
  if (isset($row['fixed_fees'])) {
1028
- if (!in_array('fixed_fees',$deprecated_properties)) $deprecated_properties[] = 'fixed_fees';
1029
- if ($row['fixed_fees']['value']!=0 || count($fees)==0) $fees[] = str_replace(' ','',$row['fixed_fees']['value']);
1030
  unset($row['fixed_fees']);
1031
  }
1032
- if (!isset($row['fees']) && count($fees)>0) $row['fees'] = array('value' => implode('+',$fees));
1033
 
1034
  $fs_fees = array();
1035
  if (isset($row['free_shipping__fees_table'])) {
1036
- if (!in_array('free_shipping__fees_table',$deprecated_properties)) $deprecated_properties[] = 'free_shipping__fees_table';
1037
  $options_and_data = $this->_getOptionsAndData($row['free_shipping__fees_table']['value']);
1038
  $options = $options_and_data['options'];
1039
  $fees_table_string = $options_and_data['data'];
1040
 
1041
  $var = null;
1042
  if ($options=='') $var = isset($row['reference_value']) ? $row['reference_value']['value'] : 'weight';
1043
- else if (in_array($options,array('incl.tax','ttc'))) $var = 'price_including_tax';
1044
- else if (in_array($options,array('excl.tax','ht'))) $var = 'price_excluding_tax';
1045
  if ($var=='price') $var = 'price_excluding_tax';
1046
 
1047
  if (isset($var)) {
1048
  if ($var=='price') $var = 'price_excluding_tax';
1049
  if ($var=='products_quantity') $var = 'quantity';
1050
- if (preg_match('/^[[:space:]]*\*[[:space:]]*:[[:space:]]*('.$float_value_regex.')[[:space:]]*$/s',$fees_table_string,$result)) $fs_fees[] = $result[1];
1051
- else $fs_fees[] = "{table {cart.".$var."} in ".str_replace(' ','',$fees_table_string)."}".($var=='quantity' ? '*{cart.quantity}' : '');
1052
  }
1053
- else $this->addMessage('error',$row,null,'Unrecognized value of deprecated property %s %s','<span class="osh-key">free_shipping__fees_table</span>','<span class="osh-formula">'.$row['free_shipping__fees_table']['value'].'</span>');
1054
  unset($row['free_shipping__fees_table']);
1055
  }
1056
  if (isset($row['free_shipping__fees_formula'])) {
1057
- if (!in_array('free_shipping__fees_formula',$deprecated_properties)) $deprecated_properties[] = 'free_shipping__fees_formula';
1058
- $fs_fees[] = str_replace(' ','',$row['free_shipping__fees_formula']['value']);
1059
  unset($row['free_shipping__fees_formula']);
1060
  }
1061
  if (isset($row['free_shipping__fixed_fees'])) {
1062
- if (!in_array('free_shipping__fixed_fees',$deprecated_properties)) $deprecated_properties[] = 'free_shipping__fixed_fees';
1063
- if ($row['free_shipping__fixed_fees']['value']!=0 || count($fees)==0) $fs_fees[] = str_replace(' ','',$row['free_shipping__fixed_fees']['value']);
1064
  unset($row['free_shipping__fixed_fees']);
1065
  }
1066
 
1067
  if (isset($row['reference_value'])) {
1068
- if (!in_array('reference_value',$deprecated_properties)) $deprecated_properties[] = 'reference_value';
1069
  unset($row['reference_value']);
1070
  }
1071
 
1072
  if (count($fs_fees)>0) {
1073
  $row2 = $row;
1074
  if (isset($row['code'])) $row2['code']['value'] = $row['code']['value'].'__free_shipping';
1075
- $row2['fees']['value'] = implode('+',$fs_fees);
1076
  $row2['conditions']['value'] = isset($row2['conditions']) ? '('.$row2['conditions']+') and {free_shipping}' : '{free_shipping}';
1077
  $row['conditions']['value'] = isset($row['conditions']) ? '('.$row['conditions']+') and !{free_shipping}' : '!{free_shipping}';
1078
  if (isset($row['free_shipping__label'])) {
1079
- if (!in_array('free_shipping__label',$deprecated_properties)) $deprecated_properties[] = 'free_shipping__label';
1080
  $row2['label']['value'] = $row['free_shipping__label']['value'];
1081
  unset($row['free_shipping__label']);
1082
  unset($row2['free_shipping__label']);
1083
  }
1084
  $this->_addRow($row2);
1085
  }
1086
- if (count($unknown_properties)>0) $this->addMessage('error',$row,null,'Usage of unknown properties %s',': <span class="osh-key">'.implode('</span>, <span class="osh-key">',$unknown_properties).'</span>');
1087
- if (count($deprecated_properties)>0) $this->addMessage('warning',$row,null,'Usage of deprecated properties %s',': <span class="osh-key">'.implode('</span>, <span class="osh-key">',$deprecated_properties).'</span>');
1088
- if (count($obsolete_disabling_method)>0) $this->addMessage('warning',$row,null,'Usage of obsolete method to disabling a shipping method (`#` before `{`)%s','<div class="code">'.implode('<br />',$obsolete_disabling_method).'</div>');
1089
- if (count($missing_semicolon)>0) $this->addMessage('warning',$row,null,'A semicolon is missing at the end of following lines %s','<div class="code">'.implode('<br />',$missing_semicolon).'</div>');
1090
  $this->_addRow($row);
1091
  }
1092
  if (trim($config_string)!='') {
1093
  $this->_addIgnoredLines(trim($config_string));
1094
  $row = null;
1095
- $this->addMessage('info',$row,null,'Ignored lines %s','<div class="code">'.trim($config_string).'</div>');
1096
  }
1097
  }
1098
 
@@ -1101,7 +1156,7 @@ class OwebiaShippingHelper
1101
  array_shift($args);
1102
  array_shift($args);
1103
  array_shift($args);
1104
- $message = new OS_Message($type,$args);
1105
  if (isset($row)) {
1106
  if (isset($property)) {
1107
  $row[$property]['messages'][] = $message;
@@ -1116,12 +1171,12 @@ class OwebiaShippingHelper
1116
  protected function _addRow(&$row) {
1117
  if (isset($row['code'])) {
1118
  $key = $row['code']['value'];
1119
- if (isset($this->_config[$key])) $this->addMessage('error',$row,'code','The property `code` must be unique, `%s` has been found twice',$key);
1120
- while (isset($this->_config[$key])) $key .= rand(0,9);
1121
  } else {
1122
  $i = 1;
1123
  do {
1124
- $key = 'code_auto'.sprintf('%03d',$i);
1125
  $i++;
1126
  } while (isset($this->_config[$key]));
1127
  }
@@ -1148,12 +1203,12 @@ class OwebiaShippingHelper
1148
  return true;
1149
  }
1150
 
1151
- if (preg_match('#\* *- *\((.*)\)#s',$address_filter,$result)) {
1152
  $address_filter = $result[1];
1153
  $excluding = true;
1154
  }
1155
 
1156
- $tmp_address_filter_array = explode(',',trim($address_filter));
1157
 
1158
  $concat = false;
1159
  $concatened = '';
@@ -1163,12 +1218,12 @@ class OwebiaShippingHelper
1163
  foreach ($tmp_address_filter_array as $address_filter) {
1164
  if ($concat) $concatened .= ','.$address_filter;
1165
  else {
1166
- if ($i<count($tmp_address_filter_array)-1 && preg_match('#\(#',$address_filter)) {
1167
  $concat = true;
1168
  $concatened .= $address_filter;
1169
  } else $address_filter_array[] = $address_filter;
1170
  }
1171
- if (preg_match('#\)#',$address_filter)) {
1172
  $address_filter_array[] = $concatened;
1173
  $concatened = '';
1174
  $concat = false;
@@ -1184,7 +1239,7 @@ class OwebiaShippingHelper
1184
  $this->debug(' country code <span class="osh-replacement">'.$address['country_code'].'</span> matches');
1185
  if (!isset($result[4]) || $result[4]=='') return !$excluding;
1186
  else {
1187
- $region_codes = explode(',',$result[4]);
1188
  $in_array = false;
1189
  for ($i=count($region_codes); --$i>=0;) {
1190
  $code = trim(str_replace(
@@ -1199,10 +1254,10 @@ class OwebiaShippingHelper
1199
  } else if ($address['postcode']===$code) {
1200
  $this->debug(' postcode <span class="osh-replacement">'.$address['postcode'].'</span> matches');
1201
  $in_array = true;
1202
- } else if (mb_substr($code,0,1)=='/' && mb_substr($code,mb_strlen($code)-1,1)=='/' && @preg_match($code, $address['postcode'])) {
1203
  $this->debug(' postcode <span class="osh-replacement">'.$address['postcode'].'</span> matches <span class="osh-formula">'.htmlentities($code).'</span>');
1204
  $in_array = true;
1205
- } else if (strpos($code,'*')!==false && preg_match('/^'.str_replace('*','(?:.*)',$code).'$/',$address['postcode'])) {
1206
  $this->debug(' postcode <span class="osh-replacement">'.$address['postcode'].'</span> matches <span class="osh-formula">'.htmlentities($code).'</span>');
1207
  $in_array = true;
1208
  }
@@ -1237,6 +1292,18 @@ class OwebiaShippingHelper
1237
  return null;
1238
  }
1239
 
 
 
 
 
 
 
 
 
 
 
 
 
1240
  protected function _processProductProperty($products, $regex_result) {
1241
  // count, sum, min, max, count distinct
1242
  $operation = strtolower($regex_result[1]);
@@ -1323,17 +1390,9 @@ class OwebiaShippingHelper
1323
  );
1324
  }
1325
  $from = $property[0];
1326
- if (is_array($value)) {
1327
- $items = array();
1328
- foreach ($value as $v) {
1329
- $items[] = is_string($v) || empty($v) ? "'".$v."'" : $v;
1330
- }
1331
- $to = 'array('.join(',', $items).')';
1332
- } else {
1333
- $to = is_string($value) || empty($value) ? "'".$value."'" : $value;
1334
- }
1335
- $this->debug(' replace <span class="osh-replacement">'.$from.'</span> by <span class="osh-replacement">'.$to.'</span> =&gt; <span class="osh-formula">'.str_replace($from,'<span class="osh-replacement">'.$to.'</span>',$formula).'</span>');
1336
- $formula = str_replace($from,$to,$formula);
1337
  }
1338
  $eval_result = $this->_evalFormula($formula);
1339
  if (!isset($eval_result)) $return_value = 'null';
@@ -1347,7 +1406,7 @@ class OwebiaShippingHelper
1347
  if ($property_type=='quantity') {
1348
  $value = $product->getQuantity();
1349
  } else {
1350
- $value = $this->_getProductProperty($product,$property_type,$property_name);
1351
  }
1352
  switch ($operation) {
1353
  case 'min':
@@ -1363,7 +1422,7 @@ class OwebiaShippingHelper
1363
  case 'count distinct':
1364
  if (!isset($return_value)) $return_value = 0;
1365
  if (!isset($distinct_values)) $distinct_values = array();
1366
- if (!in_array($value,$distinct_values)) {
1367
  $distinct_values[] = $value;
1368
  $return_value++;
1369
  }
@@ -1414,7 +1473,7 @@ class OS_Message {
1414
  }
1415
 
1416
  public function toString() {
1417
- return vsprintf($this->message,$this->args);
1418
  }
1419
  }
1420
 
1
  <?php
2
 
3
  /**
4
+ * Copyright (c) 2008-12 Owebia
5
  *
6
  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
7
  * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
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() {
104
  'store.address' => '',
105
  'store.phone' => '',
106
  'date.timestamp' => $timestamp,
107
+ 'date.year' => (int)date('Y', $timestamp),
108
+ 'date.month' => (int)date('m', $timestamp),
109
+ 'date.day' => (int)date('d', $timestamp),
110
+ 'date.hour' => (int)date('H', $timestamp),
111
+ 'date.minute' => (int)date('i', $timestamp),
112
+ 'date.second' => (int)date('s', $timestamp),
113
  );
114
  return $properties;
115
  }
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;
178
  return $messages;
179
  }
180
 
181
+ public function formatConfig($compress, $keys_to_remove=array()) {
182
  $output = '';
183
  foreach ($this->_config as $code => $row) {
184
  if (!isset($row['lines'])) {
187
  }
188
  $output .= '{'.($compress ? '' : "\n");
189
  foreach ($row as $key => $property) {
190
+ if (substr($key, 0, 1)!='*' && !in_array($key, $keys_to_remove)) {
191
  $value = $property['value'];
192
  if (isset($property['comment'])) $output .= ($compress ? '' : "\t").'/* '.$property['comment'].' */'.($compress ? '' : "\n");
193
  $output .= ($compress ? '' : "\t").$key.':'.($compress ? '' : ' ');
194
  if (is_bool($value)) $output .= $value ? 'true' : 'false';
195
  else if ((string)((int)$value)==$value) $output .= $value;
196
  else if ((string)((float)$value)==$value) $output .= ($compress ? (float)$value : $value);
197
+ else $output .= '"'.str_replace('"', '\\"', $value).'"';
198
  $output .= ','.($compress ? '' : "\n");
199
  }
200
  }
201
+ if ($compress) $output = preg_replace('/,$/', '', $output);
202
  $output .= "}\n".($compress ? '' : "\n");
203
  } else {
204
  $output .= $row['lines']."\n";
216
  'result' => null,
217
  );
218
  foreach ($this->_config as $code => &$row) {
219
+ $this->processRow($process, $row, $check_all_conditions=true);
220
  foreach ($row as $property_key => $property_value) {
221
+ if (substr($property_key, 0, 1)!='*') $this->getRowProperty($row, $property_key);
222
  }
223
  }
224
  }
229
  $this->debug('process row <span class="osh-key">'.$row['*code'].'</span>');
230
  if (!isset($row['label']['value'])) $row['label']['value'] = '***';
231
 
232
+ $enabled = $this->getRowProperty($row, 'enabled');
233
  if (isset($enabled)) {
234
  if (!$is_checking && !$enabled) {
235
+ $this->addMessage('info', $row, 'enabled', 'Configuration disabled');
236
  return new OS_Result(false);
237
  }
238
  }
239
 
240
+ $conditions = $this->getRowProperty($row, 'conditions');
241
  if (isset($conditions)) {
242
+ $result = $this->_processFormula($process, $row, 'conditions', $conditions, $is_checking);
243
  if (!$is_checking) {
244
  if (!$result->success) return $result;
245
  if (!$result->result) {
246
+ $this->addMessage('info', $row, 'conditions', "The cart doesn't match conditions");
247
  return new OS_Result(false);
248
  }
249
  }
250
  }
251
 
252
+ $destination = $this->getRowProperty($row, 'destination');
253
  if (isset($destination)) {
254
+ $destination_match = $this->_addressMatch($destination, array(
255
  'country_code' => $process['data']['destination.country.code'],
256
  'region_code' => $process['data']['destination.region.code'],
257
  'postcode' => $process['data']['destination.postcode']
258
  ));
259
  if (!$is_checking && !$destination_match) {
260
+ $this->addMessage('info', $row, 'destination', "The shipping method doesn't cover the zone");
261
  return new OS_Result(false);
262
  }
263
  }
264
 
265
+ $origin = $this->getRowProperty($row, 'origin');
266
  if (isset($origin)) {
267
+ $origin_match = $this->_addressMatch($origin, array(
268
  'country_code' => $process['data']['origin.country.code'],
269
  'region_code' => $process['data']['origin.region.code'],
270
  'postcode' => $process['data']['origin.postcode']
271
  ));
272
  if (!$is_checking && !$origin_match) {
273
+ $this->addMessage('info', $row, 'origin', "The shipping method doesn't match to shipping origin");
274
  return new OS_Result(false);
275
  }
276
  }
277
 
278
+ $customer_groups = $this->getRowProperty($row, 'customer_groups');
279
  if (isset($customer_groups)) {
280
+ $groups = explode(',', $customer_groups);
281
  $group_match = false;
282
  //$this->debug('code:'.$process['data']['customer.group.code'].', id:'.$process['data']['customer.group.id']);
283
  foreach ($groups as $group) {
290
  }
291
  }
292
  if (!$is_checking && !$group_match) {
293
+ $this->addMessage('info', $row, 'customer_groups', "The shipping method doesn't match to customer group (%s)", $process['data']['customer.group.code']);
294
  return new OS_Result(false);
295
  }
296
  }
297
 
298
+ $fees = $this->getRowProperty($row, 'fees');
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);
306
  }
309
  $property = null;
310
  $output = null;
311
  if (isset($original_row) && isset($original_key) && $original_row['*code']==$row['*code'] && $original_key==$key) {
312
+ $this->addMessage('error', $row, $key, 'Infinite loop %s', "<span class=\"code\">{".$row['*code'].'.'.$key."}</span>");
313
  return array('error' => 'Infinite loop');
314
  }
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;
322
+ if (!in_array($ref_code, array('module', 'date', 'store', 'cart', 'product', 'selection', 'customvar'))) {
323
  if ($ref_code==$row['code']['value'] && $ref_key==$key) {
324
+ $this->addMessage('error', $row, $key, 'Infinite loop %s', "<span class=\"code\">".$original."</span>");
325
  return null;
326
  }
327
  if (isset($this->_config[$ref_code][$ref_key]['value'])) {
328
+ $replacement = $this->getRowProperty($this->_config[$ref_code], $ref_key,
329
+ isset($original_row) ? $original_row : $row, isset($original_key) ? $original_key : $key);
330
  if (is_array($replacement) && isset($replacement['error'])) {
331
  return isset($original_row) ? $replacement : 'false';
332
  }
333
  } else {
334
+ //$this->addMessage('error', $row, $key, 'Non-existent property %s', "<span class=\"code\">".$original."</span>");
335
  $replacement = $original;//'null';
336
  }
337
+ $output = $this->replace($original, $replacement, $output);
338
  }
339
  }
340
  } else {
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
 
361
  protected function _min() {
378
 
379
  protected function _processFormula($process, &$row, $property_key, $formula_string, $is_checking, $use_cache=true)
380
  {
381
+ $result = $this->_prepareFormula($process, $row, $property_key, $formula_string, $is_checking, $use_cache);
382
  if (!$result->success) return $result;
383
 
384
  $eval_result = $this->_evalFormula($result->result);
385
  if (!isset($eval_result)) {
386
+ $this->addMessage('error', $row, $property_key, 'Invalid formula');
387
  $result = new OS_Result(false);
388
+ if ($use_cache) $this->setCache($formula_string, $result);
389
  return $result;
390
  }
391
+ $result = new OS_Result(true, $eval_result);
392
+ if ($use_cache) $this->setCache($formula_string, $result);
393
  return $result;
394
  }
395
 
396
  public function evalInput($process, $row, $property_key, $input) {
397
+ $result = $this->_prepareFormula($process, $row, $property_key, $input, $is_checking=false, $use_cache=true);
398
  return $result->success ? $result->result : $input;
399
  }
400
 
470
  }
471
  $this->removeDebugIndent();
472
  } else {
473
+ list($filter_property_type, $filter_property_name) = explode('.', $result[1]);
474
  $selections = array();
475
  $this->debug(' foreach <span class="osh-key">'.$filter_property_type.'</span>.<span class="osh-key">'.$filter_property_name.'</span>');
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;
494
  $process2['cart.products'] = $selection['products'];
495
  $process2['data']['selection.quantity'] = $selection['quantity'];
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();
503
  $this->debug(' <span class="osh-loop">end</span>');
504
+ if ($use_cache) $this->setCache($original, $replacement);
505
  }
506
+ $formula = $this->replace($original, $replacement, $formula);
507
  }
508
 
509
  // customvar, variables
510
  while ($this->_preg_match("#{customvar\.([a-z0-9_]+)}#i", $formula, $result)) {
511
  $original = $result[0];
512
  $replacement = isset($process['store_interface']) ? $process['store_interface']->getCustomVar($result[1]) : null;
513
+ $formula = $this->replace($original, $replacement, $formula);
514
  }
515
 
516
  $first_product = isset($process['cart.products'][0]) ? $process['cart.products'][0] : null;
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
  }
551
 
552
  if (isset($first_product)) {
553
+ // With strings auto-escape
554
+ while ($this->_preg_match("#{{{PRODUCT_REGEX}\.({ATTRIBUTE_REGEX}|{OPTION_REGEX}|stock)\.([a-z0-9_+-]+)}}#i", $formula, $result)) {
555
+ $original = $result[0];
556
+ $replacement = $this->_getProductProperty($first_product, $result[1], $result[2], $get_by_id=false);
557
+ $formula = $this->replace($original, $this->_autoEscapeStrings($replacement), $formula);
558
+ }
559
+ // Without strings auto-escape
560
+ while ($this->_preg_match("#{{PRODUCT_REGEX}\.({ATTRIBUTE_REGEX}|{OPTION_REGEX}|stock)\.([a-z0-9_+-]+)}#i", $formula, $result)) {
561
  $original = $result[0];
562
  $replacement = $this->_getProductProperty($first_product, $result[1], $result[2], $get_by_id=false);
563
+ $formula = $this->replace($original, $replacement, $formula);
564
  }
565
  }
566
 
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);
579
  }
580
+ $formula = $this->replace($original, $replacement, $formula);
581
  }
582
 
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];
592
+
593
+ $couple_regex = '[^}:]+ *\: *[0-9.]+ *';
594
+ if (!preg_match('#^ *'.$couple_regex.'(?:, *'.$couple_regex.')*$#', $fees_table_string)) {
595
+ $this->addMessage('error', $row, $property_key, 'Error in switch %s', '<span class="osh-formula">'.htmlentities($result[0]).'</span>');
596
+ $result = new OS_Result(false);
597
+ if ($use_cache) $this->setCache($formula_string, $result);
598
+ return $result;
599
+ }
600
+ $fees_table = explode(',', $fees_table_string);
601
+
602
+ $replacement = null;
603
+ foreach ($fees_table as $item) {
604
+ $fee_data = explode(':', $item);
605
+
606
+ $fee = trim($fee_data[1]);
607
+ $value = trim($fee_data[0]);
608
+ $value = $value=='*' ? '*' : $this->_evalFormula($fee_data[0]);
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);
621
+ }
622
+
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];
631
  if (isset($reference_value)) {
632
  $fees_table_string = $result[2];
633
 
634
+ if (!preg_match('#^'.self::COUPLE_REGEX.'(?:, *'.self::COUPLE_REGEX.')*$#', $fees_table_string)) {
635
+ $this->addMessage('error', $row, $property_key, 'Error in table %s', '<span class="osh-formula">'.htmlentities($result[0]).'</span>');
636
  $result = new OS_Result(false);
637
+ if ($use_cache) $this->setCache($formula_string, $result);
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
 
646
  $fee = trim($fee_data[1]);
647
  $max_value = trim($fee_data[0]);
651
  else if ($last_char==']') $including_max_value = true;
652
  else $including_max_value = true;
653
 
654
+ $max_value = str_replace(array('[', ']'), '', $max_value);
655
 
656
  if ($max_value=='*' || $including_max_value && $reference_value<=$max_value || !$including_max_value && $reference_value<$max_value) {
657
  $replacement = $fee;
660
  }
661
  }
662
  $replacement = $this->_toString($replacement);
663
+ if ($use_cache) $this->setCache($original, $replacement);
664
  }
665
+ $formula = $this->replace($original, $replacement, $formula);
666
  }
667
+ $result = new OS_Result(true, $formula);
668
  return $result;
669
  }
670
 
672
  if (is_bool($formula)) return $formula;
673
  if (!preg_match('/^(?:E|floor|ceil|round|max|min|rand|pow|pi|sqrt|log|exp|abs|int|float|true|false|null|and|or|in|substr|strtolower'
674
  .'|in_array\((?:\'(?:[^\']*)\'|(?:[^\']*)), *array\( *(?:(?:\'(?:[^\']+)\'|(?:[^\']+)) *(?: *, *(?:\'(?:[^\']+)\'|(?:[^\']+)))* *)?\) *\)'
675
+ .'|\'[^\']*\'|[0-9,\'\.\-\(\)\*\/\?\:\+\<\>\=\&\|%! ])*$/', $formula)) {
676
  $errors = array(
677
  PREG_NO_ERROR => 'PREG_NO_ERROR',
678
  PREG_INTERNAL_ERROR => 'PREG_INTERNAL_ERROR',
688
  return null;
689
  }
690
  $formula = str_replace(
691
+ array('min', 'max'),
692
+ array('$this->_min', '$this->_max'),
693
  $formula
694
  );
695
  $eval_result = null;
699
  }
700
 
701
  protected function _getOptionsAndData($string) {
702
+ if (preg_match('/^(\\s*\(\\s*([^\] ]*)\\s*\)\\s*)/', $string, $result)) {
703
  $options = $result[2];
704
+ $data = str_replace($result[1], '', $string);
705
  } else {
706
  $options = '';
707
  $data = $string;
714
 
715
  public function compress($input) {
716
  /*
717
+ if (preg_match_all("/{table (.*) in (".self::COUPLE_REGEX."(?:, *".self::COUPLE_REGEX.")*)}/imsU", $input, $result, PREG_SET_ORDER)) {
718
  foreach ($result as $result_i) {
719
+ $fees_table = explode(',', $result_i[2]);
720
  $value = null;
721
  foreach ($fees_table as $index => $item) {
722
+ list($max_value, $fee) = explode(':', $item);
723
  $last_char = $max_value{strlen($max_value)-1};
724
+ if (in_array($last_char, array('[', ']'))) {
725
  $including_char = $last_char;
726
+ $max_value = str_replace(array('[', ']'), '', $max_value);
727
  } else $including_char = '';
728
  $fees_table[$index] = ((float)$max_value).$including_char.':'.((float)$fee);
729
  }
730
+ $input = str_replace($result_i[2], implode(',', $fees_table), $input);
731
+ $input = str_replace($result_i[1], trim($result_i[1]), $input);
732
  }
733
  }
734
+ if (preg_match_all("#{foreach ([^}]*)}(.*){/foreach}#imsU", $input, $result, PREG_SET_ORDER)) {
735
  foreach ($result as $result_i) {
736
+ $input = str_replace($result_i[1], trim($result_i[1]), $input);
737
+ $input = str_replace($result_i[2], trim($result_i[2]), $input);
738
  }
739
  }
740
  */
751
  }
752
 
753
  public function uncompress($input) {
754
+ if (substr($input, 0, 4)=='gz64' && function_exists('gzuncompress') && function_exists('base64_decode')) {
755
+ $input = gzuncompress(base64_decode(substr($input, 4, strlen($input))));
756
  }
757
 
758
  /*
759
+ if (preg_match_all("/{table (.*) in (".self::COUPLE_REGEX."(?:, *".self::COUPLE_REGEX.")*)}/iU", $input, $result, PREG_SET_ORDER)) {
760
  foreach ($result as $result_i) {
761
+ $fees_table = explode(',', $result_i[2]);
762
  $value = null;
763
  foreach ($fees_table as $index => $item) {
764
+ list($max_value, $fee) = explode(':', $item);
765
  $last_char = $max_value{strlen($max_value)-1};
766
+ if (in_array($last_char, array('[', ']'))) {
767
  $including_char = $last_char;
768
+ $max_value = str_replace(array('[', ']'), '', $max_value);
769
  } else $including_char = '';
770
  $max_value = (float)$max_value;
771
  $fee = (float)$fee;
772
+ $new_max_value = number_format($max_value, 2, '.', '');
773
+ $new_fee = number_format($fee, 2, '.', '');
774
  $fees_table[$index] = (((float)$new_max_value)==$max_value ? $new_max_value : $max_value).$including_char.':'
775
  .(((float)$new_fee)==$fee ? $new_fee : $fee);
776
  }
777
+ $input = str_replace($result_i[2], implode(', ', $fees_table), $input);
778
+ $input = str_replace($result_i[1], trim($result_i[1]), $input);
779
  }
780
  }
781
+ if (preg_match_all("#{foreach ([^}]*)}(.*){/foreach}#iU", $input, $result, PREG_SET_ORDER)) {
782
  foreach ($result as $result_i) {
783
+ $input = str_replace($result_i[1], trim($result_i[1]), $input);
784
+ $input = str_replace($result_i[2], trim($result_i[2]), $input);
785
  }
786
  }
787
  */
793
  }
794
 
795
  public function parseProperty($input) {
796
+ $value = $input==='false' || $input==='true' ? $input=='true' : str_replace('\"', '"', preg_replace('/^(?:"|\')(.*)(?:"|\')$/s', '$1', $input));
797
  return $value==='' ? null : $value;
798
  }
799
 
800
  public function cleanProperty(&$row, $key) {
801
  $input = $row[$key]['value'];
802
  if (is_string($input)) {
803
+ $input = str_replace(array("\n"), array(''), $input);
804
+ while (preg_match('/({TABLE |{SUM |{COUNT | DISTINCT | IN )/', $input, $resi)) {
805
+ $input = str_replace($resi[0], strtolower($resi[0]), $input);
806
  }
807
 
808
+ while (preg_match('/{{customVar code=([a-zA-Z0-9_-]+)}}/', $input, $resi)) {
809
+ $input = str_replace($resi[0], '{customvar.'.$resi[1].'}', $input);
810
  }
811
 
812
  $regex = "{(weight|products_quantity|price_including_tax|price_excluding_tax|country)}";
813
+ if (preg_match('/'.$regex.'/', $input, $resi)) {
814
+ $this->addMessage('warning', $row, $key, 'Usage of deprecated syntax %s', '<span class="osh-formula">'.$resi[0].'</span>');
815
+ while (preg_match('/'.$regex.'/', $input, $resi)) {
816
  switch ($resi[1]) {
817
  case 'price_including_tax':
818
  case 'price_excluding_tax':
819
  case 'weight':
820
+ $input = str_replace($resi[0], "{cart.".$resi[1]."}", $input);
821
  break;
822
+ case 'products_quantity': $input = str_replace($resi[0], "{cart.quantity}", $input); break;
823
+ case 'country': $input = str_replace($resi[0], "{destination.country.name}", $input); break;
824
  }
825
  }
826
  }
827
 
828
  $regex1 = "{copy '([a-zA-Z0-9_]+)'\.'([a-zA-Z0-9_]+)'}";
829
+ if (preg_match('/'.$regex1.'/', $input, $resi)) {
830
+ $this->addMessage('warning', $row, $key, 'Usage of deprecated syntax %s', '<span class="osh-formula">'.$resi[0].'</span>');
831
+ while (preg_match('/'.$regex1.'/', $input, $resi)) $input = str_replace($resi[0], '{'.$resi[1].'.'.$resi[2].'}', $input);
832
  }
833
 
834
  $regex1 = "{(count|all|any) (attribute|option) '([^'\)]+)' ?((?:==|<=|>=|<|>|!=) ?(?:".self::FLOAT_REGEX."|true|false|'[^'\)]*'))}";
835
  $regex2 = "{(sum) (attribute|option) '([^'\)]+)'}";
836
+ if (preg_match('/'.$regex1.'/', $input, $resi) || preg_match('/'.$regex2.'/', $input, $resi)) {
837
+ $this->addMessage('warning', $row, $key, 'Usage of deprecated syntax %s', '<span class="osh-formula">'.$resi[0].'</span>');
838
+ while (preg_match('/'.$regex1.'/', $input, $resi) || preg_match('/'.$regex2.'/', $input, $resi)) {
839
  switch ($resi[1]) {
840
+ case 'count': $input = str_replace($resi[0], "{count products where product.".$resi[2]."s.".$resi[3].$resi[4]."}", $input); break;
841
+ case 'all': $input = str_replace($resi[0], "{count products where product.".$resi[2]."s.".$resi[3].$resi[4]."}=={products_quantity}", $input); break;
842
+ case 'any': $input = str_replace($resi[0], "{count products where product.".$resi[2]."s.".$resi[3].$resi[4]."}>0", $input); break;
843
+ case 'sum': $input = str_replace($resi[0], "{sum product.".$resi[2].".".$resi[3]."}", $input); break;
844
  }
845
  }
846
  }
847
 
848
  $regex = "((?:{| )product.(?:attribute|option))s.";
849
+ if (preg_match('/'.$regex.'/', $input, $resi)) {
850
+ $this->addMessage('warning', $row, $key, 'Usage of deprecated syntax %s', '<span class="osh-formula">'.$resi[0].'</span>');
851
+ while (preg_match('/'.$regex.'/', $input, $resi)) {
852
+ $input = str_replace($resi[0], $resi[1].'.', $input);
853
  }
854
  }
855
 
856
  $regex = "{table '([^']+)' (".self::COUPLE_REGEX."(?:, *".self::COUPLE_REGEX.")*)}";
857
+ if (preg_match('/'.$regex.'/', $input, $resi)) {
858
+ $this->addMessage('warning', $row, $key, 'Usage of deprecated syntax %s', '<span class="osh-formula">'.$resi[0].'</span>');
859
+ while (preg_match('/'.$regex.'/', $input, $resi)) {
860
  switch ($resi[1]) {
861
  case 'products_quantity':
862
+ $input = str_replace($resi[0], "{table {cart.weight} in ".$resi[2]."}*{cart.quantity}", $input);
863
  break;
864
  default:
865
+ $input = str_replace($resi[0], "{table {cart.".$resi[1]."} in ".$resi[2]."}", $input);
866
  break;
867
  }
868
  }
873
 
874
  protected function _parseInput() {
875
  $config_string = str_replace(
876
+ array('&gt;', '&lt;', '“', '”', utf8_encode(chr(147)), utf8_encode(chr(148)), '&laquo;', '&raquo;', "\r\n", "\t"),
877
+ array('>', '<', '"', '"', '"', '"', '"', '"', "\n", ' '),
878
  $this->_input
879
  );
880
 
881
+ if (substr($config_string, 0, 2)=='$$') $config_string = $this->uncompress(substr($config_string, 2, strlen($config_string)));
882
 
883
  //echo ini_get('pcre.backtrack_limit');
884
  //exit;
885
 
886
  $row_regex = ' *([a-z0-9_]+)\\s*:\\s*("(?:(?:[^"]|\\\\")*[^\\\\])?"|'.self::FLOAT_REGEX.'|false|true)\\s*(,)? *(?:\\n)?';
887
+ if (!preg_match_all('/((?:#+[^{\\n]*\\s+)*)\\s*(#)?{\\s*('.$row_regex.')+\\s*}/i', $config_string, $result, PREG_SET_ORDER)) {
888
  $errors = array(
889
  PREG_NO_ERROR => 'PREG_NO_ERROR',
890
  PREG_INTERNAL_ERROR => 'PREG_INTERNAL_ERROR',
900
 
901
  $this->_config = array();
902
  $available_keys = array(
903
+ 'code', 'label', 'enabled', 'description', 'fees', 'conditions', 'destination', 'origin', 'customer_groups', 'tracking_url',
904
+ 'fees_table', 'fees_formula', 'fixed_fees', 'reference_value',
905
+ 'prices_range', 'weights_range', 'product_properties',
906
+ 'free_shipping__fees_table', 'free_shipping__fees_formula', 'free_shipping__fixed_fees', 'free_shipping__label',
907
  );
908
 
909
  foreach ($result as $block) {
912
  $missing_semicolon = array();
913
  $obsolete_disabling_method = array();
914
 
915
+ //$before = strstr($config_string, $block[0], true); // Seulement compatible avec PHP 5.3.0
916
+ list($before) = explode($block[0], $config_string, 2);
917
  if ($before!==false && trim($before)!='') {
918
+ $config_string = substr($config_string, strlen($before));
919
  $this->_addIgnoredLines(trim($before));
920
  $row = null;
921
+ $this->addMessage('info', $row, null, 'Ignored lines %s', '<div class="code">'.trim($before).'</div>');
922
  }
923
 
924
  $config_string = str_replace($block[0], '', $config_string);
925
+ preg_match_all('/'.$row_regex.'/i', $block[0], $result2, PREG_SET_ORDER);
926
  $block_string = $block[0];
927
 
928
  $row = array();
929
  $i = 1;
930
  foreach ($result2 as $data) {
931
  $key = $data[1];
932
+ if (in_array($key, $available_keys) || substr($key, 0, 1)=='_') {
933
  $property = $this->parseProperty($data[2]);
934
  if (isset($property)) {
935
  $row[$key] = array('value' => $property, 'original_value' => $property);
936
+ $this->cleanProperty($row, $key);
937
  }
938
  if ($i>2) {
939
+ $block_string = str_replace($data[0], $i==3 ? "...\n" : '', $block_string);
940
  }
941
  if ($i!=count($result2) && !isset($data[3]) || isset($data[3]) && $data[3]!=',') {
942
+ if (preg_match('/^("|\')(.{40})(.*)("|\')$/s', $data[2], $resultx))
943
+ $missing_semicolon[] = trim(str_replace($data[2], $resultx[1].$resultx[2].' ...'.$resultx[4], $data[0]));
944
  else $missing_semicolon[] = trim($data[0]);
945
  }
946
  } else {
947
+ if (!in_array($key, $unknown_properties)) $unknown_properties[] = $key;
948
  }
949
  $i++;
950
  }
961
  if (count($formula_fields_to_check)>0) {
962
  foreach ($formula_fields_to_check as $property) {
963
  $property_value = $row[$property]['value'];
964
+ if (preg_match('/{ +/', $property_value)) {
965
+ $this->addMessage('warning', $row, $property, 'There are unwanted spaces after char `%s`', '{');
966
+ $property_value = preg_replace('/{ +/', '{', $property_value);
967
  }
968
+ if (preg_match('/ +}/', $property_value)) {
969
+ $this->addMessage('warning', $row, $property, 'There are unwanted spaces before char `%s`', '}');
970
+ $property_value = preg_replace('/ +}/', '}', $property_value);
971
  }
972
+ if (preg_match('/ +/', $property_value)) {
973
+ $this->addMessage('warning', $row, $property, 'There are unwanted multiples spaces `%s`', preg_replace('/( +)/', '<span class="osh-formula">*$1*</span>', $property_value));
974
+ $property_value = preg_replace('/ +/', ' ', $property_value);
975
  }
976
  $row[$property]['value'] = trim($property_value);
977
  }
980
  $float_value_regex = '\\s*('.self::POSITIVE_FLOAT_REGEX.'|\*)\\s*';
981
  $conditions = array();
982
  if (isset($row['prices_range'])) {
983
+ if (!in_array('prices_range', $deprecated_properties)) $deprecated_properties[] = 'prices_range';
984
 
985
  $result = $this->_getOptionsAndData($row['prices_range']['value']);
986
  $options = $result['options'];
987
  $prices_range = $result['data'];
988
 
989
+ if (($options=='' || in_array($options, array('incl.tax', 'ttc')))
990
+ && preg_match('/^\\s*(\[|\])?'.$float_value_regex.'=>'.$float_value_regex.'(\[|\])?\\s*$/', $prices_range, $result)) {
991
  $min_price_included = $result[1]=='[';
992
  $min_price = $result[2]=='*' ? -1 : (float)$result[2];
993
  $max_price = $result[3]=='*' ? -1 : (float)$result[3];
994
  $max_price_included = !isset($result[4]) || $result[4]==']' || $result[4]=='';
995
 
996
+ $tax_included = $options!='' && in_array($options, array('incl.tax', 'ttc')) || isset($row['reference_value']) && $row['reference_value']['value']=='price_including_tax';
997
  $price = $tax_included ? '{cart.price_including_tax}' : '{cart.price_excluding_tax}';
998
 
999
  if ($min_price!=-1) $conditions[] = $price.'>'.($min_price_included ? '=' : '').$min_price;
1000
  if ($max_price!=-1) $conditions[] = $price.'<'.($max_price_included ? '=' : '').$max_price;
1001
  }
1002
+ else $this->addMessage('error', $row, null, 'Unrecognized value of deprecated property %s %s', '<span class="osh-key">prices_range</span>', '<span class="osh-formula">'.$row['prices_range']['value'].'</span>');
1003
  unset($row['prices_range']);
1004
  }
1005
  if (isset($row['weights_range'])) {
1006
+ if (!in_array('weights_range', $deprecated_properties)) $deprecated_properties[] = 'weights_range';
1007
+ if (preg_match('/^\\s*(\[|\])?'.$float_value_regex.'=>'.$float_value_regex.'(\[|\])?\\s*$/', $row['weights_range']['value'], $result)) {
1008
  $min_weight_included = $result[1]=='[';
1009
  $min_weight = $result[2]=='*' ? -1 : (float)$result[2];
1010
  $max_weight = $result[3]=='*' ? -1 : (float)$result[3];
1013
  if ($min_weight!=-1) $conditions[] = '{cart.weight}>'.($min_weight_included ? '=' : '').$min_weight;
1014
  if ($max_weight!=-1) $conditions[] = '{cart.weight}<'.($max_weight_included ? '=' : '').$max_weight;
1015
  }
1016
+ else $this->addMessage('error', $row, null, 'Unrecognized value of deprecated property %s %s', '<span class="osh-key">weights_range</span>', '<span class="osh-formula">'.$row['weights_range']['value'].'</span>');
1017
  unset($row['weights_range']);
1018
  }
1019
  if (isset($row['product_properties'])) {
1020
+ if (!in_array('product_properties', $deprecated_properties)) $deprecated_properties[] = 'product_properties';
1021
  $product_property_regex = "\\s*(and|or)? *\((?:(all|any|sum) )?(attribute|option) '([^'\)]+)' ?(==|=|<=|>=|<|>|!=) ?(".self::FLOAT_REGEX."|true|false|'[^'\)]*')\)\\s*";
1022
+ if (preg_match('/^('.$product_property_regex.')+$/', $row['product_properties']['value'], $result)) {
1023
+ preg_match_all('/'.$product_property_regex.'/', $row['product_properties']['value'], $results, PREG_SET_ORDER);
1024
  $product_properties_condition = '';
1025
  foreach ($results as $result) {
1026
  $and_or = $result[1];
1048
  }
1049
  if ($product_properties_condition!='') $conditions[] = $product_properties_condition;
1050
  }
1051
+ else $this->addMessage('error', $row, null, 'Unrecognized value of deprecated property %s %s', '<span class="osh-key">product_properties</span>', '<span class="osh-formula">'.$row['product_properties']['value'].'</span>');
1052
  unset($row['product_properties']);
1053
  }
1054
+ if (count($conditions)>0) $row['conditions'] = array('value' => count($conditions)==1 ? $conditions[0] : '('.implode(') && (', $conditions).')');
1055
 
1056
  $fees = array();
1057
  if (isset($row['fees_table'])) {
1058
+ if (!in_array('fees_table', $deprecated_properties)) $deprecated_properties[] = 'fees_table';
1059
  $options_and_data = $this->_getOptionsAndData($row['fees_table']['value']);
1060
  $options = $options_and_data['options'];
1061
  $fees_table_string = $options_and_data['data'];
1062
 
1063
  $var = null;
1064
  if ($options=='') $var = (isset($row['reference_value']) ? $row['reference_value']['value'] : 'weight');
1065
+ else if (in_array($options, array('incl.tax', 'ttc'))) $var = 'price_including_tax';
1066
+ else if (in_array($options, array('excl.tax', 'ht'))) $var = 'price_excluding_tax';
1067
 
1068
  if (isset($var)) {
1069
  if ($var=='price') $var = 'price_excluding_tax';
1070
  if ($var=='products_quantity') $var = 'quantity';
1071
+ if (preg_match('/^[[:space:]]*\*[[:space:]]*:[[:space:]]*('.$float_value_regex.')[[:space:]]*$/s', $fees_table_string, $result)) $fees[] = $result[1];
1072
+ else $fees[] = "{table {cart.".$var."} in ".str_replace(' ', '', $fees_table_string)."}".($var=='quantity' ? '*{cart.quantity}' : '');
1073
  }
1074
+ else $this->addMessage('error', $row, null, 'Unrecognized value of deprecated property %s %s', '<span class="osh-key">fees_table</span>', '<span class="osh-formula">'.$row['fees_table']['value'].'</span>');
1075
  unset($row['fees_table']);
1076
  }
1077
  if (isset($row['fees_formula'])) {
1078
+ if (!in_array('fees_formula', $deprecated_properties)) $deprecated_properties[] = 'fees_formula';
1079
+ $fees[] = str_replace(' ', '', $row['fees_formula']['value']);
1080
  unset($row['fees_formula']);
1081
  }
1082
  if (isset($row['fixed_fees'])) {
1083
+ if (!in_array('fixed_fees', $deprecated_properties)) $deprecated_properties[] = 'fixed_fees';
1084
+ if ($row['fixed_fees']['value']!=0 || count($fees)==0) $fees[] = str_replace(' ', '', $row['fixed_fees']['value']);
1085
  unset($row['fixed_fees']);
1086
  }
1087
+ if (!isset($row['fees']) && count($fees)>0) $row['fees'] = array('value' => implode('+', $fees));
1088
 
1089
  $fs_fees = array();
1090
  if (isset($row['free_shipping__fees_table'])) {
1091
+ if (!in_array('free_shipping__fees_table', $deprecated_properties)) $deprecated_properties[] = 'free_shipping__fees_table';
1092
  $options_and_data = $this->_getOptionsAndData($row['free_shipping__fees_table']['value']);
1093
  $options = $options_and_data['options'];
1094
  $fees_table_string = $options_and_data['data'];
1095
 
1096
  $var = null;
1097
  if ($options=='') $var = isset($row['reference_value']) ? $row['reference_value']['value'] : 'weight';
1098
+ else if (in_array($options, array('incl.tax', 'ttc'))) $var = 'price_including_tax';
1099
+ else if (in_array($options, array('excl.tax', 'ht'))) $var = 'price_excluding_tax';
1100
  if ($var=='price') $var = 'price_excluding_tax';
1101
 
1102
  if (isset($var)) {
1103
  if ($var=='price') $var = 'price_excluding_tax';
1104
  if ($var=='products_quantity') $var = 'quantity';
1105
+ if (preg_match('/^[[:space:]]*\*[[:space:]]*:[[:space:]]*('.$float_value_regex.')[[:space:]]*$/s', $fees_table_string, $result)) $fs_fees[] = $result[1];
1106
+ else $fs_fees[] = "{table {cart.".$var."} in ".str_replace(' ', '', $fees_table_string)."}".($var=='quantity' ? '*{cart.quantity}' : '');
1107
  }
1108
+ else $this->addMessage('error', $row, null, 'Unrecognized value of deprecated property %s %s', '<span class="osh-key">free_shipping__fees_table</span>', '<span class="osh-formula">'.$row['free_shipping__fees_table']['value'].'</span>');
1109
  unset($row['free_shipping__fees_table']);
1110
  }
1111
  if (isset($row['free_shipping__fees_formula'])) {
1112
+ if (!in_array('free_shipping__fees_formula', $deprecated_properties)) $deprecated_properties[] = 'free_shipping__fees_formula';
1113
+ $fs_fees[] = str_replace(' ', '', $row['free_shipping__fees_formula']['value']);
1114
  unset($row['free_shipping__fees_formula']);
1115
  }
1116
  if (isset($row['free_shipping__fixed_fees'])) {
1117
+ if (!in_array('free_shipping__fixed_fees', $deprecated_properties)) $deprecated_properties[] = 'free_shipping__fixed_fees';
1118
+ if ($row['free_shipping__fixed_fees']['value']!=0 || count($fees)==0) $fs_fees[] = str_replace(' ', '', $row['free_shipping__fixed_fees']['value']);
1119
  unset($row['free_shipping__fixed_fees']);
1120
  }
1121
 
1122
  if (isset($row['reference_value'])) {
1123
+ if (!in_array('reference_value', $deprecated_properties)) $deprecated_properties[] = 'reference_value';
1124
  unset($row['reference_value']);
1125
  }
1126
 
1127
  if (count($fs_fees)>0) {
1128
  $row2 = $row;
1129
  if (isset($row['code'])) $row2['code']['value'] = $row['code']['value'].'__free_shipping';
1130
+ $row2['fees']['value'] = implode('+', $fs_fees);
1131
  $row2['conditions']['value'] = isset($row2['conditions']) ? '('.$row2['conditions']+') and {free_shipping}' : '{free_shipping}';
1132
  $row['conditions']['value'] = isset($row['conditions']) ? '('.$row['conditions']+') and !{free_shipping}' : '!{free_shipping}';
1133
  if (isset($row['free_shipping__label'])) {
1134
+ if (!in_array('free_shipping__label', $deprecated_properties)) $deprecated_properties[] = 'free_shipping__label';
1135
  $row2['label']['value'] = $row['free_shipping__label']['value'];
1136
  unset($row['free_shipping__label']);
1137
  unset($row2['free_shipping__label']);
1138
  }
1139
  $this->_addRow($row2);
1140
  }
1141
+ if (count($unknown_properties)>0) $this->addMessage('error', $row, null, 'Usage of unknown properties %s', ': <span class="osh-key">'.implode('</span>, <span class="osh-key">', $unknown_properties).'</span>');
1142
+ if (count($deprecated_properties)>0) $this->addMessage('warning', $row, null, 'Usage of deprecated properties %s', ': <span class="osh-key">'.implode('</span>, <span class="osh-key">', $deprecated_properties).'</span>');
1143
+ if (count($obsolete_disabling_method)>0) $this->addMessage('warning', $row, null, 'Usage of obsolete method to disabling a shipping method (`#` before `{`)%s', '<div class="code">'.implode('<br />', $obsolete_disabling_method).'</div>');
1144
+ if (count($missing_semicolon)>0) $this->addMessage('warning', $row, null, 'A semicolon is missing at the end of following lines %s', '<div class="code">'.implode('<br />', $missing_semicolon).'</div>');
1145
  $this->_addRow($row);
1146
  }
1147
  if (trim($config_string)!='') {
1148
  $this->_addIgnoredLines(trim($config_string));
1149
  $row = null;
1150
+ $this->addMessage('info', $row, null, 'Ignored lines %s', '<div class="code">'.trim($config_string).'</div>');
1151
  }
1152
  }
1153
 
1156
  array_shift($args);
1157
  array_shift($args);
1158
  array_shift($args);
1159
+ $message = new OS_Message($type, $args);
1160
  if (isset($row)) {
1161
  if (isset($property)) {
1162
  $row[$property]['messages'][] = $message;
1171
  protected function _addRow(&$row) {
1172
  if (isset($row['code'])) {
1173
  $key = $row['code']['value'];
1174
+ if (isset($this->_config[$key])) $this->addMessage('error', $row, 'code', 'The property `code` must be unique, `%s` has been found twice', $key);
1175
+ while (isset($this->_config[$key])) $key .= rand(0, 9);
1176
  } else {
1177
  $i = 1;
1178
  do {
1179
+ $key = 'code_auto'.sprintf('%03d', $i);
1180
  $i++;
1181
  } while (isset($this->_config[$key]));
1182
  }
1203
  return true;
1204
  }
1205
 
1206
+ if (preg_match('#\* *- *\((.*)\)#s', $address_filter, $result)) {
1207
  $address_filter = $result[1];
1208
  $excluding = true;
1209
  }
1210
 
1211
+ $tmp_address_filter_array = explode(',', trim($address_filter));
1212
 
1213
  $concat = false;
1214
  $concatened = '';
1218
  foreach ($tmp_address_filter_array as $address_filter) {
1219
  if ($concat) $concatened .= ','.$address_filter;
1220
  else {
1221
+ if ($i<count($tmp_address_filter_array)-1 && preg_match('#\(#', $address_filter)) {
1222
  $concat = true;
1223
  $concatened .= $address_filter;
1224
  } else $address_filter_array[] = $address_filter;
1225
  }
1226
+ if (preg_match('#\)#', $address_filter)) {
1227
  $address_filter_array[] = $concatened;
1228
  $concatened = '';
1229
  $concat = false;
1239
  $this->debug(' country code <span class="osh-replacement">'.$address['country_code'].'</span> matches');
1240
  if (!isset($result[4]) || $result[4]=='') return !$excluding;
1241
  else {
1242
+ $region_codes = explode(',', $result[4]);
1243
  $in_array = false;
1244
  for ($i=count($region_codes); --$i>=0;) {
1245
  $code = trim(str_replace(
1254
  } else if ($address['postcode']===$code) {
1255
  $this->debug(' postcode <span class="osh-replacement">'.$address['postcode'].'</span> matches');
1256
  $in_array = true;
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
  }
1292
  return null;
1293
  }
1294
 
1295
+ protected function _autoEscapeStrings($input) {
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
+
1307
  protected function _processProductProperty($products, $regex_result) {
1308
  // count, sum, min, max, count distinct
1309
  $operation = strtolower($regex_result[1]);
1390
  );
1391
  }
1392
  $from = $property[0];
1393
+ $to = $this->_autoEscapeStrings($value);
1394
+ $this->debug(' replace <span class="osh-replacement">'.$from.'</span> by <span class="osh-replacement">'.$to.'</span> =&gt; <span class="osh-formula">'.str_replace($from, '<span class="osh-replacement">'.$to.'</span>', $formula).'</span>');
1395
+ $formula = str_replace($from, $to, $formula);
 
 
 
 
 
 
 
 
1396
  }
1397
  $eval_result = $this->_evalFormula($formula);
1398
  if (!isset($eval_result)) $return_value = 'null';
1406
  if ($property_type=='quantity') {
1407
  $value = $product->getQuantity();
1408
  } else {
1409
+ $value = $this->_getProductProperty($product, $property_type, $property_name);
1410
  }
1411
  switch ($operation) {
1412
  case 'min':
1422
  case 'count distinct':
1423
  if (!isset($return_value)) $return_value = 0;
1424
  if (!isset($distinct_values)) $distinct_values = array();
1425
+ if (!in_array($value, $distinct_values)) {
1426
  $distinct_values[] = $value;
1427
  $return_value++;
1428
  }
1473
  }
1474
 
1475
  public function toString() {
1476
+ return vsprintf($this->message, $this->args);
1477
  }
1478
  }
1479
 
app/locale/fr_FR/Owebia_Shipping2.csv CHANGED
@@ -107,21 +107,22 @@
107
  <li><a href=""#"" onclick=""os2editor.help('property.label');"">Le libellé : `label`</a></li>
108
  <li><a href=""#"" onclick=""os2editor.help('property.fees');"">Les frais de port : `fees`</a>
109
  <ul>
110
- <li><a href=""#"" onclick=""os2editor.help('more.formulas');"">Initiation aux formules</a>
111
  <ul>
112
- <li><a href=""#"" onclick=""os2editor.help('more.special-functions');"">Fonctions spéciales dans les formules (min, max)</a></li>
113
  </ul>
114
  </li>
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.attributes-options');"">Utilisation des attributs ou des options des produits (sum, count, min, max)</a> (amélioration dans la version 2.3.10)</li>
 
118
  <li><a href=""#"" onclick=""os2editor.help('more.foreach');"">Utilisation des boucles foreach</a></li>
119
  <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>
120
  <li><a href=""#"" onclick=""os2editor.help('more.custom-variables');"">Utilisation des variables personnalisées de Magento (Custom Variables)</a></li>
121
  </ul>
122
  </li>
123
  <li><a href=""#"" onclick=""os2editor.help('property.conditions');"">Les conditions : `conditions`</a></li>
124
- <li class=""new""><a href=""#"" onclick=""os2editor.help('property.destination');"">La destination : `destination`</a> (amélioration dans la version 2.4.0)</li>
125
  <li><a href=""#"" onclick=""os2editor.help('property.enabled');"">L'activation : `enabled`</a></li>
126
  <li><a href=""#"" onclick=""os2editor.help('property.code');"">Le code : `code`</a></li>
127
  <li><a href=""#"" onclick=""os2editor.help('property.description');"">La description : `description`</a></li>
@@ -300,23 +301,37 @@ Pour ce faire, utiliser les variables suivantes :</p>
300
  <ul>
301
 
302
  <li><b>{cart.weight}</b>: poids des marchandises</li>
303
- <li class=""new""><b>{cart.weight.for-charge}</b>: poids des marchandises dont la livraison n'est pas offerte (par les règles de prix panier de Magento)</li>
304
- <li><b>{cart.price_excluding_tax}</b>: prix HT (équivaut à <b>{cart.price-tax+discount}</b>)</li>
305
- <li><b>{cart.price_including_tax}</b>: prix TTC (équivaut à <b>{cart.price+tax+discount}</b>)</li>
306
- <li class=""new""><b>{cart.price-tax+discount}</b>: prix HT avec remise</li>
307
- <li class=""new""><b>{cart.price-tax-discount}</b>: prix HT sans remise</li>
308
- <li class=""new""><b>{cart.price+tax+discount}</b>: prix TTC avec remise</li>
309
- <li class=""new""><b>{cart.price+tax-discount}</b>: prix TTC sans remise</li>
310
  <li><b>{cart.quantity}</b>: nombre d'articles dans le panier</li>
311
- <li class=""new""><b>{cart.coupon}</b>: coupon de réduction</li>
312
- <li><b>{date.timestamp}</b>: timestamp UNIX de la date actuelle</li>
313
- <li><b>{date.year}</b>: année de la date actuelle</li>
314
- <li><b>{date.month}</b>: mois de la date actuelle</li>
315
- <li><b>{date.day}</b>: jour de la date actuelle</li>
316
- <li><b>{date.hour}</b>: heure de la date actuelle</li>
317
- <li><b>{date.minute}</b>: minute de la date actuelle</li>
318
- <li><b>{date.second}</b>: seconde de la date actuelle</li>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
319
  <li><b>{free_shipping}</b>: frais de port offert (par une règle dans Magento) [true/false]</li>
 
320
  </ul>
321
  <p>
322
  Vous avez la possibilité de mettre des espaces et des retours à la ligne dans les formules (pour aérer).
@@ -325,6 +340,13 @@ Pour ce faire, utiliser les variables suivantes :</p>
325
  Vous pouvez également utiliser des fonctionnalités avancées telles que les tables de tarifs, la copie d'une propriété d'une autre méthode,
326
  les fonctions spéciales, l'utilisation des attributs et des options des produits ou encore l'utilisation des variables personnalisées.
327
  </p>
 
 
 
 
 
 
 
328
 
329
  <div class=""help-footer"">
330
  <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
@@ -367,6 +389,29 @@ fees: <span class=""string"">""{table {cart.price_excluding_tax} in 15.00:5.30,
367
  fees: <span class=""string"">""{table ceil({cart.weight}/10) in 1:5.30, 2:6.50}""</span>,
368
  </div>
369
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
370
  <div class=""help-footer"">
371
  <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
372
  </div>
@@ -423,99 +468,51 @@ Liste des fonctions spéciales :
423
  <ul>
424
  <li><b>min(x,y) :</b> calcule le minimum entre plusieurs valeurs (éventuellement plus de deux valeurs). Si l'une des valeurs est nulle, elle est ignorée.</li>
425
  <li><b>max(x,y) :</b> calcule le maximum entre plusieurs valeurs (éventuellement plus de deux valeurs). Si l'une des valeurs est nulle, elle est ignorée.</li>
 
 
426
  </ul>
427
 
428
- <div class=""code""><span class=""comment""># Exemple d'utilisation de la fonction min pour proposé des frais de port gratuits<br/>
429
- # et un supplément pour les méthodes de transport plus rapides</span><br/>
430
- {<br/>
431
- &nbsp;&nbsp;&nbsp;code: <span class=""string"">""courrier_suivi""</span>,<br/>
432
- &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Courrier suivi""</span>,<br/>
433
- &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""FR""</span>,<br/>
434
- &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_including_tax}&lt;80""</span>,<br/>
435
- &nbsp;&nbsp;&nbsp;fees: <span class=""string"">""{table {cart.weight} in 0.050:2.21, 0.100:2.77, 0.500:4.60}""</span>,<br/>
436
- }<br/>
437
- <br/>
438
- {<br/>
439
- &nbsp;&nbsp;&nbsp;code: <span class=""string"">""courrier_suivi_offert""</span>,<br/>
440
- &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Frais de port offerts - Courrier suivi""</span>,<br/>
441
- &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""{courrier_suivi.destination}""</span>,<br/>
442
- &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_including_tax}&gt;=80 and {cart.weight}&lt;=0.500""</span>,<br/>
443
- &nbsp;&nbsp;&nbsp;fees: 0.00,<br/>
444
- }<br/>
445
- <br/>
446
- {<br/>
447
- &nbsp;&nbsp;&nbsp;code: <span class=""string"">""lettre_recommandee""</span>,<br/>
448
- &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Lettre Recommandée""</span>,<br/>
449
- &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""FR""</span>,<br/>
450
- &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_including_tax}&lt;80""</span>,<br/>
451
- &nbsp;&nbsp;&nbsp;fees: <span class=""string"">""{table {cart.weight} in 0.050:4.3,0.100:4.75,0.250:5.62,0.500:6.42,1.000:7.32,2.000:8.56,10.000:10.30}""</span>,<br/>
452
- }<br/>
453
- <br/>
454
  {<br/>
455
- &nbsp;&nbsp;&nbsp;code: <span class=""string"">""lettre_recommandee_offert""</span>,<br/>
456
- &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Frais de port offerts - Lettre Recommandée""</span>,<br/>
457
- &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""{lettre_recommandee.destination}""</span>,<br/>
458
- &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_including_tax}&gt;=80 and {cart.weight}&gt;0.500 and {cart.weight}&lt;=10.000""</span>,<br/>
459
- &nbsp;&nbsp;&nbsp;fees: 0.00,<br/>
460
- }<br/>
461
- <br/>
462
- {<br/>
463
- &nbsp;&nbsp;&nbsp;code: <span class=""string"">""supplement_lettre_recommandee""</span>,<br/>
464
- &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Supplément Lettre Recommandée""</span>,<br/>
465
- &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""{lettre_recommandee.destination}""</span>,<br/>
466
- &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{courrier_suivi_offert.conditions}""</span>,<br/>
467
- &nbsp;&nbsp;&nbsp;fees: <span class=""string"">""{lettre_recommandee.fees} - {courrier_suivi.fees}""</span>,<br/>
468
  }<br/>
469
  <br/>
 
470
  {<br/>
471
- &nbsp;&nbsp;&nbsp;code: <span class=""string"">""colissimo""</span>,<br/>
472
- &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Colissimo""</span>,<br/>
473
  &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""FR""</span>,<br/>
474
- &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_including_tax}&lt;80""</span>,<br/>
475
- &nbsp;&nbsp;&nbsp;fees: <span class=""string"">""{table {cart.weight} in 0.3:8.7,0.8:9.9,1.8:10.85,2.8:11.8,4.8:13.7,6.8:15.6,9.8:18.45,14.8:20.45,29.8:26.45}""</span>,<br/>
476
- }<br/>
477
- <br/>
478
- {<br/>
479
- &nbsp;&nbsp;&nbsp;code: <span class=""string"">""colissimo_offert""</span>,<br/>
480
- &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Frais de port offerts - Colissimo""</span>,<br/>
481
- &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""{colissimo.destination}""</span>,<br/>
482
- &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_including_tax}&gt;=80 and {cart.weight}&gt;10 and {cart.weight}&lt;=29.8""</span>,<br/>
483
- &nbsp;&nbsp;&nbsp;fees: 0.00,<br/>
484
  }<br/>
485
  <br/>
 
486
  {<br/>
487
- &nbsp;&nbsp;&nbsp;code: <span class=""string"">""supplement_colissimo""</span>,<br/>
488
- &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Supplément Colissimo""</span>,<br/>
489
- &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""{colissimo.destination}""</span>,<br/>
490
- &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{courrier_suivi_offert.conditions} or {lettre_recommandee_offert.conditions}""</span>,<br/>
491
- &nbsp;&nbsp;&nbsp;fees: <span class=""string"">""{colissimo.fees} - min({courrier_suivi.fees},{lettre_recommandee.fees})""</span>,<br/>
492
- }<br/>
493
- <br/>
494
- {<br/>
495
- &nbsp;&nbsp;&nbsp;code: <span class=""string"">""chronopost""</span>,<br/>
496
- &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Chronopost""</span>,<br/>
497
  &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""FR""</span>,<br/>
498
- &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_including_tax}&lt;80""</span>,<br/>
499
- &nbsp;&nbsp;&nbsp;fees: <span class=""string"">""{table {cart.weight} in 1:13.29, 2:13.99, 3:18.4, 4:19.24, 5:20.08, 6:20.92, 7:21.76, 8:22.6, 9:23.44, 10:24.28, 15:28.48, 20:32.68, 25:36.88, 30:41.08}""</span>,<br/>
500
  }<br/>
501
  <br/>
 
502
  {<br/>
503
- &nbsp;&nbsp;&nbsp;code: <span class=""string"">""chronopost_offert""</span>,<br/>
504
- &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Frais de port offerts - Chronopost""</span>,<br/>
505
  &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""FR""</span>,<br/>
506
- &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{cart.price_including_tax}&lt;80 and {cart.weight}&gt;29.8 and {cart.weight}&lt;=30""</span>,<br/>
507
- &nbsp;&nbsp;&nbsp;fees: 0.00,<br/>
508
  }<br/>
509
- <br/>
510
- {<br/>
511
- &nbsp;&nbsp;&nbsp;code: <span class=""string"">""supplement_chronopost""</span>,<br/>
512
- &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Supplément Chronopost""</span>,<br/>
513
- &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""{chronopost.destination}""</span>,<br/>
514
- &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""{courrier_suivi_offert.conditions} or {lettre_recommandee_offert.conditions} or {colissimo_offert.conditions}""</span>,<br/>
515
- &nbsp;&nbsp;&nbsp;fees: <span class=""string"">""{chronopost.fees} - min({courrier_suivi.fees},{lettre_recommandee.fees},{colissimo.fees})""</span>,<br/>
516
- }
517
  </div>
518
 
 
 
 
 
519
  <div class=""help-footer"">
520
  <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
521
  </div>
107
  <li><a href=""#"" onclick=""os2editor.help('property.label');"">Le libellé : `label`</a></li>
108
  <li><a href=""#"" onclick=""os2editor.help('property.fees');"">Les frais de port : `fees`</a>
109
  <ul>
110
+ <li class=""new""><a href=""#"" onclick=""os2editor.help('more.formulas');"">Initiation aux formules</a> (utilisation des chaînes de caractères avec la version 2.4.5)
111
  <ul>
112
+ <li><a href=""#"" onclick=""os2editor.help('more.special-functions');"">Fonctions spéciales dans les formules (min, max, substr, in_array)</a> (substr et in_array depuis la version 2.4.5)</li>
113
  </ul>
114
  </li>
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>
123
  </li>
124
  <li><a href=""#"" onclick=""os2editor.help('property.conditions');"">Les conditions : `conditions`</a></li>
125
+ <li class=""new""><a href=""#"" onclick=""os2editor.help('property.destination');"">La destination : `destination`</a> (expressions régulières depuis la version 2.4.0)</li>
126
  <li><a href=""#"" onclick=""os2editor.help('property.enabled');"">L'activation : `enabled`</a></li>
127
  <li><a href=""#"" onclick=""os2editor.help('property.code');"">Le code : `code`</a></li>
128
  <li><a href=""#"" onclick=""os2editor.help('property.description');"">La description : `description`</a></li>
301
  <ul>
302
 
303
  <li><b>{cart.weight}</b>: poids des marchandises</li>
304
+ <li><b>{cart.weight.for-charge}</b>: poids des marchandises dont la livraison n'est pas offerte (par les règles de prix panier de Magento)</li>
 
 
 
 
 
 
305
  <li><b>{cart.quantity}</b>: nombre d'articles dans le panier</li>
306
+ <li><b>{cart.coupon}</b>: coupon de réduction (chaîne de caractère)</li>
307
+ <li>Prix :
308
+ <ul>
309
+ <li><b>{cart.price_excluding_tax}</b>: prix HT (équivaut à <b>{cart.price-tax+discount}</b>)</li>
310
+ <li><b>{cart.price_including_tax}</b>: prix TTC (équivaut à <b>{cart.price+tax+discount}</b>)</li>
311
+ <li><b>{cart.price-tax+discount}</b> : prix HT après remise</li>
312
+ <li><b>{cart.price-tax-discount}</b> : prix HT avant remise</li>
313
+ <li><b>{cart.price+tax+discount}</b> : prix TTC après remise</li>
314
+ <li><b>{cart.price+tax-discount}</b>: prix TTC avant remise</li>
315
+ </ul>
316
+ </li>
317
+ <li>Date courante :
318
+ <ul>
319
+ <li><b>{date.timestamp}</b>: timestamp UNIX de la date actuelle</li>
320
+ <li><b>{date.year}</b>, <b>{date.month}</b>, <b>{date.day}</b>, <b>{date.hour}</b>, <b>{date.minute}</b>, <b>{date.second}</b>: année, mois, jour, heure, minute et seconde de la date actuelle</li>
321
+ </ul>
322
+ </li>
323
+ <li>Destination :
324
+ <ul>
325
+ <li><b>{destination.country.code}</b>: code du pays de destination</li>
326
+ <li><b>{destination.country.name}</b>: nom du pays de destination</li>
327
+ <li><b>{destination.region.code}</b>: code de la région de destination</li>
328
+ <li><b>{destination.postcode}</b>: code postal de destination</li>
329
+ </ul>
330
+ </li>
331
+ <li>Origine (idem destination) : <b>{origin.country.code}</b>, <b>{origin.country.name}</b>, <b>{origin.region.code}</b>, <b>{origin.postcode}</b></li>
332
+ </li>
333
  <li><b>{free_shipping}</b>: frais de port offert (par une règle dans Magento) [true/false]</li>
334
+ <li>Autres variables en vrac : {cart.weight.unit}, {customer.group.id}, {customer.group.code}, {store.id}, {store.code}, {store.name}, {store.address}, {store.phone}</li>
335
  </ul>
336
  <p>
337
  Vous avez la possibilité de mettre des espaces et des retours à la ligne dans les formules (pour aérer).
340
  Vous pouvez également utiliser des fonctionnalités avancées telles que les tables de tarifs, la copie d'une propriété d'une autre méthode,
341
  les fonctions spéciales, l'utilisation des attributs et des options des produits ou encore l'utilisation des variables personnalisées.
342
  </p>
343
+ <p class=""new"" style=""font-weight: bold;"">
344
+ Lorsque vous utilisez des variables qui ne sont pas numériques ou booléennes, vous devez les échapper avec des guillemets simples ou utiliser la syntaxe d'auto-échappement <span class=""code"">{{ }}</span>.
345
+ </p>
346
+ <div class=""code""><span class=""comment""># Échappement avec des guillemets</span><br/>conditions: <span class=""string"">""'{cart.coupon}'=='test'""</span>,<br/>
347
+ <br/>
348
+ <span class=""comment""># Auto-échappement (depuis la version 2.4.5), {{cart.coupon}} sera remplacé par 'moncoupon' ou par null en fonction de sa valeur</span><br/>conditions: <span class=""string"">""{{cart.coupon}}=='test'""</span>,
349
+ </div>
350
 
351
  <div class=""help-footer"">
352
  <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
389
  fees: <span class=""string"">""{table ceil({cart.weight}/10) in 1:5.30, 2:6.50}""</span>,
390
  </div>
391
 
392
+ <div class=""help-footer"">
393
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
394
+ </div>
395
+ "
396
+ "{os2editor.help.more.switch}","
397
+ <div class=""help-header"">
398
+ <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
399
+ </div>
400
+
401
+ <h4>Utilisation des ""switch"" (tables de correspondances)</h4>
402
+
403
+ <p>
404
+ Dans un switch, on doit spécifier la valeur de référence. Pour cela, on peut utiliser une des variables disponibles.<br/>
405
+ Vous pouvez aussi utiliser une formule afin de définir une autre variable de référence.
406
+ </p>
407
+
408
+ <div class=""code""><span class=""comment""># Table de correpondance avec le coupon</span><br/>
409
+ fees: <span class=""string"">""{switch {{cart.coupon}} in 'coupon1':5.30, 'coupon2':6.50, null:10.00, *:7.50}""</span>,<br/>
410
+ <br/>
411
+ <span class=""comment""># Table de correpondance avec le pays de destination</span><br/>
412
+ fees: <span class=""string"">""{switch {{destination.country.code}} in 'FR':5.30, 'BE':6.50, 'DE':10.00, *:7.50}""</span>,
413
+ </div>
414
+
415
  <div class=""help-footer"">
416
  <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
417
  </div>
468
  <ul>
469
  <li><b>min(x,y) :</b> calcule le minimum entre plusieurs valeurs (éventuellement plus de deux valeurs). Si l'une des valeurs est nulle, elle est ignorée.</li>
470
  <li><b>max(x,y) :</b> calcule le maximum entre plusieurs valeurs (éventuellement plus de deux valeurs). Si l'une des valeurs est nulle, elle est ignorée.</li>
471
+ <li class=""new""><b>substr(string, start, length) :</b> retourne un segment de chaîne de caractères.</li>
472
+ <li class=""new""><b>in_array(value, array(value1, value2)) :</b> indique si une valeur appartient à un tableau.</li>
473
  </ul>
474
 
475
+ <div class=""code""><span class=""comment""># Exemple d'utilisation de la fonction min<br/>
476
+ [...]<br/>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
477
  {<br/>
478
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""exemple""</span>,<br/>
479
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Exemple""</span>,<br/>
480
+ &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""{chronopost.destination}""</span>,<br/>
481
+ &nbsp;&nbsp;&nbsp;fees: <span class=""string"">""min({cart.weight},{cart.price},{cart.quantity})""</span>,<br/>
 
 
 
 
 
 
 
 
 
482
  }<br/>
483
  <br/>
484
+ <span class=""comment""># Exemple d'utilisation de la fonction substr *<br/>
485
  {<br/>
486
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""free_shipping""</span>,<br/>
487
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Port offert""</span>,<br/>
488
  &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""FR""</span>,<br/>
489
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""substr('{cart.coupon}', 0, 5)=='free_'""</span>,<br/>
490
+ &nbsp;&nbsp;&nbsp;fees: <span class=""string"">""0""</span>,<br/>
 
 
 
 
 
 
 
 
491
  }<br/>
492
  <br/>
493
+ <span class=""comment""># Exemple d'utilisation de la fonction in_array avec des chaînes de caractères *<br/>
494
  {<br/>
495
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""free_shipping""</span>,<br/>
496
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Port offert""</span>,<br/>
 
 
 
 
 
 
 
 
497
  &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""FR""</span>,<br/>
498
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""in_array({{cart.coupon}}, array('free1', 'free2'))""</span>,<br/>
499
+ &nbsp;&nbsp;&nbsp;fees: <span class=""string"">""0""</span>,<br/>
500
  }<br/>
501
  <br/>
502
+ <span class=""comment""># Exemple d'utilisation de la fonction in_array avec des nombres<br/>
503
  {<br/>
504
+ &nbsp;&nbsp;&nbsp;code: <span class=""string"">""free_shipping""</span>,<br/>
505
+ &nbsp;&nbsp;&nbsp;label: <span class=""string"">""Port offert""</span>,<br/>
506
  &nbsp;&nbsp;&nbsp;destination: <span class=""string"">""FR""</span>,<br/>
507
+ &nbsp;&nbsp;&nbsp;conditions: <span class=""string"">""in_array({cart.quantity}, array(10,20,30))""</span>,<br/>
508
+ &nbsp;&nbsp;&nbsp;fees: <span class=""string"">""0""</span>,<br/>
509
  }<br/>
 
 
 
 
 
 
 
 
510
  </div>
511
 
512
+ <p class=""new"">
513
+ * Concernant l'échappement des chaînes de caractères, se référer à l'<a href=""#"" onclick=""os2editor.help('more.formulas');"">inititation aux formules</a>.
514
+ </p>
515
+
516
  <div class=""help-footer"">
517
  <p><a href=""#"" onclick=""os2editor.help('summary');"">Sommaire</a></p>
518
  </div>
js/owebia/shipping2/os2editor.css CHANGED
@@ -409,6 +409,10 @@
409
  margin: 0 0 15px 20px;
410
  list-style: disc;
411
  }
 
 
 
 
412
 
413
  #os2-editor .os2editor-page h4 {
414
  padding: 0 0 2px 0;
@@ -452,6 +456,7 @@
452
  }
453
  #os2-editor .table-of-contents ul ul {
454
  margin: 3px 0 5px 15px;
 
455
  }
456
  #os2-editor .table-of-contents li {
457
  padding: 2px 0;
409
  margin: 0 0 15px 20px;
410
  list-style: disc;
411
  }
412
+ #os2-editor .os2editor-page ul ul {
413
+ margin: 0 0 3px 20px;
414
+ list-style: circle;
415
+ }
416
 
417
  #os2-editor .os2editor-page h4 {
418
  padding: 0 0 2px 0;
456
  }
457
  #os2-editor .table-of-contents ul ul {
458
  margin: 3px 0 5px 15px;
459
+ list-style: none;
460
  }
461
  #os2-editor .table-of-contents li {
462
  padding: 2px 0;
package.xml CHANGED
@@ -1,22 +1,24 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Owebia_Shipping_2</name>
4
- <version>2.4.4</version>
5
  <stability>stable</stability>
6
- <license uri="http://www.opensource.org/licenses/osl-3.0.php">Open Software License (OSL 3.0)</license>
7
  <channel>community</channel>
8
  <extends/>
9
  <summary>Shipping Methods / Modes de livraison : Colissimo, Chronopost, Export 3J</summary>
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.4 - 30 novembre 2011]
14
- Correction d'un bug avec l'utilisation de product.category.id
15
- Ajout des valeurs memory_limit et memory_usage dans le debug</notes>
 
 
16
  <authors><author><name>owebia</name><user>auto-converted</user><email>antoine.lemoine@owebia.com</email></author></authors>
17
- <date>2011-11-30</date>
18
- <time>15:25:52</time>
19
- <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="cfbb6a96b517b1e00478556dd6fdfb6d"/></dir></target><target name="mage"><dir name="js"><dir name="owebia"><dir name="shipping2"><file name="os2editor.css" hash="1c1b01fcf4971a50e730ad0588c0eb5b"/><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="fcff55f860bfb743b34245e6ce2e5d5b"/></dir></dir></dir></dir></dir></dir><dir name="Controller"><file name="Abstract.php" hash="f8fa0d63caf4585e9ac42fae2e970a23"/></dir><dir name="controllers"><dir name="Checkout"><file name="CartController.php" hash="8c6ee136298e0e2dd0052143887282ce"/></dir><file name="AjaxController.php" hash="aec2cb9e8c7f0fb2ab0ffad1fa3bb43e"/></dir><dir name="etc"><file name="adminhtml.xml" hash="ed61385695adc726513ecb0d80b5471b"/><file name="config.xml" hash="ba6820caf10b9a1af5ddf9b609b12649"/><file name="system.xml" hash="67f66b677ed950ecce17d8dc50ea1061"/></dir><dir name="includes"><dir name="cache"><file name="countries" hash="6b1a5494b6dddcc65f2946dbf0226c29"/></dir><file name="OS2_AddressFilter.php" hash="bb26bb2da522049ea6da82092503e35e"/><file name="OS2_CustomerGroup.php" hash="f39c69309ea1d268654917231834f802"/><file name="OwebiaShippingHelper.php" hash="233ac860a668941a8d7e1bbcba056ed3"/></dir><dir name="Model"><dir name="Carrier"><file name="AbstractOwebiaShipping.php" hash="fec2a7ad0a7d923b2f596162081d6294"/><file name="OwebiaShipping1.php" hash="2e6caa067fdfae4673b8f8db52f7a3fe"/><file name="OwebiaShipping2.php" hash="310917d67dcf22bed6cbf5adefb90bde"/><file name="OwebiaShipping3.php" hash="e8ecfbac4088df56c609b04e688cc04b"/></dir></dir><file name="changelog" hash="93cd414f9b219da1d129ba340ff3f1f7"/></dir></dir></target></contents>
20
  <compatible/>
21
  <dependencies/>
22
  </package>
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>
8
  <extends/>
9
  <summary>Shipping Methods / Modes de livraison : Colissimo, Chronopost, Export 3J</summary>
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>