Owebia_Shipping_2 - Version 2.5.22

Version Notes

[2.5.22 - July 18, 2016]
Add composer.json and modman files

[2.5.21 - May 9, 2016]
Fix replacement of special functions, thanks to Sébastien L.

[2.5.20 - 25 avril 2016]
Fix code indentation
Fix version number
Add readme file in package

[2.5.19 - 09 novembre 2015]
Note: the extension is not affected by the patch SUPEE-6788 since it uses the new admin url routing syntax for 3 years (version 2.4.8.0)
Fix bug: deactivation of auto-escaping by default since it can cause some bugs (ex: impossible to use {address_filter.EU-27} in shipto)
Fix bug: fix auto-escaping of properties like {{shipto.country_name}}
Fix bug: variable replacements in labels (variables {cart.price-tax-discount}, {cart.price-tax+discount}, {cart.price+tax-discount} and {cart.price+tax+discount})
Fix bug: use items and not quote to retrieve values {cart.price-tax-discount}, {cart.price-tax+discount}, {cart.price+tax-discount} and {cart.price+tax+discount} (quote totals are not available at this time, calculating them causes duplications of addresses and a false grand_total value)
Fix bug: retrieve customer in backoffice order
Fix unicode accented chars in json_encode for PHP < 5.4
Fix bug: usage of regular expressions inside {count ...}, {sum ...}, {min ...} and {max ...}
Allow usage of php functions date and strtotime (ex: "label": "'Your package will be delivered between ' . date('d/m', strtotime('+5 days')) . ' and ' . date('d/m Y', strtotime('+7 days'))",

Download this release

Release Info

Developer owebia
Extension Owebia_Shipping_2
Version 2.5.22
Comparing to
See all releases


Code changes from version 2.5.19 to 2.5.22

Files changed (50) hide show
  1. README.md +36 -0
  2. app/code/community/Owebia/Shipping2/Block/Adminhtml/Os2/Editor.php +245 -234
  3. app/code/community/Owebia/Shipping2/Block/Adminhtml/Os2/Editor/Property/Input.php +4 -3
  4. app/code/community/Owebia/Shipping2/Block/Adminhtml/Os2/Help.php +83 -83
  5. app/code/community/Owebia/Shipping2/Block/Adminhtml/System/Config/Form/Field/Config.php +61 -57
  6. app/code/community/Owebia/Shipping2/Block/Adminhtml/System/Config/Form/Field/Informations.php +10 -10
  7. app/code/community/Owebia/Shipping2/Controller/Abstract.php +96 -97
  8. app/code/community/Owebia/Shipping2/Helper/Data.php +134 -134
  9. app/code/community/Owebia/Shipping2/Model/Carrier/Abstract.php +187 -187
  10. app/code/community/Owebia/Shipping2/Model/Carrier/OwebiaShipping1.php +1 -1
  11. app/code/community/Owebia/Shipping2/Model/Carrier/OwebiaShipping2.php +1 -1
  12. app/code/community/Owebia/Shipping2/Model/Carrier/OwebiaShipping3.php +1 -1
  13. app/code/community/Owebia/Shipping2/Model/Carrier/OwebiaShipping4.php +0 -25
  14. app/code/community/Owebia/Shipping2/Model/Mysql4/Setup.php +1 -1
  15. app/code/community/Owebia/Shipping2/Model/Os2/Data/Abstract.php +51 -47
  16. app/code/community/Owebia/Shipping2/Model/Os2/Data/AbstractWithAttributes.php +40 -40
  17. app/code/community/Owebia/Shipping2/Model/Os2/Data/Address.php +9 -10
  18. app/code/community/Owebia/Shipping2/Model/Os2/Data/AddressFilter.php +83 -83
  19. app/code/community/Owebia/Shipping2/Model/Os2/Data/AttributeSet.php +13 -11
  20. app/code/community/Owebia/Shipping2/Model/Os2/Data/Billto.php +6 -13
  21. app/code/community/Owebia/Shipping2/Model/Os2/Data/Cart.php +115 -115
  22. app/code/community/Owebia/Shipping2/Model/Os2/Data/CartItem.php +124 -119
  23. app/code/community/Owebia/Shipping2/Model/Os2/Data/Category.php +8 -8
  24. app/code/community/Owebia/Shipping2/Model/Os2/Data/Customer.php +15 -15
  25. app/code/community/Owebia/Shipping2/Model/Os2/Data/CustomerGroup.php +50 -50
  26. app/code/community/Owebia/Shipping2/Model/Os2/Data/Customvar.php +10 -10
  27. app/code/community/Owebia/Shipping2/Model/Os2/Data/Date.php +24 -23
  28. app/code/community/Owebia/Shipping2/Model/Os2/Data/Info.php +0 -2
  29. app/code/community/Owebia/Shipping2/Model/Os2/Data/Product.php +93 -86
  30. app/code/community/Owebia/Shipping2/Model/Os2/Data/Quote.php +6 -6
  31. app/code/community/Owebia/Shipping2/Model/Os2/Data/Selection.php +4 -5
  32. app/code/community/Owebia/Shipping2/Model/Os2/Data/StockItem.php +14 -14
  33. app/code/community/Owebia/Shipping2/Model/Os2/Data/Store.php +25 -25
  34. app/code/community/Owebia/Shipping2/Model/System/Config/Source/LoadOnParent.php +14 -13
  35. app/code/community/Owebia/Shipping2/Model/System/Config/Source/ProcessChildren.php +14 -13
  36. app/code/community/Owebia/Shipping2/changelog +24 -13
  37. app/code/community/Owebia/Shipping2/controllers/Adminhtml/Os2/AjaxController.php +169 -169
  38. app/code/community/Owebia/Shipping2/controllers/Checkout/CartController.php +5 -5
  39. app/code/community/Owebia/Shipping2/doc_en_US.html +1094 -1072
  40. app/code/community/Owebia/Shipping2/doc_fr_FR.html +1106 -1084
  41. app/code/community/Owebia/Shipping2/etc/adminhtml.xml +29 -29
  42. app/code/community/Owebia/Shipping2/etc/config.xml +168 -183
  43. app/code/community/Owebia/Shipping2/etc/system.xml +461 -570
  44. app/code/community/Owebia/Shipping2/includes/OS2_AddressFilterParser.php +122 -122
  45. app/code/community/Owebia/Shipping2/includes/OwebiaShippingHelper.php +1425 -1429
  46. app/code/community/Owebia/Shipping2/sql/owebia_shipping2_setup/mysql4-install-2.5.13.php +0 -1
  47. app/etc/modules/Owebia_Shipping2.xml +7 -7
  48. app/locale/en_US/Owebia_Shipping2.csv +454 -454
  49. app/locale/fr_FR/Owebia_Shipping2.csv +467 -467
  50. package.xml +16 -5
README.md ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ # ENGLISH
3
+
4
+ ## How to manually install the extension?
5
+
6
+ - Backup your store database and web directory
7
+ - Login to Magento backend
8
+ - Go to System > Tools > Compilations, if Compiler Status is Enabled, disable the compilation
9
+ - Uncompress the archive file, then copy the directory "app" in your Magento root directory
10
+ - Go to System > Cache Management. Click button Flush Magento Cache
11
+ - Logout from Magento backend and login again
12
+
13
+ ## How to completely uninstall the extension ?
14
+ After having uninstalled the extension in Magento Connect Manager, some references remain in the database.
15
+ To solve this problem, you must execute the following MySQL query:
16
+
17
+ DELETE FROM `core_config_data` WHERE `path` LIKE 'carriers/owebiashipping_/%'
18
+
19
+ --------------------------
20
+
21
+ # FRANCAIS
22
+
23
+ ## Comment installer l'extension manuellement ?
24
+
25
+ - Faites une sauvegarde de votre boutique et de votre répertoire web
26
+ - Connectez-vous au panneau d'administration de Magento
27
+ - Allez dans Système > Outils > Compilation, désactiver le compilateur s'il est activé
28
+ - Décompresser l'archive, puis copier le répertoire "app" dans le répertoire racine de votre boutique Magento
29
+ - Allez dans Système > Gestion du cache. Cliquer sur le bouton Vider le cache de Magento
30
+ - Déconnectez-vous du panneau d'administration de Magento puis connectez-vous à nouveau
31
+
32
+ ## Comment désinstaller complètement l’extension ?
33
+ Après avoir désinstallé l’extension depuis Magento Connect Manager, il reste encore des références dans la base de donnée.
34
+ Pour solutionner ce problème, il faut exécuter la requête MySQL suivante :
35
+
36
+ DELETE FROM `core_config_data` WHERE `path` LIKE 'carriers/owebiashipping_/%'
app/code/community/Owebia/Shipping2/Block/Adminhtml/Os2/Editor.php CHANGED
@@ -21,250 +21,261 @@
21
 
22
  class Owebia_Shipping2_Block_Adminhtml_Os2_Editor extends Mage_Adminhtml_Block_Abstract
23
  {
24
- protected $_config;
25
- protected $_opened_row_ids;
26
 
27
- public function __construct($attributes) {
28
- $attributes = $attributes + array(
29
- 'config' => '',
30
- 'opened_row_ids' => array(),
31
- );
32
- $this->_config = $attributes['config'];
33
- $this->_opened_row_ids = $attributes['opened_row_ids'];
34
- }
 
35
 
36
- public function __() {
37
- $args = func_get_args();
38
- return Mage::helper('owebia_shipping2')->__($args);
39
- }
 
40
 
41
- private function _getPropertyInput($property_name, $property) {
42
- if (is_array($property)) { // Compatibility PHP 5.2
43
- $value = isset($property['original_value']) ? $property['original_value'] : (isset($property['value']) ? $property['value'] : (isset($property) ? $property : ''));
44
- } else {
45
- $value = $property;
46
- }
 
47
 
48
- $toolbar = "<span class=\"os2-field-btn os2-field-help\" data-property=\"{$property_name}\"></span>";
49
- switch ($property_name) {
50
- case 'enabled':
51
- $enabled = $value!==false;
52
- $input = "<select class=field name=\"{$property_name}\">"
53
- ."<option value=\"1\"".($enabled ? ' selected="selected"' : '').">".$this->__('Enabled (default)')."</option>"
54
- ."<option value=\"0\"".($enabled ? '' : ' selected="selected"').">".$this->__('Disabled')."</option>"
55
- ."</select>";
56
- break;
57
- case 'type':
58
- $input = "<select class=field name=\"{$property_name}\">"
59
- ."<option value=method".($value=='method' || !$value ? '' : ' selected="selected"').">".$this->__('Shipping Method (default)')."</option>"
60
- ."<option value=data".($value=='data' ? ' selected="selected"' : '').">".$this->__('Data')."</option>"
61
- ."<option value=meta".($value=='meta' ? ' selected="selected"' : '').">".$this->__('Meta')."</option>"
62
- ."</select>";
63
- break;
64
- case 'shipto':
65
- case 'billto':
66
- case 'origin':
67
- $toolbar = "<span class=\"os2-field-btn os2-field-edit\"></span>".$toolbar;
68
- default:
69
- $input = "<input class=field name=\"{$property_name}\" value=\"".htmlspecialchars($value, ENT_COMPAT, 'UTF-8')."\"/>";
70
- break;
71
- }
72
- return $input;
73
- }
74
-
75
- public function getPropertyTools($controller, $property_name) {
76
- $after = '';
77
- switch ($property_name) {
78
- case 'label':
79
- case 'description':
80
- $after = "<fieldset class=buttons-set><legend>".$this->__('Insert')."</legend>"
81
- ."<p>"
82
- .$controller->button__('Shipping country',"os2editor.insertAtCaret(this,'{shipto.country_name}');",'os2-insert')
83
- .$controller->button__('Cart weight',"os2editor.insertAtCaret(this,'{cart.weight}');",'os2-insert')
84
- .$controller->button__('Products quantity',"os2editor.insertAtCaret(this,'{cart.qty}');",'os2-insert')
85
- .$controller->button__('Price incl. tax',"os2editor.insertAtCaret(this,'{cart.price+tax+discount}');",'os2-insert')
86
- .$controller->button__('Price excl. tax',"os2editor.insertAtCaret(this,'{cart.price-tax+discount}');",'os2-insert')
87
- ."</p>"
88
- ."</fieldset>";
89
- break;
90
- case 'fees':
91
- $after = "<fieldset class=buttons-set><legend>".$this->__('Insert')."</legend>"
92
- ."<p>"
93
- .$controller->button__('Weight',"os2editor.insertAtCaret(this,'{cart.weight}');",'os2-insert')
94
- .$controller->button__('Products quantity',"os2editor.insertAtCaret(this,'{cart.qty}');",'os2-insert')
95
- .$controller->button__('Price incl. tax',"os2editor.insertAtCaret(this,'{cart.price+tax+discount}');",'os2-insert')
96
- .$controller->button__('Price excl. tax',"os2editor.insertAtCaret(this,'{cart.price-tax+discount}');",'os2-insert')
97
- ."</p>"
98
- ."</fieldset>";
99
- break;
100
- case 'conditions':
101
- $after = "<fieldset class=buttons-set><legend>".$this->__('Insert')."</legend>"
102
- ."<p>"
103
- .$controller->button__('Weight',"os2editor.insertAtCaret(this,'{cart.weight}');",'os2-insert')
104
- .$controller->button__('Products quantity',"os2editor.insertAtCaret(this,'{cart.qty}');",'os2-insert')
105
- .$controller->button__('Price incl. tax',"os2editor.insertAtCaret(this,'{cart.price+tax+discount}');",'os2-insert')
106
- .$controller->button__('Price excl. tax',"os2editor.insertAtCaret(this,'{cart.price-tax+discount}');",'os2-insert')
107
- ."</p>"
108
- ."</fieldset>";
109
- break;
110
- case 'customer_groups':
111
- $model = Mage::getModel('owebia_shipping2/Os2_Data_CustomerGroup');
112
- $groups = (array)$model->getCollection();
113
- $output = '';
114
- foreach ($groups as $id => $name) {
115
- $output .= $controller->button($this->esc($name.' ('.$id.')'),"os2editor.insertAtCaret(this,'".$this->jsEscape($id)."');",'os2-insert');
116
- }
117
- $after = "<fieldset class=buttons-set><legend>".$this->__('Tools')."</legend>"
118
- ."<p>"
119
- .$controller->button__('Human readable version',"os2editor.getReadableSelection(this);")
120
- ."</p><div id=os2-output></div>"
121
- ."</fieldset>"
122
- ."<fieldset class=buttons-set><legend>".$this->__('Insert')."</legend>"
123
- ."<p>{$output}</p>"
124
- ."</fieldset>"
125
- ;
126
- break;
127
- case 'tracking_url':
128
- $after = "<fieldset class=buttons-set><legend>".$this->__('Insert')."</legend>"
129
- ."<p>"
130
- .$controller->button__('Tracking number',"os2editor.insertAtCaret(this,'{tracking_number}');",'os2-insert')
131
- ."</p>"
132
- ."</fieldset>";
133
- break;
134
- case 'shipto':
135
- case 'billto':
136
- case 'origin':
137
- $after = "<fieldset class=buttons-set><legend>".$this->__('Tools')."</legend>"
138
- ."<p>"
139
- .$controller->button__('Human readable version',"os2editor.getReadableSelection(this);")
140
- ."</p><div id=os2-output></div>"
141
- ."</fieldset>"
142
- ;
143
- break;
144
- case 'about':
145
- break;
146
- }
147
- return $after;
148
- }
 
149
 
150
- public function sortProperties($k1, $k2) {
151
- $i1 = isset($this->properties_sort[$k1]) ? $this->properties_sort[$k1] : 1000;
152
- $i2 = isset($this->properties_sort[$k2]) ? $this->properties_sort[$k2] : 1000;
153
- return $i1==$i2 ? strcmp($k1, $k2) : $i1-$i2;
154
- }
 
155
 
156
- protected function _getRowUI(&$row) {
157
- $properties = array('*id', 'type', 'about', 'enabled');
158
- $type = isset($row['type']['value']) ? $row['type']['value'] : null;
159
- switch ($type) {
160
- case 'meta':
161
- $row_label = $this->__('[meta] %s', $row['*id']);
162
- break;
163
- case 'data':
164
- $row_label = $this->__('[data] %s', $row['*id']);
165
- break;
166
- default:
167
- if (!isset($row['label'])) {
168
- $row['label']['value'] = $this->__('New shipping method');
169
- }
170
- $row_label = $row['label']['value'];
171
- $properties = array_merge($properties, array('label', 'description', 'shipto', 'billto', 'origin', 'conditions', 'fees', 'customer_groups', 'tracking_url'));
172
- }
 
173
 
174
- $properties_label = array(
175
- '*id' => 'ID',
176
- 'type' => 'Type',
177
- 'about' => 'About',
178
- 'enabled' => 'Enabled',
179
- 'label' => 'Label',
180
- 'description' => 'Description',
181
- 'shipto' => 'Shipping address',
182
- 'billto' => 'Billing address',
183
- 'origin' => 'Origin address',
184
- 'conditions' => 'Conditions',
185
- 'fees' => 'Fees',
186
- 'customer_groups' => 'Customer groups',
187
- 'tracking_url' => 'Tracking url',
188
- );
189
- foreach ($properties as $property_name) {
190
- if (!isset($row[$property_name])) $row[$property_name] = null;
191
- }
192
- $this->properties_sort = array_flip($properties);
193
- uksort($row, array($this, 'sortProperties'));
194
- $list = '';
195
- $content = '';
196
- $j = 0;
197
- foreach ($row as $property_name => $property) {
198
- $property_label = isset($properties_label[$property_name]) ? $properties_label[$property_name] : $property_name;
199
- $error = array();
200
- if (isset($property['messages'])) {
201
- foreach ($property['messages'] as $message) {
202
- $error[] = $this->__($message);
203
- }
204
- }
205
- $content .= "<tr class=\"os2-p-container".($error ? ' os2-error' : '')."\"".($error ? ' title="'.$this->esc(implode(', ', $error)).'"' : '')."><th>".$this->__($property_label)."</th><td>".$this->_getPropertyInput($property_name, $property, $big = false)."</td></tr>";
206
- $j++;
207
- }
208
- //$output = "<ul class=\"properties-list ui-layout-west\">{$list}</ul><div class=\"properties-container ui-layout-center\">{$content}</div>";
209
- $output = "<table class=properties-container>{$content}</table>";
210
- return $output;
211
- }
212
 
213
- protected function _getRowItem($row, $opened) {
214
- $type = isset($row['type']['value']) ? $row['type']['value'] : null;
215
- switch ($type) {
216
- case 'meta':
217
- $label = $this->__('[meta] %s', $row['*id']);
218
- break;
219
- case 'data':
220
- $label = $this->__('[data] %s', $row['*id']);
221
- break;
222
- default:
223
- $label = isset($row['label']['value']) ? $row['label']['value'] : $this->__('New shipping method');
224
- break;
225
- }
226
- $content = '';
227
- if ($opened) {
228
- $content = $this->_getRowUI($row);
229
- }
230
- $error = false;
231
- foreach ($row as $property_name => $property) {
232
- if (is_array($property) /*Compatibility*/ && isset($property['messages'])) {
233
- $error = true;
234
- break;
235
- }
236
- }
237
- return "<li data-id=\"{$row['*id']}\"".($error ? ' class=os2-error' : '')."><h5><button class=\"os2-remove-row-btn\" title=\"{$this->__('Remove')}\"></button>".$label."</h5><div class=\"row-ui".($opened ? ' opened' : '')."\">{$content}</div></li>";
238
- }
 
239
 
240
- protected function esc($input) {
241
- return htmlspecialchars($input, ENT_COMPAT, 'UTF-8');
242
- }
 
243
 
244
- protected function jsEscape($input) {
245
- return str_replace(array("\r\n","\r","\n","'"),array("\\n","\\n","\\n","\\'"),$input);
246
- }
 
247
 
248
- public function getRowUI(&$row) {
249
- return $this->_getRowUI($row);
250
- }
 
251
 
252
- public function getHtml() {
253
- $config = $this->getData('config');
254
- $opened_row_ids = $this->getData('opened_row_ids');
255
- $output = /*"<pre>".print_r($config, true)."</pre>".*/"";
256
- $i = 0;
257
- if (!$config) {
258
- $output .= "<p style=\"padding:10px;\">Configuration vide</p>";
259
- } else {
260
- $output .= "<ul id=os2-editor-elems-container>";
261
- foreach ($config as $row_id => &$row) {
262
- $opened = in_array($row_id, $opened_row_ids) || !$opened_row_ids && $i==0;
263
- $output .= $this->_getRowItem($row, $opened);
264
- $i++;
265
- }
266
- $output .= "</ul>";
267
- }
268
- return $output;
269
- }
 
270
  }
21
 
22
  class Owebia_Shipping2_Block_Adminhtml_Os2_Editor extends Mage_Adminhtml_Block_Abstract
23
  {
24
+ protected $_config;
25
+ protected $_opened_row_ids;
26
 
27
+ public function __construct($attributes)
28
+ {
29
+ $attributes = $attributes + array(
30
+ 'config' => '',
31
+ 'opened_row_ids' => array(),
32
+ );
33
+ $this->_config = $attributes['config'];
34
+ $this->_opened_row_ids = $attributes['opened_row_ids'];
35
+ }
36
 
37
+ public function __()
38
+ {
39
+ $args = func_get_args();
40
+ return Mage::helper('owebia_shipping2')->__($args);
41
+ }
42
 
43
+ private function _getPropertyInput($property_name, $property)
44
+ {
45
+ if (is_array($property)) { // Compatibility PHP 5.2
46
+ $value = isset($property['original_value']) ? $property['original_value'] : (isset($property['value']) ? $property['value'] : (isset($property) ? $property : ''));
47
+ } else {
48
+ $value = $property;
49
+ }
50
 
51
+ $toolbar = "<span class=\"os2-field-btn os2-field-help\" data-property=\"{$property_name}\"></span>";
52
+ switch ($property_name) {
53
+ case 'enabled':
54
+ $enabled = $value!==false;
55
+ $input = "<select class=field name=\"{$property_name}\">"
56
+ ."<option value=\"1\"".($enabled ? ' selected="selected"' : '').">".$this->__('Enabled (default)')."</option>"
57
+ ."<option value=\"0\"".($enabled ? '' : ' selected="selected"').">".$this->__('Disabled')."</option>"
58
+ ."</select>";
59
+ break;
60
+ case 'type':
61
+ $input = "<select class=field name=\"{$property_name}\">"
62
+ ."<option value=method".($value=='method' || !$value ? '' : ' selected="selected"').">".$this->__('Shipping Method (default)')."</option>"
63
+ ."<option value=data".($value=='data' ? ' selected="selected"' : '').">".$this->__('Data')."</option>"
64
+ ."<option value=meta".($value=='meta' ? ' selected="selected"' : '').">".$this->__('Meta')."</option>"
65
+ ."</select>";
66
+ break;
67
+ case 'shipto':
68
+ case 'billto':
69
+ case 'origin':
70
+ $toolbar = "<span class=\"os2-field-btn os2-field-edit\"></span>".$toolbar;
71
+ default:
72
+ $input = "<input class=field name=\"{$property_name}\" value=\"".htmlspecialchars($value, ENT_COMPAT, 'UTF-8')."\"/>";
73
+ break;
74
+ }
75
+ return $input;
76
+ }
77
+
78
+ public function getPropertyTools($controller, $property_name)
79
+ {
80
+ $after = '';
81
+ switch ($property_name) {
82
+ case 'label':
83
+ case 'description':
84
+ $after = "<fieldset class=buttons-set><legend>".$this->__('Insert')."</legend>"
85
+ ."<p>"
86
+ .$controller->button__('Shipping country',"os2editor.insertAtCaret(this,'{shipto.country_name}');",'os2-insert')
87
+ .$controller->button__('Cart weight',"os2editor.insertAtCaret(this,'{cart.weight}');",'os2-insert')
88
+ .$controller->button__('Products quantity',"os2editor.insertAtCaret(this,'{cart.qty}');",'os2-insert')
89
+ .$controller->button__('Price incl. tax',"os2editor.insertAtCaret(this,'{cart.price+tax+discount}');",'os2-insert')
90
+ .$controller->button__('Price excl. tax',"os2editor.insertAtCaret(this,'{cart.price-tax+discount}');",'os2-insert')
91
+ ."</p>"
92
+ ."</fieldset>";
93
+ break;
94
+ case 'fees':
95
+ $after = "<fieldset class=buttons-set><legend>".$this->__('Insert')."</legend>"
96
+ ."<p>"
97
+ .$controller->button__('Weight',"os2editor.insertAtCaret(this,'{cart.weight}');",'os2-insert')
98
+ .$controller->button__('Products quantity',"os2editor.insertAtCaret(this,'{cart.qty}');",'os2-insert')
99
+ .$controller->button__('Price incl. tax',"os2editor.insertAtCaret(this,'{cart.price+tax+discount}');",'os2-insert')
100
+ .$controller->button__('Price excl. tax',"os2editor.insertAtCaret(this,'{cart.price-tax+discount}');",'os2-insert')
101
+ ."</p>"
102
+ ."</fieldset>";
103
+ break;
104
+ case 'conditions':
105
+ $after = "<fieldset class=buttons-set><legend>".$this->__('Insert')."</legend>"
106
+ ."<p>"
107
+ .$controller->button__('Weight',"os2editor.insertAtCaret(this,'{cart.weight}');",'os2-insert')
108
+ .$controller->button__('Products quantity',"os2editor.insertAtCaret(this,'{cart.qty}');",'os2-insert')
109
+ .$controller->button__('Price incl. tax',"os2editor.insertAtCaret(this,'{cart.price+tax+discount}');",'os2-insert')
110
+ .$controller->button__('Price excl. tax',"os2editor.insertAtCaret(this,'{cart.price-tax+discount}');",'os2-insert')
111
+ ."</p>"
112
+ ."</fieldset>";
113
+ break;
114
+ case 'customer_groups':
115
+ $model = Mage::getModel('owebia_shipping2/Os2_Data_CustomerGroup');
116
+ $groups = (array)$model->getCollection();
117
+ $output = '';
118
+ foreach ($groups as $id => $name) {
119
+ $output .= $controller->button($this->esc($name.' ('.$id.')'),"os2editor.insertAtCaret(this,'".$this->jsEscape($id)."');",'os2-insert');
120
+ }
121
+ $after = "<fieldset class=buttons-set><legend>".$this->__('Tools')."</legend>"
122
+ ."<p>"
123
+ .$controller->button__('Human readable version',"os2editor.getReadableSelection(this);")
124
+ ."</p><div id=os2-output></div>"
125
+ ."</fieldset>"
126
+ ."<fieldset class=buttons-set><legend>".$this->__('Insert')."</legend>"
127
+ ."<p>{$output}</p>"
128
+ ."</fieldset>"
129
+ ;
130
+ break;
131
+ case 'tracking_url':
132
+ $after = "<fieldset class=buttons-set><legend>".$this->__('Insert')."</legend>"
133
+ ."<p>"
134
+ .$controller->button__('Tracking number',"os2editor.insertAtCaret(this,'{tracking_number}');",'os2-insert')
135
+ ."</p>"
136
+ ."</fieldset>";
137
+ break;
138
+ case 'shipto':
139
+ case 'billto':
140
+ case 'origin':
141
+ $after = "<fieldset class=buttons-set><legend>".$this->__('Tools')."</legend>"
142
+ ."<p>"
143
+ .$controller->button__('Human readable version',"os2editor.getReadableSelection(this);")
144
+ ."</p><div id=os2-output></div>"
145
+ ."</fieldset>"
146
+ ;
147
+ break;
148
+ case 'about':
149
+ break;
150
+ }
151
+ return $after;
152
+ }
153
 
154
+ public function sortProperties($k1, $k2)
155
+ {
156
+ $i1 = isset($this->properties_sort[$k1]) ? $this->properties_sort[$k1] : 1000;
157
+ $i2 = isset($this->properties_sort[$k2]) ? $this->properties_sort[$k2] : 1000;
158
+ return $i1==$i2 ? strcmp($k1, $k2) : $i1-$i2;
159
+ }
160
 
161
+ protected function _getRowUI(&$row)
162
+ {
163
+ $properties = array('*id', 'type', 'about', 'enabled');
164
+ $type = isset($row['type']['value']) ? $row['type']['value'] : null;
165
+ switch ($type) {
166
+ case 'meta':
167
+ $row_label = $this->__('[meta] %s', $row['*id']);
168
+ break;
169
+ case 'data':
170
+ $row_label = $this->__('[data] %s', $row['*id']);
171
+ break;
172
+ default:
173
+ if (!isset($row['label'])) {
174
+ $row['label']['value'] = $this->__('New shipping method');
175
+ }
176
+ $row_label = $row['label']['value'];
177
+ $properties = array_merge($properties, array('label', 'description', 'shipto', 'billto', 'origin', 'conditions', 'fees', 'customer_groups', 'tracking_url'));
178
+ }
179
 
180
+ $properties_label = array(
181
+ '*id' => 'ID',
182
+ 'type' => 'Type',
183
+ 'about' => 'About',
184
+ 'enabled' => 'Enabled',
185
+ 'label' => 'Label',
186
+ 'description' => 'Description',
187
+ 'shipto' => 'Shipping address',
188
+ 'billto' => 'Billing address',
189
+ 'origin' => 'Origin address',
190
+ 'conditions' => 'Conditions',
191
+ 'fees' => 'Fees',
192
+ 'customer_groups' => 'Customer groups',
193
+ 'tracking_url' => 'Tracking url',
194
+ );
195
+ foreach ($properties as $property_name) {
196
+ if (!isset($row[$property_name])) $row[$property_name] = null;
197
+ }
198
+ $this->properties_sort = array_flip($properties);
199
+ uksort($row, array($this, 'sortProperties'));
200
+ $list = '';
201
+ $content = '';
202
+ $j = 0;
203
+ foreach ($row as $property_name => $property) {
204
+ $property_label = isset($properties_label[$property_name]) ? $properties_label[$property_name] : $property_name;
205
+ $error = array();
206
+ if (isset($property['messages'])) {
207
+ foreach ($property['messages'] as $message) {
208
+ $error[] = $this->__($message);
209
+ }
210
+ }
211
+ $content .= "<tr class=\"os2-p-container".($error ? ' os2-error' : '')."\"".($error ? ' title="'.$this->esc(implode(', ', $error)).'"' : '')."><th>".$this->__($property_label)."</th><td>".$this->_getPropertyInput($property_name, $property, $big = false)."</td></tr>";
212
+ $j++;
213
+ }
214
+ //$output = "<ul class=\"properties-list ui-layout-west\">{$list}</ul><div class=\"properties-container ui-layout-center\">{$content}</div>";
215
+ $output = "<table class=properties-container>{$content}</table>";
216
+ return $output;
217
+ }
218
 
219
+ protected function _getRowItem($row, $opened)
220
+ {
221
+ $type = isset($row['type']['value']) ? $row['type']['value'] : null;
222
+ switch ($type) {
223
+ case 'meta':
224
+ $label = $this->__('[meta] %s', $row['*id']);
225
+ break;
226
+ case 'data':
227
+ $label = $this->__('[data] %s', $row['*id']);
228
+ break;
229
+ default:
230
+ $label = isset($row['label']['value']) ? $row['label']['value'] : $this->__('New shipping method');
231
+ break;
232
+ }
233
+ $content = '';
234
+ if ($opened) {
235
+ $content = $this->_getRowUI($row);
236
+ }
237
+ $error = false;
238
+ foreach ($row as $property_name => $property) {
239
+ if (is_array($property) /*Compatibility*/ && isset($property['messages'])) {
240
+ $error = true;
241
+ break;
242
+ }
243
+ }
244
+ return "<li data-id=\"{$row['*id']}\"".($error ? ' class=os2-error' : '')."><h5><button class=\"os2-remove-row-btn\" title=\"{$this->__('Remove')}\"></button>".$label."</h5><div class=\"row-ui".($opened ? ' opened' : '')."\">{$content}</div></li>";
245
+ }
246
 
247
+ protected function esc($input)
248
+ {
249
+ return htmlspecialchars($input, ENT_COMPAT, 'UTF-8');
250
+ }
251
 
252
+ protected function jsEscape($input)
253
+ {
254
+ return str_replace(array("\r\n","\r","\n","'"),array("\\n","\\n","\\n","\\'"),$input);
255
+ }
256
 
257
+ public function getRowUI(&$row)
258
+ {
259
+ return $this->_getRowUI($row);
260
+ }
261
 
262
+ public function getHtml()
263
+ {
264
+ $config = $this->getData('config');
265
+ $opened_row_ids = $this->getData('opened_row_ids');
266
+ $output = /*"<pre>".print_r($config, true)."</pre>".*/"";
267
+ $i = 0;
268
+ if (!$config) {
269
+ $output .= "<p style=\"padding:10px;\">Configuration vide</p>";
270
+ } else {
271
+ $output .= "<ul id=os2-editor-elems-container>";
272
+ foreach ($config as $row_id => &$row) {
273
+ $opened = in_array($row_id, $opened_row_ids) || !$opened_row_ids && $i==0;
274
+ $output .= $this->_getRowItem($row, $opened);
275
+ $i++;
276
+ }
277
+ $output .= "</ul>";
278
+ }
279
+ return $output;
280
+ }
281
  }
app/code/community/Owebia/Shipping2/Block/Adminhtml/Os2/Editor/Property/Input.php CHANGED
@@ -21,7 +21,8 @@
21
 
22
  class Owebia_Shipping2_Block_Adminhtml_Os2_Editor_Property_Input extends Mage_Adminhtml_Block_Abstract
23
  {
24
- protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element) {
25
-
26
- }
 
27
  }
21
 
22
  class Owebia_Shipping2_Block_Adminhtml_Os2_Editor_Property_Input extends Mage_Adminhtml_Block_Abstract
23
  {
24
+ protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
25
+ {
26
+
27
+ }
28
  }
app/code/community/Owebia/Shipping2/Block/Adminhtml/Os2/Help.php CHANGED
@@ -21,97 +21,97 @@
21
 
22
  class Owebia_Shipping2_Block_Adminhtml_Os2_Help extends Mage_Adminhtml_Block_Abstract
23
  {
24
- public function __()
25
- {
26
- $args = func_get_args();
27
- return Mage::helper('owebia_shipping2')->__($args);
28
- }
29
 
30
- public function getHtml()
31
- {
32
- $controller = $this->getData('controller');
33
- $help_id = $this->getData('help_id');
34
- $content = $this->getData('content');
35
- $helper = $this->getData('helper');
36
 
37
- $locale_code = Mage::app()->getLocale()->getLocaleCode();
38
- $help_file = Mage::getBaseDir('app') . '/code/community/Owebia/Shipping2/doc_' . $locale_code . '.html';
39
- if (!file_exists($help_file)) {
40
- $help_file = Mage::getBaseDir('app') . '/code/community/Owebia/Shipping2/doc_en_US.html';
41
- }
42
- $content = file_get_contents($help_file);
43
- $doc_sidebar = preg_replace('#^.*<!-- doc sidebar start -->(.*)<!-- doc sidebar end -->.*$#s', '\1', $content);
44
- $doc_content = preg_replace('#^.*<!-- doc content start -->(.*)<!-- doc content end -->.*$#s', '\1', $content);
45
- $doc_scripts = preg_replace('#^.*<!-- doc scripts start -->(.*)<!-- doc scripts end -->.*$#s', '\1', $content);
46
- $doc_scripts = str_replace('$(', "jQuery(", $doc_scripts);
47
- $doc_scripts = str_replace('$.', "jQuery.", $doc_scripts);
48
- $content = $doc_sidebar . $doc_content
49
- //. "<script>jQuery.fn.scrollspy = function(){};" . $doc_scripts . "</script>"
50
- . "<script>
51
  jQuery.fn.scrollspy = function(){};
52
  {$doc_scripts}
53
  function bjson() {
54
- var index = 0;
55
- jQuery('div.json').each(function(){
56
- var text = jQuery(this).text();
57
- while (text.match(/\"__auto__\"/)) {
58
- text = text.replace(/\"__auto__\"/, '\"id_' + ('000' + index).slice(-3) + '\"');
59
- index++;
60
- }
61
- var obj = jQuery.parseJSON(text);
62
- var beautified = jsonEncode(obj, true, true);
63
- jQuery(this).html('<pre>' + beautified + '</pre>');
64
- jQuery(this).addClass('code');
65
- });
66
  }
67
  setTimeout(function(){
68
- bjson();
69
  }, 1000);
70
  </script>"
71
- ;
72
- //$nav = "<div id=os2-help-nav><a href=\"#\" onclick=\"os2editor.refreshHelp();\">".$this->__('Refresh')."</a> | <a href=\"#\" onclick=\"os2editor.previousHelp();\">".$this->__('Previous page')."</a>".($help_id!='summary' ? " | <a href=\"#summary\">".$this->__('Summary')."</a>" : '')."</div>";
73
- $nav = '';
74
- $title = '';
75
- $header = "<div class=\"ui-layout-north os2-help-header\">{$nav}<h4>{$title}</h4></div>";
76
- $content = ($header ? "{$header}" : '')."<div id=os2-help class=ui-layout-center>{$content}</div>";
77
- return $content;
78
 
79
- $controller = $this->getData('controller');
80
- $help_id = $this->getData('help_id');
81
- $content = $this->getData('content');
82
- $helper = $this->getData('helper');
83
- $content = str_replace(
84
- array("\\t", "<c>", "<c class=new>", "</c>", "<string>", "</string>", "<property>", "</property>"),
85
- array('&nbsp;&nbsp;&nbsp;', "<span class=code>", "<span class=\"code new\">", "</span>", "<span class=code><span class=string>", "</span></span>", "<span class=property>", "</span>"),
86
- $content);
87
- $header = null;
88
- $footer = null;
89
- $title = null;
90
- if ($help_id=='changelog') {
91
- $changelog = @file_get_contents($controller->getModulePath('changelog'));
92
- if (!$changelog) $changelog = "Empty changelog";
93
- $changelog = mb_convert_encoding($changelog, 'UTF-8', 'ISO-8859-1');
94
- if (!$changelog) $changelog = "Encoding error";
95
- $changelog = htmlspecialchars($changelog, ENT_QUOTES, 'UTF-8');
96
- $changelog = str_replace("\n", "<br/>", $changelog);
97
- $content = str_replace('{changelog}', $changelog, $content);
98
- }
99
- while (preg_match('#{code=json}(.*?){/code}#s', $content, $result)) {
100
- $json = str_replace("\r\n", '', $result[1]);
101
- try {
102
- $json = Zend_Json::decode($json);
103
- } catch (Exception $e) {}
104
- $content = str_replace($result[0], "<div class=code>".$helper::jsonEncode($json, $beautify = true, $html = true)."</div>", $content);
105
- }
106
- if (preg_match('#<h4>(.*)</h4>#', $content, $result)) {
107
- $title = $result[1];
108
- $content = str_replace($result[0], '', $content);
109
- }
110
- $nav = "<div id=os2-help-nav><a href=\"#\" onclick=\"os2editor.refreshHelp();\">".$this->__('Refresh')."</a> | <a href=\"#\" onclick=\"os2editor.previousHelp();\">".$this->__('Previous page')."</a>".($help_id!='summary' ? " | <a href=\"#summary\">".$this->__('Summary')."</a>" : '')."</div>";
111
- $header = "<div class=\"ui-layout-north os2-help-header\">{$nav}<h4>{$title}</h4></div>";
112
- $content = ($header ? "{$header}" : '')."<div id=os2-help class=ui-layout-center>{$content}</div>";
113
- $content = preg_replace('/ href="#([a-z0-9_\-\.]+)"/', ' href="#" onclick="os2editor.help(\'\1\');"', $content);
114
- return $content;
115
-
116
- }
117
  }
21
 
22
  class Owebia_Shipping2_Block_Adminhtml_Os2_Help extends Mage_Adminhtml_Block_Abstract
23
  {
24
+ public function __()
25
+ {
26
+ $args = func_get_args();
27
+ return Mage::helper('owebia_shipping2')->__($args);
28
+ }
29
 
30
+ public function getHtml()
31
+ {
32
+ $controller = $this->getData('controller');
33
+ $help_id = $this->getData('help_id');
34
+ $content = $this->getData('content');
35
+ $helper = $this->getData('helper');
36
 
37
+ $locale_code = Mage::app()->getLocale()->getLocaleCode();
38
+ $help_file = Mage::getBaseDir('app') . '/code/community/Owebia/Shipping2/doc_' . $locale_code . '.html';
39
+ if (!file_exists($help_file)) {
40
+ $help_file = Mage::getBaseDir('app') . '/code/community/Owebia/Shipping2/doc_en_US.html';
41
+ }
42
+ $content = file_get_contents($help_file);
43
+ $doc_sidebar = preg_replace('#^.*<!-- doc sidebar start -->(.*)<!-- doc sidebar end -->.*$#s', '\1', $content);
44
+ $doc_content = preg_replace('#^.*<!-- doc content start -->(.*)<!-- doc content end -->.*$#s', '\1', $content);
45
+ $doc_scripts = preg_replace('#^.*<!-- doc scripts start -->(.*)<!-- doc scripts end -->.*$#s', '\1', $content);
46
+ $doc_scripts = str_replace('$(', "jQuery(", $doc_scripts);
47
+ $doc_scripts = str_replace('$.', "jQuery.", $doc_scripts);
48
+ $content = $doc_sidebar . $doc_content
49
+ //. "<script>jQuery.fn.scrollspy = function(){};" . $doc_scripts . "</script>"
50
+ . "<script>
51
  jQuery.fn.scrollspy = function(){};
52
  {$doc_scripts}
53
  function bjson() {
54
+ var index = 0;
55
+ jQuery('div.json').each(function(){
56
+ var text = jQuery(this).text();
57
+ while (text.match(/\"__auto__\"/)) {
58
+ text = text.replace(/\"__auto__\"/, '\"id_' + ('000' + index).slice(-3) + '\"');
59
+ index++;
60
+ }
61
+ var obj = jQuery.parseJSON(text);
62
+ var beautified = jsonEncode(obj, true, true);
63
+ jQuery(this).html('<pre>' + beautified + '</pre>');
64
+ jQuery(this).addClass('code');
65
+ });
66
  }
67
  setTimeout(function(){
68
+ bjson();
69
  }, 1000);
70
  </script>"
71
+ ;
72
+ //$nav = "<div id=os2-help-nav><a href=\"#\" onclick=\"os2editor.refreshHelp();\">".$this->__('Refresh')."</a> | <a href=\"#\" onclick=\"os2editor.previousHelp();\">".$this->__('Previous page')."</a>".($help_id!='summary' ? " | <a href=\"#summary\">".$this->__('Summary')."</a>" : '')."</div>";
73
+ $nav = '';
74
+ $title = '';
75
+ $header = "<div class=\"ui-layout-north os2-help-header\">{$nav}<h4>{$title}</h4></div>";
76
+ $content = ($header ? "{$header}" : '')."<div id=os2-help class=ui-layout-center>{$content}</div>";
77
+ return $content;
78
 
79
+ $controller = $this->getData('controller');
80
+ $help_id = $this->getData('help_id');
81
+ $content = $this->getData('content');
82
+ $helper = $this->getData('helper');
83
+ $content = str_replace(
84
+ array("\\t", "<c>", "<c class=new>", "</c>", "<string>", "</string>", "<property>", "</property>"),
85
+ array('&nbsp;&nbsp;&nbsp;', "<span class=code>", "<span class=\"code new\">", "</span>", "<span class=code><span class=string>", "</span></span>", "<span class=property>", "</span>"),
86
+ $content);
87
+ $header = null;
88
+ $footer = null;
89
+ $title = null;
90
+ if ($help_id=='changelog') {
91
+ $changelog = @file_get_contents($controller->getModulePath('changelog'));
92
+ if (!$changelog) $changelog = "Empty changelog";
93
+ $changelog = mb_convert_encoding($changelog, 'UTF-8', 'ISO-8859-1');
94
+ if (!$changelog) $changelog = "Encoding error";
95
+ $changelog = htmlspecialchars($changelog, ENT_QUOTES, 'UTF-8');
96
+ $changelog = str_replace("\n", "<br/>", $changelog);
97
+ $content = str_replace('{changelog}', $changelog, $content);
98
+ }
99
+ while (preg_match('#{code=json}(.*?){/code}#s', $content, $result)) {
100
+ $json = str_replace("\r\n", '', $result[1]);
101
+ try {
102
+ $json = Zend_Json::decode($json);
103
+ } catch (Exception $e) {}
104
+ $content = str_replace($result[0], "<div class=code>".$helper::jsonEncode($json, $beautify = true, $html = true)."</div>", $content);
105
+ }
106
+ if (preg_match('#<h4>(.*)</h4>#', $content, $result)) {
107
+ $title = $result[1];
108
+ $content = str_replace($result[0], '', $content);
109
+ }
110
+ $nav = "<div id=os2-help-nav><a href=\"#\" onclick=\"os2editor.refreshHelp();\">".$this->__('Refresh')."</a> | <a href=\"#\" onclick=\"os2editor.previousHelp();\">".$this->__('Previous page')."</a>".($help_id!='summary' ? " | <a href=\"#summary\">".$this->__('Summary')."</a>" : '')."</div>";
111
+ $header = "<div class=\"ui-layout-north os2-help-header\">{$nav}<h4>{$title}</h4></div>";
112
+ $content = ($header ? "{$header}" : '')."<div id=os2-help class=ui-layout-center>{$content}</div>";
113
+ $content = preg_replace('/ href="#([a-z0-9_\-\.]+)"/', ' href="#" onclick="os2editor.help(\'\1\');"', $content);
114
+ return $content;
115
+
116
+ }
117
  }
app/code/community/Owebia/Shipping2/Block/Adminhtml/System/Config/Form/Field/Config.php CHANGED
@@ -21,72 +21,76 @@
21
 
22
  class Owebia_Shipping2_Block_Adminhtml_System_Config_Form_Field_Config extends Mage_Adminhtml_Block_System_Config_Form_Field
23
  {
24
- private static $JS_INCLUDED = false;
25
-
26
- public function __() {
27
- $args = func_get_args();
28
- return Mage::helper('owebia_shipping2')->__($args);
29
- }
 
30
 
31
- protected function _prepareLayout() {
32
- $layout = $this->getLayout();
33
- $head = $layout->getBlock('head');
34
- $head->addJs('owebia/shipping2/jquery-1.8.2.min.js');
35
- $head->addJs('owebia/shipping2/jquery.noconflict.js');
36
- $head->addJs('owebia/shipping2/jquery-ui-1.8.23.custom/js/jquery-ui-1.8.23.custom.min.js');
37
- $head->addJs('owebia/shipping2/jquery.layout-1.3.0-rc30.6.min.js');
38
- $head->addJs('owebia/shipping2/colorbox/jquery.colorbox-min.js');
39
- $head->addJs('owebia/shipping2/jquery.caret.1.02.min.js');
40
- $head->addJs('owebia/shipping2/os2editor.js');
41
- //$head->addItem('js_css', 'owebia/shipping2/jquery-ui-1.8.23.custom/css/ui-lightness/jquery-ui-1.8.23.custom.css');
42
- $head->addItem('js_css', 'owebia/shipping2/colorbox/colorbox.css', 'media="all"');
43
- $head->addItem('js_css', 'owebia/shipping2/os2editor.css', 'media="all"');
44
- //$head->addItem('other', 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js');
45
- //$head->append($block);
46
-
47
- parent::_prepareLayout();
48
- }
 
49
 
50
- private function label__($input) {
51
- return str_replace(array("\r\n","\r","\n","'"), array("\\n","\\n","\\n","\\'"), $this->__($input));
52
- }
 
53
 
54
- protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element) {
55
- $output = '';
56
- if (!self::$JS_INCLUDED) {
57
- $output = "<script type=\"text/javascript\">\n"
58
- ."//<![CDATA[\n"
59
- ."jQuery.noConflict();\n"
60
- ."var os2editor = new OS2Editor({\n"
61
- ."ajax_url: '".$this->getUrl('adminhtml/os2_ajax/index')."?isAjax=true',\n"
62
- ."form_key: FORM_KEY,\n"
63
- ."apply_btn_label: '".$this->label__('Apply')."',\n"
64
- ."cancel_btn_label: '".$this->label__('Cancel')."',\n"
65
- ."menu_item_dissociate_label: '".$this->label__('Dissociate')."',\n"
66
- ."menu_item_remove_label: '".$this->label__('Remove')."',\n"
67
- ."menu_item_edit_label: '".$this->label__('Edit')."',\n"
68
- ."prompt_new_value_label: '".$this->label__('Enter the new value:')."',\n"
69
- ."default_row_label: '".$this->label__('[No label]')."',\n"
70
- ."loading_label: '".$this->label__('Loading...')."'\n"
71
- ."});\n"
72
- ."
 
73
  "
74
- ."//]]>\n"
75
- ."</script>\n"
76
- ;
77
- self::$JS_INCLUDED = true;
78
- }
79
 
80
- $shipping_code = preg_replace('/^groups\[([^\]]*)\].*$/','\1',$element->getName());
81
- return <<<EOD
82
  {$output}
83
  <div style="margin-bottom:1px;">
84
- <button type="button" class="scalable" onclick="os2editor.init(this, '{$shipping_code}').page('source');"><span>{$this->__('Source &amp; Correction')}</span></button>
85
- <button type="button" class="scalable" onclick="os2editor.init(this, '{$shipping_code}').help('summary');"><span>{$this->__('Help')}</span></button>
86
- <!--<a href="{$this->getUrl('adminhtml/os2_ajax/doc')}">doc</a>-->
87
  </div>
88
  {$element->getElementHtml()}<br/>
89
  <a href="http://www.owebia.com/contributions/magento/owebia-shipping/fr/modeles-de-configuration" target="_blank">{$this->__('Download configuration templates')}</a>
90
  EOD;
91
- }
92
  }
21
 
22
  class Owebia_Shipping2_Block_Adminhtml_System_Config_Form_Field_Config extends Mage_Adminhtml_Block_System_Config_Form_Field
23
  {
24
+ private static $JS_INCLUDED = false;
25
+
26
+ public function __()
27
+ {
28
+ $args = func_get_args();
29
+ return Mage::helper('owebia_shipping2')->__($args);
30
+ }
31
 
32
+ protected function _prepareLayout()
33
+ {
34
+ $layout = $this->getLayout();
35
+ $head = $layout->getBlock('head');
36
+ $head->addJs('owebia/shipping2/jquery-1.8.2.min.js');
37
+ $head->addJs('owebia/shipping2/jquery.noconflict.js');
38
+ $head->addJs('owebia/shipping2/jquery-ui-1.8.23.custom/js/jquery-ui-1.8.23.custom.min.js');
39
+ $head->addJs('owebia/shipping2/jquery.layout-1.3.0-rc30.6.min.js');
40
+ $head->addJs('owebia/shipping2/colorbox/jquery.colorbox-min.js');
41
+ $head->addJs('owebia/shipping2/jquery.caret.1.02.min.js');
42
+ $head->addJs('owebia/shipping2/os2editor.js');
43
+ //$head->addItem('js_css', 'owebia/shipping2/jquery-ui-1.8.23.custom/css/ui-lightness/jquery-ui-1.8.23.custom.css');
44
+ $head->addItem('js_css', 'owebia/shipping2/colorbox/colorbox.css', 'media="all"');
45
+ $head->addItem('js_css', 'owebia/shipping2/os2editor.css', 'media="all"');
46
+ //$head->addItem('other', 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js');
47
+ //$head->append($block);
48
+
49
+ parent::_prepareLayout();
50
+ }
51
 
52
+ private function label__($input)
53
+ {
54
+ return str_replace(array("\r\n","\r","\n","'"), array("\\n","\\n","\\n","\\'"), $this->__($input));
55
+ }
56
 
57
+ protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
58
+ {
59
+ $output = '';
60
+ if (!self::$JS_INCLUDED) {
61
+ $output = "<script type=\"text/javascript\">\n"
62
+ ."//<![CDATA[\n"
63
+ ."jQuery.noConflict();\n"
64
+ ."var os2editor = new OS2Editor({\n"
65
+ ."ajax_url: '".$this->getUrl('adminhtml/os2_ajax/index')."?isAjax=true',\n"
66
+ ."form_key: FORM_KEY,\n"
67
+ ."apply_btn_label: '".$this->label__('Apply')."',\n"
68
+ ."cancel_btn_label: '".$this->label__('Cancel')."',\n"
69
+ ."menu_item_dissociate_label: '".$this->label__('Dissociate')."',\n"
70
+ ."menu_item_remove_label: '".$this->label__('Remove')."',\n"
71
+ ."menu_item_edit_label: '".$this->label__('Edit')."',\n"
72
+ ."prompt_new_value_label: '".$this->label__('Enter the new value:')."',\n"
73
+ ."default_row_label: '".$this->label__('[No label]')."',\n"
74
+ ."loading_label: '".$this->label__('Loading...')."'\n"
75
+ ."});\n"
76
+ ."
77
  "
78
+ ."//]]>\n"
79
+ ."</script>\n"
80
+ ;
81
+ self::$JS_INCLUDED = true;
82
+ }
83
 
84
+ $shipping_code = preg_replace('/^groups\[([^\]]*)\].*$/','\1',$element->getName());
85
+ return <<<EOD
86
  {$output}
87
  <div style="margin-bottom:1px;">
88
+ <button type="button" class="scalable" onclick="os2editor.init(this, '{$shipping_code}').page('source');"><span>{$this->__('Source &amp; Correction')}</span></button>
89
+ <button type="button" class="scalable" onclick="os2editor.init(this, '{$shipping_code}').help('summary');"><span>{$this->__('Help')}</span></button>
90
+ <!--<a href="{$this->getUrl('adminhtml/os2_ajax/doc')}">doc</a>-->
91
  </div>
92
  {$element->getElementHtml()}<br/>
93
  <a href="http://www.owebia.com/contributions/magento/owebia-shipping/fr/modeles-de-configuration" target="_blank">{$this->__('Download configuration templates')}</a>
94
  EOD;
95
+ }
96
  }
app/code/community/Owebia/Shipping2/Block/Adminhtml/System/Config/Form/Field/Informations.php CHANGED
@@ -21,15 +21,15 @@
21
 
22
  class Owebia_Shipping2_Block_Adminhtml_System_Config_Form_Field_Informations extends Mage_Adminhtml_Block_System_Config_Form_Field
23
  {
24
- public function __()
25
- {
26
- $args = func_get_args();
27
- return Mage::helper('owebia_shipping2')->__($args);
28
- }
29
 
30
- protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
31
- {
32
- $version = Mage::getConfig()->getNode('modules/Owebia_Shipping2/version');
33
- return $this->__('Version: %s', $version);
34
- }
35
  }
21
 
22
  class Owebia_Shipping2_Block_Adminhtml_System_Config_Form_Field_Informations extends Mage_Adminhtml_Block_System_Config_Form_Field
23
  {
24
+ public function __()
25
+ {
26
+ $args = func_get_args();
27
+ return Mage::helper('owebia_shipping2')->__($args);
28
+ }
29
 
30
+ protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
31
+ {
32
+ $version = Mage::getConfig()->getNode('modules/Owebia_Shipping2/version');
33
+ return $this->__('Version: %s', $version);
34
+ }
35
  }
app/code/community/Owebia/Shipping2/Controller/Abstract.php CHANGED
@@ -21,110 +21,109 @@
21
 
22
  class Owebia_Shipping2_Controller_Abstract extends Mage_Adminhtml_Controller_Action
23
  {
24
- public function __()
25
- {
26
- $args = func_get_args();
27
- return Mage::helper('owebia_shipping2')->__($args);
28
- }
29
 
30
- public function getModulePath($path)
31
- {
32
- if (file_exists(dirname(__FILE__) . '/Owebia_Shipping2_' . str_replace('/', '_', $path))) {
33
- return 'Owebia_Shipping2_'.str_replace('/', '_', $path);
34
- } else {
35
- return Mage::getBaseDir('code') . '/community/Owebia/Shipping2/' . $path;
36
- }
37
- }
38
 
39
- protected function getMimeType($extension)
40
- {
41
- $mime_type_array = array(
42
- '.gz' => 'application/x-gzip',
43
- '.tgz' => 'application/x-gzip',
44
- '.zip' => 'application/zip',
45
- '.pdf' => 'application/pdf',
46
- '.png' => 'image/png',
47
- '.gif' => 'image/gif',
48
- '.jpg' => 'image/jpeg',
49
- '.jpeg' => 'image/jpeg',
50
- '.txt' => 'text/plain',
51
- '.htm' => 'text/html',
52
- '.html' => 'text/html',
53
- '.mpg' => 'video/mpeg',
54
- '.avi' => 'video/x-msvideo',
55
- );
56
- return isset($mime_type_array[$extension]) ? $mime_type_array[$extension] : 'application/octet-stream';
57
- }
 
 
 
 
 
 
 
58
 
59
- protected function forceDownload($filename, $content)
60
- {
61
- if (headers_sent()) {
62
- trigger_error('forceDownload($filename) - Headers have already been sent',E_USER_ERROR);
63
- return false;
64
- }
65
 
66
- $extension = strrchr($filename,'.');
67
- $mime_type = $this->getMimeType($extension);
 
 
 
 
 
 
 
 
68
 
69
- header('Content-disposition: attachment; filename="'.$filename.'"');
70
- header('Content-Type: application/force-download');
71
- header('Content-Transfer-Encoding: '.$mime_type."\n"); // Surtout ne pas enlever le \n
72
- //header('Content-Length: '.filesize($filename));
73
- header('Pragma: no-cache');
74
- header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0');
75
- header('Expires: 0');
76
- echo $content;
77
- return true;
78
- }
79
 
80
- protected function cleanKey($key)
81
- {
82
- return preg_replace('/[^a-z0-9\-_]/i','_',$key);
83
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
 
85
- protected function page($page, $layout_content = array(), $with_dialog = true)
86
- {
87
- if (!is_array($layout_content)) $layout_content = array('center' => $layout_content);
88
- return ($with_dialog ? "<div id=os2-dialog>"
89
- . $this->pageHeader($this->__('Owebia Shipping 2 Editor'),
90
- $this->button__('Source &amp; Correction', "os2editor.page('source');", 'source')
91
- . $this->button__('Help', "os2editor.help('summary');", 'help')
92
- //. $this->button__('Donate', "os2editor.page('donate');", 'donate')
93
- . $this->button__('Close', "os2editor.close();", 'cancel')
94
- )
95
- . "<div id=os2-page-container class=ui-layout-center>" : '')
96
- . "<div id=os2-page-{$page} class=os2-page>"
97
- . (!isset($layout_content['north']) ? '' : "<div class=\"ui-layout-north inner-layout\">".$layout_content['north']."</div>")
98
- . "<div class=\"ui-layout-center inner-layout\">".$layout_content['center']."</div>"
99
- . (!isset($layout_content['south']) ? '' : "<div class=\"ui-layout-south inner-layout\">".$layout_content['south']."</div>")
100
- . (!isset($layout_content['west']) ? '' : "<div class=\"ui-layout-west inner-layout\">".$layout_content['west']."</div>")
101
- . (!isset($layout_content['east']) ? '' : "<div class=\"ui-layout-east inner-layout\">".$layout_content['east']."</div>")
102
- . "</div>"
103
- . ($with_dialog ? "</div>"
104
- . "</div>" : '')
105
- ;
106
- }
107
 
108
- protected function pageHeader($title, $buttons)
109
- {
110
- return "<div class=ui-layout-north><div id=os2-page-header>"
111
- ."<table cellspacing=0><tr>"
112
- ."<td><h3>{$title}</h3></td>"
113
- ."<td class=buttons>{$buttons}</td>"
114
- ."</tr></table>"
115
- ."</div></div>"
116
- ;
117
- }
118
 
119
- public function button($label, $onclick, $class_name='')
120
- {
121
- $class_name = 'scalable'.($class_name!='' ? ' '.$class_name : '');
122
- return "<button type=\"button\" class=\"".$class_name."\" onclick=\"".$onclick."\"><span>".$label."</span></button>";
123
- }
124
-
125
- public function button__($label, $onclick, $class_name='')
126
- {
127
- return $this->button($this->__($label),$onclick,$class_name);
128
- }
129
  }
130
-
21
 
22
  class Owebia_Shipping2_Controller_Abstract extends Mage_Adminhtml_Controller_Action
23
  {
24
+ public function __()
25
+ {
26
+ $args = func_get_args();
27
+ return Mage::helper('owebia_shipping2')->__($args);
28
+ }
29
 
30
+ public function getModulePath($path)
31
+ {
32
+ if (file_exists(dirname(__FILE__) . '/Owebia_Shipping2_' . str_replace('/', '_', $path))) {
33
+ return 'Owebia_Shipping2_'.str_replace('/', '_', $path);
34
+ } else {
35
+ return Mage::getBaseDir('code') . '/community/Owebia/Shipping2/' . $path;
36
+ }
37
+ }
38
 
39
+ protected function getMimeType($extension)
40
+ {
41
+ $mime_type_array = array(
42
+ '.gz' => 'application/x-gzip',
43
+ '.tgz' => 'application/x-gzip',
44
+ '.zip' => 'application/zip',
45
+ '.pdf' => 'application/pdf',
46
+ '.png' => 'image/png',
47
+ '.gif' => 'image/gif',
48
+ '.jpg' => 'image/jpeg',
49
+ '.jpeg' => 'image/jpeg',
50
+ '.txt' => 'text/plain',
51
+ '.htm' => 'text/html',
52
+ '.html' => 'text/html',
53
+ '.mpg' => 'video/mpeg',
54
+ '.avi' => 'video/x-msvideo',
55
+ );
56
+ return isset($mime_type_array[$extension]) ? $mime_type_array[$extension] : 'application/octet-stream';
57
+ }
58
+
59
+ protected function forceDownload($filename, $content)
60
+ {
61
+ if (headers_sent()) {
62
+ trigger_error('forceDownload($filename) - Headers have already been sent',E_USER_ERROR);
63
+ return false;
64
+ }
65
 
66
+ $extension = strrchr($filename,'.');
67
+ $mime_type = $this->getMimeType($extension);
 
 
 
 
68
 
69
+ header('Content-disposition: attachment; filename="'.$filename.'"');
70
+ header('Content-Type: application/force-download');
71
+ header('Content-Transfer-Encoding: '.$mime_type."\n"); // Surtout ne pas enlever le \n
72
+ //header('Content-Length: '.filesize($filename));
73
+ header('Pragma: no-cache');
74
+ header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0');
75
+ header('Expires: 0');
76
+ echo $content;
77
+ return true;
78
+ }
79
 
80
+ protected function cleanKey($key)
81
+ {
82
+ return preg_replace('/[^a-z0-9\-_]/i','_',$key);
83
+ }
 
 
 
 
 
 
84
 
85
+ protected function page($page, $layout_content = array(), $with_dialog = true)
86
+ {
87
+ if (!is_array($layout_content)) $layout_content = array('center' => $layout_content);
88
+ return ($with_dialog ? "<div id=os2-dialog>"
89
+ . $this->pageHeader($this->__('Owebia Shipping 2 Editor'),
90
+ $this->button__('Source &amp; Correction', "os2editor.page('source');", 'source')
91
+ . $this->button__('Help', "os2editor.help('summary');", 'help')
92
+ //. $this->button__('Donate', "os2editor.page('donate');", 'donate')
93
+ . $this->button__('Close', "os2editor.close();", 'cancel')
94
+ )
95
+ . "<div id=os2-page-container class=ui-layout-center>" : '')
96
+ . "<div id=os2-page-{$page} class=os2-page>"
97
+ . (!isset($layout_content['north']) ? '' : "<div class=\"ui-layout-north inner-layout\">".$layout_content['north']."</div>")
98
+ . "<div class=\"ui-layout-center inner-layout\">".$layout_content['center']."</div>"
99
+ . (!isset($layout_content['south']) ? '' : "<div class=\"ui-layout-south inner-layout\">".$layout_content['south']."</div>")
100
+ . (!isset($layout_content['west']) ? '' : "<div class=\"ui-layout-west inner-layout\">".$layout_content['west']."</div>")
101
+ . (!isset($layout_content['east']) ? '' : "<div class=\"ui-layout-east inner-layout\">".$layout_content['east']."</div>")
102
+ . "</div>"
103
+ . ($with_dialog ? "</div>"
104
+ . "</div>" : '')
105
+ ;
106
+ }
107
 
108
+ protected function pageHeader($title, $buttons)
109
+ {
110
+ return "<div class=ui-layout-north><div id=os2-page-header>"
111
+ ."<table cellspacing=0><tr>"
112
+ ."<td><h3>{$title}</h3></td>"
113
+ ."<td class=buttons>{$buttons}</td>"
114
+ ."</tr></table>"
115
+ ."</div></div>"
116
+ ;
117
+ }
 
 
 
 
 
 
 
 
 
 
 
 
118
 
119
+ public function button($label, $onclick, $class_name='')
120
+ {
121
+ $class_name = 'scalable'.($class_name!='' ? ' '.$class_name : '');
122
+ return "<button type=\"button\" class=\"".$class_name."\" onclick=\"".$onclick."\"><span>".$label."</span></button>";
123
+ }
 
 
 
 
 
124
 
125
+ public function button__($label, $onclick, $class_name='')
126
+ {
127
+ return $this->button($this->__($label),$onclick,$class_name);
128
+ }
 
 
 
 
 
 
129
  }
 
app/code/community/Owebia/Shipping2/Helper/Data.php CHANGED
@@ -21,145 +21,145 @@
21
 
22
  class Owebia_Shipping2_Helper_Data extends Mage_Core_Helper_Data
23
  {
24
- protected $_translate_inline;
25
 
26
- public function __()
27
- {
28
- $args = func_get_args();
29
- if (isset($args[0]) && is_array($args[0]) && count($args)==1) {
30
- $args = $args[0];
31
- }
32
- $message = array_shift($args);
33
- if ($message instanceof OS_Message) {
34
- $args = $message->args;
35
- $message = $message->message;
36
- }
37
-
38
- $output = parent::__($message);
39
-
40
- /*if (true) {
41
- $translations = @file_get_contents('translations.os2');
42
- $translations = eval('return '.$translations.';');
43
- if (!is_array($translations)) $translations = array();
44
 
45
- $file = 'NC';
46
- $line = 'NC';
47
- $backtrace = debug_backtrace();
48
- foreach ($backtrace as $trace) {
49
- if (!isset($trace['function'])) continue;
50
- if (substr($trace['function'], strlen($trace['function'])-2, strlen($trace['function']))=='__') {
51
- $file = ltrim(str_replace(Mage::getBaseDir(), '', $trace['file']), '/');
52
- $line = $trace['line'];
53
- continue;
54
- }
55
- //$file = ltrim(str_replace(Mage::getBaseDir(), '', $trace['file']), '/');
56
- //echo $file.', '.$trace['function'].'(), '.$line.', '.$message.'<br/>';
57
- break;
58
- }
59
 
60
- $translations[Mage::app()->getLocale()->getLocaleCode()][$file][$message] = $output;
61
- ksort($translations[Mage::app()->getLocale()->getLocaleCode()]);
62
- file_put_contents('translations.os2', var_export($translations, true));
63
- }*/
64
 
65
- if (count($args)==0) {
66
- $result = $output;
67
- } else {
68
- if (!isset($this->_translate_inline)) $this->_translate_inline = Mage::getSingleton('core/translate')->getTranslateInline();
69
- if ($this->_translate_inline) {
70
- $parts = explode('}}{{', $output);
71
- $parts[0] = vsprintf($parts[0], $args);
72
- $result = implode('}}{{', $parts);
73
- } else {
74
- $result = vsprintf($output, $args);
75
- }
76
- }
77
- return $result;
78
- }
79
 
80
- public function getMethodText($helper, $process, $row, $property)
81
- {
82
- if (!isset($row[$property])) return '';
83
 
84
- $output = '';
85
- $cart = $process['data']['cart'];
86
- return $helper->evalInput($process, $row, $property, str_replace(
87
- array(
88
- '{cart.weight}',
89
- '{cart.price-tax+discount}',
90
- '{cart.price-tax-discount}',
91
- '{cart.price+tax+discount}',
92
- '{cart.price+tax-discount}',
93
- ),
94
- array(
95
- $cart->weight . $cart->weight_unit,
96
- $this->currency($cart->{'price-tax+discount'}),
97
- $this->currency($cart->{'price-tax-discount'}),
98
- $this->currency($cart->{'price+tax+discount'}),
99
- $this->currency($cart->{'price+tax-discount'}),
100
- ),
101
- $helper->getRowProperty($row, $property)
102
- ));
103
- }
104
-
105
- public function getDataModelMap($helper, $carrier_code, $request)
106
- {
107
- $mage_config = Mage::getConfig();
108
- return array(
109
- 'info' => Mage::getModel('owebia_shipping2/Os2_Data_Info', array_merge($helper->getInfos(), array(
110
- 'magento_version' => Mage::getVersion(),
111
- 'module_version' => (string)$mage_config->getNode('modules/Owebia_Shipping2/version'),
112
- 'carrier_code' => $carrier_code,
113
- ))),
114
- 'cart' => Mage::getModel('owebia_shipping2/Os2_Data_Cart', array(
115
- 'request' => $request,
116
- 'options' => array(
117
- 'bundle' => array(
118
- 'process_children' => (boolean)Mage::getStoreConfig('owebia_shipping2/bundle_product/process_children'),
119
- 'load_item_options_on_parent' => (boolean)Mage::getStoreConfig('owebia_shipping2/bundle_product/load_item_options_on_parent'),
120
- 'load_item_data_on_parent' => (boolean)Mage::getStoreConfig('owebia_shipping2/bundle_product/load_item_data_on_parent'),
121
- 'load_product_data_on_parent' => (boolean)Mage::getStoreConfig('owebia_shipping2/bundle_product/load_product_data_on_parent'),
122
- ),
123
- 'configurable' => array(
124
- 'load_item_options_on_parent' => (boolean)Mage::getStoreConfig('owebia_shipping2/configurable_product/load_item_options_on_parent'),
125
- 'load_item_data_on_parent' => (boolean)Mage::getStoreConfig('owebia_shipping2/configurable_product/load_item_data_on_parent'),
126
- 'load_product_data_on_parent' => (boolean)Mage::getStoreConfig('owebia_shipping2/configurable_product/load_product_data_on_parent'),
127
- ),
128
- ),
129
- )),
130
- 'quote' => Mage::getModel('owebia_shipping2/Os2_Data_Quote'),
131
- 'selection' => Mage::getModel('owebia_shipping2/Os2_Data_Selection'),
132
- 'customer' => Mage::getModel('owebia_shipping2/Os2_Data_Customer'),
133
- 'customer_group' => Mage::getModel('owebia_shipping2/Os2_Data_CustomerGroup'),
134
- 'customvar' => Mage::getModel('owebia_shipping2/Os2_Data_Customvar'),
135
- 'date' => Mage::getModel('owebia_shipping2/Os2_Data_Date'),
136
- 'address_filter' => Mage::getModel('owebia_shipping2/Os2_Data_AddressFilter'),
137
- 'origin' => Mage::getModel('owebia_shipping2/Os2_Data_Address', $this->_extract($request->getData(), array(
138
- 'country_id' => 'country_id',
139
- 'region_id' => 'region_id',
140
- 'postcode' => 'postcode',
141
- 'city' => 'city',
142
- ))),
143
- 'shipto' => Mage::getModel('owebia_shipping2/Os2_Data_Address', $this->_extract($request->getData(), array(
144
- 'country_id' => 'dest_country_id',
145
- 'region_id' => 'dest_region_id',
146
- 'region_code' => 'dest_region_code',
147
- 'street' => 'dest_street',
148
- 'city' => 'dest_city',
149
- 'postcode' => 'dest_postcode',
150
- ))),
151
- 'billto' => Mage::getModel('owebia_shipping2/Os2_Data_Billto'),
152
- 'store' => Mage::getModel('owebia_shipping2/Os2_Data_Store', array('id' => $request->getData('store_id'))),
153
- 'request' => Mage::getModel('owebia_shipping2/Os2_Data_Abstract', $request->getData()),
154
- );
155
- }
156
 
157
- protected function _extract($data, $attributes)
158
- {
159
- $extract = array();
160
- foreach ($attributes as $to => $from) {
161
- $extract[$to] = isset($data[$from]) ? $data[$from] : null;
162
- }
163
- return $extract;
164
- }
165
  }
21
 
22
  class Owebia_Shipping2_Helper_Data extends Mage_Core_Helper_Data
23
  {
24
+ protected $_translate_inline;
25
 
26
+ public function __()
27
+ {
28
+ $args = func_get_args();
29
+ if (isset($args[0]) && is_array($args[0]) && count($args)==1) {
30
+ $args = $args[0];
31
+ }
32
+ $message = array_shift($args);
33
+ if ($message instanceof OS_Message) {
34
+ $args = $message->args;
35
+ $message = $message->message;
36
+ }
37
+
38
+ $output = parent::__($message);
39
+
40
+ /*if (true) {
41
+ $translations = @file_get_contents('translations.os2');
42
+ $translations = eval('return '.$translations.';');
43
+ if (!is_array($translations)) $translations = array();
44
 
45
+ $file = 'NC';
46
+ $line = 'NC';
47
+ $backtrace = debug_backtrace();
48
+ foreach ($backtrace as $trace) {
49
+ if (!isset($trace['function'])) continue;
50
+ if (substr($trace['function'], strlen($trace['function'])-2, strlen($trace['function']))=='__') {
51
+ $file = ltrim(str_replace(Mage::getBaseDir(), '', $trace['file']), '/');
52
+ $line = $trace['line'];
53
+ continue;
54
+ }
55
+ //$file = ltrim(str_replace(Mage::getBaseDir(), '', $trace['file']), '/');
56
+ //echo $file.', '.$trace['function'].'(), '.$line.', '.$message.'<br/>';
57
+ break;
58
+ }
59
 
60
+ $translations[Mage::app()->getLocale()->getLocaleCode()][$file][$message] = $output;
61
+ ksort($translations[Mage::app()->getLocale()->getLocaleCode()]);
62
+ file_put_contents('translations.os2', var_export($translations, true));
63
+ }*/
64
 
65
+ if (count($args)==0) {
66
+ $result = $output;
67
+ } else {
68
+ if (!isset($this->_translate_inline)) $this->_translate_inline = Mage::getSingleton('core/translate')->getTranslateInline();
69
+ if ($this->_translate_inline) {
70
+ $parts = explode('}}{{', $output);
71
+ $parts[0] = vsprintf($parts[0], $args);
72
+ $result = implode('}}{{', $parts);
73
+ } else {
74
+ $result = vsprintf($output, $args);
75
+ }
76
+ }
77
+ return $result;
78
+ }
79
 
80
+ public function getMethodText($helper, $process, $row, $property)
81
+ {
82
+ if (!isset($row[$property])) return '';
83
 
84
+ $output = '';
85
+ $cart = $process['data']['cart'];
86
+ return $helper->evalInput($process, $row, $property, str_replace(
87
+ array(
88
+ '{cart.weight}',
89
+ '{cart.price-tax+discount}',
90
+ '{cart.price-tax-discount}',
91
+ '{cart.price+tax+discount}',
92
+ '{cart.price+tax-discount}',
93
+ ),
94
+ array(
95
+ $cart->weight . $cart->weight_unit,
96
+ $this->currency($cart->{'price-tax+discount'}),
97
+ $this->currency($cart->{'price-tax-discount'}),
98
+ $this->currency($cart->{'price+tax+discount'}),
99
+ $this->currency($cart->{'price+tax-discount'}),
100
+ ),
101
+ $helper->getRowProperty($row, $property)
102
+ ));
103
+ }
104
+
105
+ public function getDataModelMap($helper, $carrier_code, $request)
106
+ {
107
+ $mage_config = Mage::getConfig();
108
+ return array(
109
+ 'info' => Mage::getModel('owebia_shipping2/Os2_Data_Info', array_merge($helper->getInfos(), array(
110
+ 'magento_version' => Mage::getVersion(),
111
+ 'module_version' => (string)$mage_config->getNode('modules/Owebia_Shipping2/version'),
112
+ 'carrier_code' => $carrier_code,
113
+ ))),
114
+ 'cart' => Mage::getModel('owebia_shipping2/Os2_Data_Cart', array(
115
+ 'request' => $request,
116
+ 'options' => array(
117
+ 'bundle' => array(
118
+ 'process_children' => (boolean)Mage::getStoreConfig('owebia_shipping2/bundle_product/process_children'),
119
+ 'load_item_options_on_parent' => (boolean)Mage::getStoreConfig('owebia_shipping2/bundle_product/load_item_options_on_parent'),
120
+ 'load_item_data_on_parent' => (boolean)Mage::getStoreConfig('owebia_shipping2/bundle_product/load_item_data_on_parent'),
121
+ 'load_product_data_on_parent' => (boolean)Mage::getStoreConfig('owebia_shipping2/bundle_product/load_product_data_on_parent'),
122
+ ),
123
+ 'configurable' => array(
124
+ 'load_item_options_on_parent' => (boolean)Mage::getStoreConfig('owebia_shipping2/configurable_product/load_item_options_on_parent'),
125
+ 'load_item_data_on_parent' => (boolean)Mage::getStoreConfig('owebia_shipping2/configurable_product/load_item_data_on_parent'),
126
+ 'load_product_data_on_parent' => (boolean)Mage::getStoreConfig('owebia_shipping2/configurable_product/load_product_data_on_parent'),
127
+ ),
128
+ ),
129
+ )),
130
+ 'quote' => Mage::getModel('owebia_shipping2/Os2_Data_Quote'),
131
+ 'selection' => Mage::getModel('owebia_shipping2/Os2_Data_Selection'),
132
+ 'customer' => Mage::getModel('owebia_shipping2/Os2_Data_Customer'),
133
+ 'customer_group' => Mage::getModel('owebia_shipping2/Os2_Data_CustomerGroup'),
134
+ 'customvar' => Mage::getModel('owebia_shipping2/Os2_Data_Customvar'),
135
+ 'date' => Mage::getModel('owebia_shipping2/Os2_Data_Date'),
136
+ 'address_filter' => Mage::getModel('owebia_shipping2/Os2_Data_AddressFilter'),
137
+ 'origin' => Mage::getModel('owebia_shipping2/Os2_Data_Address', $this->_extract($request->getData(), array(
138
+ 'country_id' => 'country_id',
139
+ 'region_id' => 'region_id',
140
+ 'postcode' => 'postcode',
141
+ 'city' => 'city',
142
+ ))),
143
+ 'shipto' => Mage::getModel('owebia_shipping2/Os2_Data_Address', $this->_extract($request->getData(), array(
144
+ 'country_id' => 'dest_country_id',
145
+ 'region_id' => 'dest_region_id',
146
+ 'region_code' => 'dest_region_code',
147
+ 'street' => 'dest_street',
148
+ 'city' => 'dest_city',
149
+ 'postcode' => 'dest_postcode',
150
+ ))),
151
+ 'billto' => Mage::getModel('owebia_shipping2/Os2_Data_Billto'),
152
+ 'store' => Mage::getModel('owebia_shipping2/Os2_Data_Store', array('id' => $request->getData('store_id'))),
153
+ 'request' => Mage::getModel('owebia_shipping2/Os2_Data_Abstract', $request->getData()),
154
+ );
155
+ }
156
 
157
+ protected function _extract($data, $attributes)
158
+ {
159
+ $extract = array();
160
+ foreach ($attributes as $to => $from) {
161
+ $extract[$to] = isset($data[$from]) ? $data[$from] : null;
162
+ }
163
+ return $extract;
164
+ }
165
  }
app/code/community/Owebia/Shipping2/Model/Carrier/Abstract.php CHANGED
@@ -21,197 +21,197 @@
21
 
22
  // if compilation
23
  if (file_exists(dirname(__FILE__).'/Owebia_Shipping2_includes_OwebiaShippingHelper.php')) {
24
- include_once 'Owebia_Shipping2_includes_OS2_AddressFilterParser.php';
25
- include_once 'Owebia_Shipping2_includes_OwebiaShippingHelper.php';
26
  } else {
27
- include_once Mage::getBaseDir('code').'/community/Owebia/Shipping2/includes/OS2_AddressFilterParser.php';
28
- include_once Mage::getBaseDir('code').'/community/Owebia/Shipping2/includes/OwebiaShippingHelper.php';
29
  }
30
 
31
  abstract class Owebia_Shipping2_Model_Carrier_Abstract extends Mage_Shipping_Model_Carrier_Abstract
32
  {
33
- protected $_config;
34
- protected $_helper;
35
- protected $_data_models = array();
36
-
37
- /**
38
- * Collect rates for this shipping method based on information in $request
39
- *
40
- * @param Mage_Shipping_Model_Rate_Request $data
41
- * @return Mage_Shipping_Model_Rate_Result
42
- */
43
- public function collectRates(Mage_Shipping_Model_Rate_Request $request)
44
- {
45
- //setlocale(LC_NUMERIC, 'fr_FR');
46
- if (!$this->__getConfigData('active')) return false; // skip if not enabled
47
- //$this->display($request->_data);
48
- $process = $this->__getProcess($request);
49
- return $this->getRates($process);
50
- }
51
-
52
- public function display($var)
53
- {
54
- $i = 0;
55
- foreach ($var as $name => $value) {
56
- //if ($i>20)
57
- echo "{$name} => {$value}<br/>";
58
- //$this->_helper->debug($name.' => '.$value.'<br/>');
59
- $i++;
60
- }
61
- }
62
-
63
- public function getRates($process)
64
- {
65
- $this->_process($process);
66
- return $process['result'];
67
- }
68
-
69
- public function getAllowedMethods()
70
- {
71
- $process = array();
72
- $config = $this->_getConfig();
73
- $allowed_methods = array();
74
- if (count($config)>0) {
75
- foreach ($config as $row) $allowed_methods[$row['*id']] = isset($row['label']) ? $row['label']['value'] : 'No label';
76
- }
77
- return $allowed_methods;
78
- }
79
-
80
- public function isTrackingAvailable()
81
- {
82
- return true;
83
- }
84
-
85
- public function getTrackingInfo($tracking_number)
86
- {
87
- $original_tracking_number = $tracking_number;
88
- $global_tracking_url = $this->__getConfigData('tracking_view_url');
89
- $tracking_url = $global_tracking_url;
90
- $parts = explode(':', $tracking_number);
91
- if (count($parts)>=2) {
92
- $tracking_number = $parts[1];
93
-
94
- $process = array();
95
- $config = $this->_getConfig();
96
-
97
- if (isset($config[$parts[0]]['tracking_url'])) {
98
- $row = $config[$parts[0]];
99
- $tmp_tracking_url = $this->_helper->getRowProperty($row, 'tracking_url');
100
- if (isset($tmp_tracking_url)) $tracking_url = $tmp_tracking_url;
101
- }
102
- }
103
-
104
- $tracking_status = Mage::getModel('shipping/tracking_result_status')
105
- ->setCarrier($this->_code)
106
- ->setCarrierTitle($this->__getConfigData('title'))
107
- ->setTracking($tracking_number)
108
- ->addData(
109
- array(
110
- 'status'=> $tracking_url ? '<a target="_blank" href="' . str_replace('{tracking_number}', $tracking_number, $tracking_url) . '">' . $this->__('track the package') . '</a>' : "suivi non disponible pour le colis {$tracking_number} (original_tracking_number='{$original_tracking_number}', global_tracking_url='{$global_tracking_url}'" . (isset($row) ? ", tmp_tracking_url='{$tmp_tracking_url}'" : '') . ")"
111
- )
112
- )
113
- ;
114
- $tracking_result = Mage::getModel('shipping/tracking_result')
115
- ->append($tracking_status)
116
- ;
117
-
118
- if ($trackings = $tracking_result->getAllTrackings()) return $trackings[0];
119
- return false;
120
- }
121
-
122
- /***************************************************************************************************************************/
123
-
124
- protected function _process(&$process)
125
- {
126
- $debug = (bool)(isset($_GET['debug']) ? $_GET['debug'] : $this->__getConfigData('debug'));
127
- if ($debug) $this->_helper->initDebug($this->_code, $process);
128
-
129
- $value_found = false;
130
- foreach ($process['config'] as $row) {
131
- $result = $this->_helper->processRow($process, $row);
132
- if ($result->success) {
133
- $value_found = true;
134
- $this->__appendMethod($process, $row, $result->result);
135
- if ($process['options']->stop_to_first_match) break;
136
- }
137
- }
138
-
139
- $http_request = Mage::app()->getFrontController()->getRequest();
140
- if ($debug && $this->__checkRequest($http_request, 'checkout/cart/index')) {
141
- Mage::getSingleton('core/session')
142
- ->addNotice('DEBUG'.$this->_helper->getDebug());
143
- }
144
- }
145
-
146
- protected function _getConfig()
147
- {
148
- if (!isset($this->_config)) {
149
- $this->_helper = new OwebiaShippingHelper(
150
- $this->__getConfigData('config'),
151
- (boolean)$this->__getConfigData('auto_correction')
152
- );
153
- $this->_config = $this->_helper->getConfig();
154
- }
155
- return $this->_config;
156
- }
157
-
158
- /***************************************************************************************************************************/
159
-
160
- protected function __checkRequest($http_request, $path)
161
- {
162
- list($router, $controller, $action) = explode('/', $path);
163
- return $http_request->getRouteName()==$router && $http_request->getControllerName()==$controller && $http_request->getActionName()==$action;
164
- }
165
-
166
- protected function __getProcess($request)
167
- {
168
- $mage_config = Mage::getConfig();
169
- $os2_config = $this->_getConfig();
170
- $data = Mage::helper('owebia_shipping2')->getDataModelMap($this->_helper, $this->_code, $request);
171
- $process = array(
172
- 'data' => $data,
173
- 'cart.items' => array(),
174
- 'config' => $os2_config,
175
- 'result' => Mage::getModel('shipping/rate_result'),
176
- 'options' => (object)array(
177
- 'auto_escaping' => (boolean)$this->__getConfigData('auto_escaping'),
178
- 'auto_correction' => (boolean)$this->__getConfigData('auto_correction'),
179
- 'stop_to_first_match' => (boolean)$this->__getConfigData('stop_to_first_match'),
180
- ),
181
- );
182
- return $process;
183
- }
184
-
185
- public function addDataModel($name, $model)
186
- {
187
- $this->_data_models[$name] = $model;
188
- }
189
-
190
- protected function __getConfigData($key)
191
- {
192
- return $this->getConfigData($key);
193
- }
194
-
195
- protected function __appendMethod(&$process, $row, $fees)
196
- {
197
- $helper = Mage::helper('owebia_shipping2');
198
- $method = Mage::getModel('shipping/rate_result_method')
199
- ->setCarrier($this->_code)
200
- ->setCarrierTitle($this->__getConfigData('title'))
201
- ->setMethod($row['*id'])
202
- ->setMethodTitle($helper->getMethodText($this->_helper, $process, $row, 'label'))
203
- ->setMethodDescription($helper->getMethodText($this->_helper, $process, $row, 'description'))
204
- ->setPrice($fees)
205
- ->setCost($fees)
206
- ;
207
-
208
- $process['result']->append($method);
209
- }
210
-
211
- protected function __()
212
- {
213
- $args = func_get_args();
214
- return Mage::helper('owebia_shipping2')->__($args);
215
- }
216
  }
217
 
21
 
22
  // if compilation
23
  if (file_exists(dirname(__FILE__).'/Owebia_Shipping2_includes_OwebiaShippingHelper.php')) {
24
+ include_once 'Owebia_Shipping2_includes_OS2_AddressFilterParser.php';
25
+ include_once 'Owebia_Shipping2_includes_OwebiaShippingHelper.php';
26
  } else {
27
+ include_once Mage::getBaseDir('code').'/community/Owebia/Shipping2/includes/OS2_AddressFilterParser.php';
28
+ include_once Mage::getBaseDir('code').'/community/Owebia/Shipping2/includes/OwebiaShippingHelper.php';
29
  }
30
 
31
  abstract class Owebia_Shipping2_Model_Carrier_Abstract extends Mage_Shipping_Model_Carrier_Abstract
32
  {
33
+ protected $_config;
34
+ protected $_helper;
35
+ protected $_data_models = array();
36
+
37
+ /**
38
+ * Collect rates for this shipping method based on information in $request
39
+ *
40
+ * @param Mage_Shipping_Model_Rate_Request $data
41
+ * @return Mage_Shipping_Model_Rate_Result
42
+ */
43
+ public function collectRates(Mage_Shipping_Model_Rate_Request $request)
44
+ {
45
+ //setlocale(LC_NUMERIC, 'fr_FR');
46
+ if (!$this->__getConfigData('active')) return false; // skip if not enabled
47
+ //$this->display($request->_data);
48
+ $process = $this->__getProcess($request);
49
+ return $this->getRates($process);
50
+ }
51
+
52
+ public function display($var)
53
+ {
54
+ $i = 0;
55
+ foreach ($var as $name => $value) {
56
+ //if ($i>20)
57
+ echo "{$name} => {$value}<br/>";
58
+ //$this->_helper->debug($name.' => '.$value.'<br/>');
59
+ $i++;
60
+ }
61
+ }
62
+
63
+ public function getRates($process)
64
+ {
65
+ $this->_process($process);
66
+ return $process['result'];
67
+ }
68
+
69
+ public function getAllowedMethods()
70
+ {
71
+ $process = array();
72
+ $config = $this->_getConfig();
73
+ $allowed_methods = array();
74
+ if (count($config)>0) {
75
+ foreach ($config as $row) $allowed_methods[$row['*id']] = isset($row['label']) ? $row['label']['value'] : 'No label';
76
+ }
77
+ return $allowed_methods;
78
+ }
79
+
80
+ public function isTrackingAvailable()
81
+ {
82
+ return true;
83
+ }
84
+
85
+ public function getTrackingInfo($tracking_number)
86
+ {
87
+ $original_tracking_number = $tracking_number;
88
+ $global_tracking_url = $this->__getConfigData('tracking_view_url');
89
+ $tracking_url = $global_tracking_url;
90
+ $parts = explode(':', $tracking_number);
91
+ if (count($parts)>=2) {
92
+ $tracking_number = $parts[1];
93
+
94
+ $process = array();
95
+ $config = $this->_getConfig();
96
+
97
+ if (isset($config[$parts[0]]['tracking_url'])) {
98
+ $row = $config[$parts[0]];
99
+ $tmp_tracking_url = $this->_helper->getRowProperty($row, 'tracking_url');
100
+ if (isset($tmp_tracking_url)) $tracking_url = $tmp_tracking_url;
101
+ }
102
+ }
103
+
104
+ $tracking_status = Mage::getModel('shipping/tracking_result_status')
105
+ ->setCarrier($this->_code)
106
+ ->setCarrierTitle($this->__getConfigData('title'))
107
+ ->setTracking($tracking_number)
108
+ ->addData(
109
+ array(
110
+ 'status'=> $tracking_url ? '<a target="_blank" href="' . str_replace('{tracking_number}', $tracking_number, $tracking_url) . '">' . $this->__('track the package') . '</a>' : "suivi non disponible pour le colis {$tracking_number} (original_tracking_number='{$original_tracking_number}', global_tracking_url='{$global_tracking_url}'" . (isset($row) ? ", tmp_tracking_url='{$tmp_tracking_url}'" : '') . ")"
111
+ )
112
+ )
113
+ ;
114
+ $tracking_result = Mage::getModel('shipping/tracking_result')
115
+ ->append($tracking_status)
116
+ ;
117
+
118
+ if ($trackings = $tracking_result->getAllTrackings()) return $trackings[0];
119
+ return false;
120
+ }
121
+
122
+ /***************************************************************************************************************************/
123
+
124
+ protected function _process(&$process)
125
+ {
126
+ $debug = (bool)(isset($_GET['debug']) ? $_GET['debug'] : $this->__getConfigData('debug'));
127
+ if ($debug) $this->_helper->initDebug($this->_code, $process);
128
+
129
+ $value_found = false;
130
+ foreach ($process['config'] as $row) {
131
+ $result = $this->_helper->processRow($process, $row);
132
+ if ($result->success) {
133
+ $value_found = true;
134
+ $this->__appendMethod($process, $row, $result->result);
135
+ if ($process['options']->stop_to_first_match) break;
136
+ }
137
+ }
138
+
139
+ $http_request = Mage::app()->getFrontController()->getRequest();
140
+ if ($debug && $this->__checkRequest($http_request, 'checkout/cart/index')) {
141
+ Mage::getSingleton('core/session')
142
+ ->addNotice('DEBUG'.$this->_helper->getDebug());
143
+ }
144
+ }
145
+
146
+ protected function _getConfig()
147
+ {
148
+ if (!isset($this->_config)) {
149
+ $this->_helper = new OwebiaShippingHelper(
150
+ $this->__getConfigData('config'),
151
+ (boolean)$this->__getConfigData('auto_correction')
152
+ );
153
+ $this->_config = $this->_helper->getConfig();
154
+ }
155
+ return $this->_config;
156
+ }
157
+
158
+ /***************************************************************************************************************************/
159
+
160
+ protected function __checkRequest($http_request, $path)
161
+ {
162
+ list($router, $controller, $action) = explode('/', $path);
163
+ return $http_request->getRouteName()==$router && $http_request->getControllerName()==$controller && $http_request->getActionName()==$action;
164
+ }
165
+
166
+ protected function __getProcess($request)
167
+ {
168
+ $mage_config = Mage::getConfig();
169
+ $os2_config = $this->_getConfig();
170
+ $data = Mage::helper('owebia_shipping2')->getDataModelMap($this->_helper, $this->_code, $request);
171
+ $process = array(
172
+ 'data' => $data,
173
+ 'cart.items' => array(),
174
+ 'config' => $os2_config,
175
+ 'result' => Mage::getModel('shipping/rate_result'),
176
+ 'options' => (object)array(
177
+ 'auto_escaping' => (boolean)$this->__getConfigData('auto_escaping'),
178
+ 'auto_correction' => (boolean)$this->__getConfigData('auto_correction'),
179
+ 'stop_to_first_match' => (boolean)$this->__getConfigData('stop_to_first_match'),
180
+ ),
181
+ );
182
+ return $process;
183
+ }
184
+
185
+ public function addDataModel($name, $model)
186
+ {
187
+ $this->_data_models[$name] = $model;
188
+ }
189
+
190
+ protected function __getConfigData($key)
191
+ {
192
+ return $this->getConfigData($key);
193
+ }
194
+
195
+ protected function __appendMethod(&$process, $row, $fees)
196
+ {
197
+ $helper = Mage::helper('owebia_shipping2');
198
+ $method = Mage::getModel('shipping/rate_result_method')
199
+ ->setCarrier($this->_code)
200
+ ->setCarrierTitle($this->__getConfigData('title'))
201
+ ->setMethod($row['*id'])
202
+ ->setMethodTitle($helper->getMethodText($this->_helper, $process, $row, 'label'))
203
+ ->setMethodDescription($helper->getMethodText($this->_helper, $process, $row, 'description'))
204
+ ->setPrice($fees)
205
+ ->setCost($fees)
206
+ ;
207
+
208
+ $process['result']->append($method);
209
+ }
210
+
211
+ protected function __()
212
+ {
213
+ $args = func_get_args();
214
+ return Mage::helper('owebia_shipping2')->__($args);
215
+ }
216
  }
217
 
app/code/community/Owebia/Shipping2/Model/Carrier/OwebiaShipping1.php CHANGED
@@ -21,5 +21,5 @@
21
 
22
  class Owebia_Shipping2_Model_Carrier_OwebiaShipping1 extends Owebia_Shipping2_Model_Carrier_Abstract
23
  {
24
- protected $_code = 'owebiashipping1';
25
  }
21
 
22
  class Owebia_Shipping2_Model_Carrier_OwebiaShipping1 extends Owebia_Shipping2_Model_Carrier_Abstract
23
  {
24
+ protected $_code = 'owebiashipping1';
25
  }
app/code/community/Owebia/Shipping2/Model/Carrier/OwebiaShipping2.php CHANGED
@@ -21,5 +21,5 @@
21
 
22
  class Owebia_Shipping2_Model_Carrier_OwebiaShipping2 extends Owebia_Shipping2_Model_Carrier_Abstract
23
  {
24
- protected $_code = 'owebiashipping2';
25
  }
21
 
22
  class Owebia_Shipping2_Model_Carrier_OwebiaShipping2 extends Owebia_Shipping2_Model_Carrier_Abstract
23
  {
24
+ protected $_code = 'owebiashipping2';
25
  }
app/code/community/Owebia/Shipping2/Model/Carrier/OwebiaShipping3.php CHANGED
@@ -21,5 +21,5 @@
21
 
22
  class Owebia_Shipping2_Model_Carrier_OwebiaShipping3 extends Owebia_Shipping2_Model_Carrier_Abstract
23
  {
24
- protected $_code = 'owebiashipping3';
25
  }
21
 
22
  class Owebia_Shipping2_Model_Carrier_OwebiaShipping3 extends Owebia_Shipping2_Model_Carrier_Abstract
23
  {
24
+ protected $_code = 'owebiashipping3';
25
  }
app/code/community/Owebia/Shipping2/Model/Carrier/OwebiaShipping4.php DELETED
@@ -1,25 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Copyright (c) 2008-14 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,
8
- * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9
- *
10
- * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
13
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
14
- * IN THE SOFTWARE.
15
- *
16
- * @website http://www.owebia.com/
17
- * @project Magento Owebia Shipping 2 module
18
- * @author Antoine Lemoine
19
- * @license http://www.opensource.org/licenses/MIT The MIT License (MIT)
20
- **/
21
-
22
- class Owebia_Shipping2_Model_Carrier_OwebiaShipping4 extends Owebia_Shipping2_Model_Carrier_Abstract
23
- {
24
- protected $_code = 'owebiashipping4';
25
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Owebia/Shipping2/Model/Mysql4/Setup.php CHANGED
@@ -21,4 +21,4 @@
21
 
22
  class Owebia_Shipping2_Model_Mysql4_Setup extends Mage_Catalog_Model_Resource_Eav_Mysql4_Setup
23
  {
24
- }
21
 
22
  class Owebia_Shipping2_Model_Mysql4_Setup extends Mage_Catalog_Model_Resource_Eav_Mysql4_Setup
23
  {
24
+ }
app/code/community/Owebia/Shipping2/Model/Os2/Data/Abstract.php CHANGED
@@ -21,57 +21,61 @@
21
 
22
  class Owebia_Shipping2_Model_Os2_Data_Abstract
23
  {
24
- protected $additional_attributes = array();
25
- protected $_attributes;
26
- protected $_loaded_object = false;
27
- protected $_data;
28
 
29
- public function __construct($arguments=null) {
30
- $this->_data = (array)$arguments;
31
- //echo '<pre>Owebia_Shipping2_Model_Os2_Data_Abstract::__construct<br/>';foreach ($this->_data as $n => $v){echo "\t$n => ".(is_object($v) ? get_class($v) : (is_array($v) ? 'array' : $v))."<br/>";}
32
- }
 
33
 
34
- protected function _loadObject() {
35
- return null;
36
- }
 
37
 
38
- protected function _getObject() {
39
- if ($this->_loaded_object===false) $this->_loaded_object = $this->_loadObject();
40
- //foreach ($this->_loaded_object->getData() as $index => $value) echo "$index = $value<br/>";
41
- return $this->_loaded_object;
42
- }
 
43
 
44
- protected function _load($name) {
45
- $object = $this->_getObject();
46
- if (!$object) return null;
47
- /*echo get_class($this).'.getData('.$name.')'.$object->getData($name).'<br/>';
48
- foreach ($object->getData() as $index => $value) echo "$index = $value<br/>";*/
49
- return $object->getData($name);
50
- }
 
51
 
52
- public function __sleep() {
53
- if (isset($this->_attributes)) return $this->_attributes;
54
- $this->_attributes = array_unique(array_merge(array_keys($this->_data), $this->additional_attributes));
55
- /*usort($this->_attributes, function($v1, $v2){
56
- if ($v1=='id') return -1;
57
- if ($v2=='id') return 1;
58
- if ($v2=='*') return -1;
59
- if ($v1=='*') return 1;
60
- return $v1==$v2 ? 0 : ($v1<$v2 ? -1 : 1);
61
- });*/
62
- return $this->_attributes;
63
- }
 
64
 
65
- public function __get($name) {
66
- /*$name2 = str_replace('.', '_', $name);
67
- if (isset($this->_data[$name2])) return $this->_data[$name2];*/
68
- //if (isset($this->_data[$name])) return $this->_data[$name]; // pb if id is null
69
- if (!is_array($this->_data)) $this->_data = array();
70
- if (array_key_exists($name, $this->_data)) return $this->_data[$name];
71
- //if (in_array($name, $this->additional_attributes)) $this->_data[$name] = $this->_load($name);
72
- $this->_data[$name] = $this->_load($name);
73
- return $this->_data[$name];
74
- }
 
75
  }
76
-
77
- ?>
21
 
22
  class Owebia_Shipping2_Model_Os2_Data_Abstract
23
  {
24
+ protected $additional_attributes = array();
25
+ protected $_attributes;
26
+ protected $_loaded_object = false;
27
+ protected $_data;
28
 
29
+ public function __construct($arguments = null)
30
+ {
31
+ $this->_data = (array)$arguments;
32
+ //echo '<pre>Owebia_Shipping2_Model_Os2_Data_Abstract::__construct<br/>';foreach ($this->_data as $n => $v){echo "\t$n => ".(is_object($v) ? get_class($v) : (is_array($v) ? 'array' : $v))."<br/>";}
33
+ }
34
 
35
+ protected function _loadObject()
36
+ {
37
+ return null;
38
+ }
39
 
40
+ protected function _getObject()
41
+ {
42
+ if ($this->_loaded_object===false) $this->_loaded_object = $this->_loadObject();
43
+ //foreach ($this->_loaded_object->getData() as $index => $value) echo "$index = $value<br/>";
44
+ return $this->_loaded_object;
45
+ }
46
 
47
+ protected function _load($name)
48
+ {
49
+ $object = $this->_getObject();
50
+ if (!$object) return null;
51
+ /*echo get_class($this).'.getData('.$name.')'.$object->getData($name).'<br/>';
52
+ foreach ($object->getData() as $index => $value) echo "$index = $value<br/>";*/
53
+ return $object->getData($name);
54
+ }
55
 
56
+ public function __sleep()
57
+ {
58
+ if (isset($this->_attributes)) return $this->_attributes;
59
+ $this->_attributes = array_unique(array_merge(array_keys($this->_data), $this->additional_attributes));
60
+ /*usort($this->_attributes, function($v1, $v2){
61
+ if ($v1=='id') return -1;
62
+ if ($v2=='id') return 1;
63
+ if ($v2=='*') return -1;
64
+ if ($v1=='*') return 1;
65
+ return $v1==$v2 ? 0 : ($v1<$v2 ? -1 : 1);
66
+ });*/
67
+ return $this->_attributes;
68
+ }
69
 
70
+ public function __get($name)
71
+ {
72
+ /*$name2 = str_replace('.', '_', $name);
73
+ if (isset($this->_data[$name2])) return $this->_data[$name2];*/
74
+ //if (isset($this->_data[$name])) return $this->_data[$name]; // pb if id is null
75
+ if (!is_array($this->_data)) $this->_data = array();
76
+ if (array_key_exists($name, $this->_data)) return $this->_data[$name];
77
+ //if (in_array($name, $this->additional_attributes)) $this->_data[$name] = $this->_load($name);
78
+ $this->_data[$name] = $this->_load($name);
79
+ return $this->_data[$name];
80
+ }
81
  }
 
 
app/code/community/Owebia/Shipping2/Model/Os2/Data/AbstractWithAttributes.php CHANGED
@@ -21,47 +21,47 @@
21
 
22
  class Owebia_Shipping2_Model_Os2_Data_AbstractWithAttributes extends Owebia_Shipping2_Model_Os2_Data_Abstract
23
  {
24
- protected function _load($name) {
25
- $elems = explode('.', $name, $limit=2);
26
- $count = count($elems);
27
- $last_index = $count-1;
28
- if ($count==2) {
29
- switch ($elems[0]) {
30
- case 'a':
31
- case 'attribute':
32
- $name = $elems[1];
33
- return $this->_getAttribute($name);
34
- }
35
- }
36
- //return parent::_load($name);
37
- return $this->_getAttribute($name);
38
- }
 
39
 
40
- protected function _getAttribute($attribute_name) {
41
- $get_value = false;
42
- if (substr($attribute_name, strlen($attribute_name)-6, 6)=='.value') {
43
- $get_value = true;
44
- $attribute_name = substr($attribute_name, 0, strlen($attribute_name)-6);
45
- }
 
46
 
47
- $object = $this->_getObject();
48
- if (!$object) return null;
49
- $attribute = $object->getResource()->getAttribute($attribute_name);
50
- if (!$attribute) return null;
51
 
52
- $attribute_frontend = $attribute->getFrontend();
53
- $input_type = $attribute_frontend->getInputType();
54
- switch ($input_type) {
55
- case 'select' :
56
- //echo 'attribute_name:'.$object->getData($attribute_name).', '.$attribute_frontend->getValue($object).';<br/>';
57
- $value = !$get_value ? $object->getData($attribute_name) : $attribute_frontend->getValue($object);
58
- break;
59
- default :
60
- $value = $object->getData($attribute_name);
61
- break;
62
- }
63
- return $value;
64
- }
65
  }
66
-
67
- ?>
21
 
22
  class Owebia_Shipping2_Model_Os2_Data_AbstractWithAttributes extends Owebia_Shipping2_Model_Os2_Data_Abstract
23
  {
24
+ protected function _load($name)
25
+ {
26
+ $elems = explode('.', $name, $limit=2);
27
+ $count = count($elems);
28
+ $last_index = $count-1;
29
+ if ($count==2) {
30
+ switch ($elems[0]) {
31
+ case 'a':
32
+ case 'attribute':
33
+ $name = $elems[1];
34
+ return $this->_getAttribute($name);
35
+ }
36
+ }
37
+ //return parent::_load($name);
38
+ return $this->_getAttribute($name);
39
+ }
40
 
41
+ protected function _getAttribute($attribute_name)
42
+ {
43
+ $get_value = false;
44
+ if (substr($attribute_name, strlen($attribute_name)-6, 6)=='.value') {
45
+ $get_value = true;
46
+ $attribute_name = substr($attribute_name, 0, strlen($attribute_name)-6);
47
+ }
48
 
49
+ $object = $this->_getObject();
50
+ if (!$object) return null;
51
+ $attribute = $object->getResource()->getAttribute($attribute_name);
52
+ if (!$attribute) return null;
53
 
54
+ $attribute_frontend = $attribute->getFrontend();
55
+ $input_type = $attribute_frontend->getInputType();
56
+ switch ($input_type) {
57
+ case 'select' :
58
+ //echo 'attribute_name:'.$object->getData($attribute_name).', '.$attribute_frontend->getValue($object).';<br/>';
59
+ $value = !$get_value ? $object->getData($attribute_name) : $attribute_frontend->getValue($object);
60
+ break;
61
+ default :
62
+ $value = $object->getData($attribute_name);
63
+ break;
64
+ }
65
+ return $value;
66
+ }
67
  }
 
 
app/code/community/Owebia/Shipping2/Model/Os2/Data/Address.php CHANGED
@@ -21,15 +21,14 @@
21
 
22
  class Owebia_Shipping2_Model_Os2_Data_Address extends Owebia_Shipping2_Model_Os2_Data_Abstract
23
  {
24
- protected $additional_attributes = array('country_id', 'country_name', 'postcode');
25
 
26
- protected function _load($name) {
27
- switch ($name) {
28
- case 'country_name':
29
- return Mage::getModel('directory/country')->load($this->country_id)->getName();
30
- }
31
- return parent::_load($name);
32
- }
 
33
  }
34
-
35
- ?>
21
 
22
  class Owebia_Shipping2_Model_Os2_Data_Address extends Owebia_Shipping2_Model_Os2_Data_Abstract
23
  {
24
+ protected $additional_attributes = array('country_id', 'country_name', 'postcode');
25
 
26
+ protected function _load($name)
27
+ {
28
+ switch ($name) {
29
+ case 'country_name':
30
+ return Mage::getModel('directory/country')->load($this->country_id)->getName();
31
+ }
32
+ return parent::_load($name);
33
+ }
34
  }
 
 
app/code/community/Owebia/Shipping2/Model/Os2/Data/AddressFilter.php CHANGED
@@ -21,90 +21,90 @@
21
 
22
  class Owebia_Shipping2_Model_Os2_Data_AddressFilter extends Owebia_Shipping2_Model_Os2_Data_Abstract
23
  {
24
- protected static $_countries = null;
25
 
26
- // source : geonames.org, 2012-09-26
27
- protected static $_shortcuts = array(
28
- // continents
29
- 'AF' => array(
30
- 'label' => 'Africa',
31
- 'replace' => 'AO,BF,BI,BJ,BW,CD,CF,CG,CI,CM,CV,DJ,DZ,EG,EH,ER,ET,GA,GH,GM,GN,GQ,GW,KE,KM,LR,LS,LY,MA,MG,ML,MR,MU,MW,MZ,NA,NE,NG,RE,RW,SC,SD,SS,SH,SL,SN,SO,ST,SZ,TD,TG,TN,TZ,UG,YT,ZA,ZM,ZW',
32
- ),
33
- 'AS' => array(
34
- 'label' => 'Asia',
35
- 'replace' => 'AE,AF,AM,AZ,BD,BH,BN,BT,CC,CN,CX,GE,HK,ID,IL,IN,IO,IQ,IR,JO,JP,KG,KH,KP,KR,KW,KZ,LA,LB,LK,MM,MN,MO,MV,MY,NP,OM,PH,PK,PS,QA,SA,SG,SY,TH,TJ,TM,TR,TW,UZ,VN,YE',
36
- ),
37
- 'EU' => array(
38
- 'label' => 'Europa',
39
- 'replace' => 'AD,AL,AT,AX,BA,BE,BG,BY,CH,CY,CZ,DE,DK,EE,ES,FI,FO,FR,GB,GG,GI,GR,HR,HU,IE,IM,IS,IT,JE,XK,LI,LT,LU,LV,MC,MD,ME,MK,MT,NL,NO,PL,PT,RO,RS,RU,SE,SI,SJ,SK,SM,UA,VA,CS',
40
- ),
41
- 'NA' => array(
42
- 'label' => 'North America',
43
- 'replace' => 'AG,AI,AW,BB,BL,BM,BQ,BS,BZ,CA,CR,CU,CW,DM,DO,GD,GL,GP,GT,HN,HT,JM,KN,KY,LC,MF,MQ,MS,MX,NI,PA,PM,PR,SV,SX,TC,TT,US,VC,VG,VI,AN',
44
- ),
45
- 'SA' => array(
46
- 'label' => 'South America',
47
- 'replace' => 'AR,BO,BR,CL,CO,EC,FK,GF,GY,PE,PY,SR,UY,VE',
48
- ),
49
- 'OC' => array(
50
- 'label' => 'Oceania',
51
- 'replace' => 'AS,AU,CK,FJ,FM,GU,KI,MH,MP,NC,NF,NR,NU,NZ,PF,PG,PN,PW,SB,TK,TL,TO,TV,UM,VU,WF,WS',
52
- ),
53
- 'AN' => array(
54
- 'label' => 'Antartica',
55
- 'replace' => 'AQ,BV,GS,HM,TF',
56
- ),
57
- /*UK=>GB*/
58
- 'EU-27' => array(
59
- 'label' => 'European Union',
60
- 'replace' => 'AT,BE,BG,CY,CZ,DE,DK,EE,EL,ES,FI,FR,HU,IE,IT,LT,LU,LV,MT,NL,PL,PT,RO,SI,SK,SE,GB',
61
- ),
62
- /* Guadeloupe, Martinique, Guyane, Réunion, Mayotte */
63
- 'DOM' => array(
64
- 'label' => "Département d'Outre-Mer",
65
- 'replace' => 'GP,MQ,GF,RE,YT',
66
- ),
67
- /* Polynésie française, Saint-Pierre-et-Miquelon, Wallis-et-Futuna, Saint-Martin, Saint-Barthélemy */
68
- 'COM' => array(
69
- 'label' => "Collectivités d'Outre-Mer",
70
- 'replace' => 'PF,PM,WF,MF,BL',
71
- ),
72
- );
73
 
74
- public static function readable($input) {
75
- if (!self::$_countries) {
76
- $collection = Mage::getModel('directory/country')->getCollection();
77
- $countries = array();
78
- foreach ($collection as $country) {
79
- $countries[$country->getId()] = $country->getName();
80
- }
81
- self::$_countries = $countries;
82
- }
83
-
84
- $elems = preg_split('/\b/', $input);
85
- $output = '';
86
- foreach ($elems as $elem) {
87
- if (isset(self::$_countries[$elem])) {
88
- $output .= self::$_countries[$elem];
89
- } else {
90
- $output .= $elem;
91
- }
92
- }
93
- while (preg_match('/{address_filter\.([^}]+)}/', $output, $result)) {
94
- $name = $result[1];
95
- $replacement = isset(self::$_shortcuts[$name]) ? self::$_shortcuts[$name]['label'] : 'unknown';
96
- $replacement = Mage::helper('owebia_shipping2')->__($replacement);
97
- $output = str_replace($result[0], $replacement, $output);
98
- }
99
- return $output;
100
- }
 
101
 
102
- protected function _load($name) {
103
- if (isset(self::$_shortcuts[$name])) {
104
- return self::$_shortcuts[$name]['replace'];
105
- }
106
- return parent::_load($name);
107
- }
 
108
  }
109
-
110
- ?>
21
 
22
  class Owebia_Shipping2_Model_Os2_Data_AddressFilter extends Owebia_Shipping2_Model_Os2_Data_Abstract
23
  {
24
+ protected static $_countries = null;
25
 
26
+ // source : geonames.org, 2012-09-26
27
+ protected static $_shortcuts = array(
28
+ // continents
29
+ 'AF' => array(
30
+ 'label' => 'Africa',
31
+ 'replace' => 'AO,BF,BI,BJ,BW,CD,CF,CG,CI,CM,CV,DJ,DZ,EG,EH,ER,ET,GA,GH,GM,GN,GQ,GW,KE,KM,LR,LS,LY,MA,MG,ML,MR,MU,MW,MZ,NA,NE,NG,RE,RW,SC,SD,SS,SH,SL,SN,SO,ST,SZ,TD,TG,TN,TZ,UG,YT,ZA,ZM,ZW',
32
+ ),
33
+ 'AS' => array(
34
+ 'label' => 'Asia',
35
+ 'replace' => 'AE,AF,AM,AZ,BD,BH,BN,BT,CC,CN,CX,GE,HK,ID,IL,IN,IO,IQ,IR,JO,JP,KG,KH,KP,KR,KW,KZ,LA,LB,LK,MM,MN,MO,MV,MY,NP,OM,PH,PK,PS,QA,SA,SG,SY,TH,TJ,TM,TR,TW,UZ,VN,YE',
36
+ ),
37
+ 'EU' => array(
38
+ 'label' => 'Europa',
39
+ 'replace' => 'AD,AL,AT,AX,BA,BE,BG,BY,CH,CY,CZ,DE,DK,EE,ES,FI,FO,FR,GB,GG,GI,GR,HR,HU,IE,IM,IS,IT,JE,XK,LI,LT,LU,LV,MC,MD,ME,MK,MT,NL,NO,PL,PT,RO,RS,RU,SE,SI,SJ,SK,SM,UA,VA,CS',
40
+ ),
41
+ 'NA' => array(
42
+ 'label' => 'North America',
43
+ 'replace' => 'AG,AI,AW,BB,BL,BM,BQ,BS,BZ,CA,CR,CU,CW,DM,DO,GD,GL,GP,GT,HN,HT,JM,KN,KY,LC,MF,MQ,MS,MX,NI,PA,PM,PR,SV,SX,TC,TT,US,VC,VG,VI,AN',
44
+ ),
45
+ 'SA' => array(
46
+ 'label' => 'South America',
47
+ 'replace' => 'AR,BO,BR,CL,CO,EC,FK,GF,GY,PE,PY,SR,UY,VE',
48
+ ),
49
+ 'OC' => array(
50
+ 'label' => 'Oceania',
51
+ 'replace' => 'AS,AU,CK,FJ,FM,GU,KI,MH,MP,NC,NF,NR,NU,NZ,PF,PG,PN,PW,SB,TK,TL,TO,TV,UM,VU,WF,WS',
52
+ ),
53
+ 'AN' => array(
54
+ 'label' => 'Antartica',
55
+ 'replace' => 'AQ,BV,GS,HM,TF',
56
+ ),
57
+ /*UK=>GB*/
58
+ 'EU-27' => array(
59
+ 'label' => 'European Union',
60
+ 'replace' => 'AT,BE,BG,CY,CZ,DE,DK,EE,EL,ES,FI,FR,HU,IE,IT,LT,LU,LV,MT,NL,PL,PT,RO,SI,SK,SE,GB',
61
+ ),
62
+ /* Guadeloupe, Martinique, Guyane, Réunion, Mayotte */
63
+ 'DOM' => array(
64
+ 'label' => "Département d'Outre-Mer",
65
+ 'replace' => 'GP,MQ,GF,RE,YT',
66
+ ),
67
+ /* Polynésie française, Saint-Pierre-et-Miquelon, Wallis-et-Futuna, Saint-Martin, Saint-Barthélemy */
68
+ 'COM' => array(
69
+ 'label' => "Collectivités d'Outre-Mer",
70
+ 'replace' => 'PF,PM,WF,MF,BL',
71
+ ),
72
+ );
73
 
74
+ public static function readable($input)
75
+ {
76
+ if (!self::$_countries) {
77
+ $collection = Mage::getModel('directory/country')->getCollection();
78
+ $countries = array();
79
+ foreach ($collection as $country) {
80
+ $countries[$country->getId()] = $country->getName();
81
+ }
82
+ self::$_countries = $countries;
83
+ }
84
+
85
+ $elems = preg_split('/\b/', $input);
86
+ $output = '';
87
+ foreach ($elems as $elem) {
88
+ if (isset(self::$_countries[$elem])) {
89
+ $output .= self::$_countries[$elem];
90
+ } else {
91
+ $output .= $elem;
92
+ }
93
+ }
94
+ while (preg_match('/{address_filter\.([^}]+)}/', $output, $result)) {
95
+ $name = $result[1];
96
+ $replacement = isset(self::$_shortcuts[$name]) ? self::$_shortcuts[$name]['label'] : 'unknown';
97
+ $replacement = Mage::helper('owebia_shipping2')->__($replacement);
98
+ $output = str_replace($result[0], $replacement, $output);
99
+ }
100
+ return $output;
101
+ }
102
 
103
+ protected function _load($name)
104
+ {
105
+ if (isset(self::$_shortcuts[$name])) {
106
+ return self::$_shortcuts[$name]['replace'];
107
+ }
108
+ return parent::_load($name);
109
+ }
110
  }
 
 
app/code/community/Owebia/Shipping2/Model/Os2/Data/AttributeSet.php CHANGED
@@ -21,16 +21,18 @@
21
 
22
  class Owebia_Shipping2_Model_Os2_Data_AttributeSet extends Owebia_Shipping2_Model_Os2_Data_Abstract
23
  {
24
- protected function _loadObject() {
25
- return Mage::getModel('eav/entity_attribute_set')->load($this->id);
26
- }
 
27
 
28
- protected function _load($name) {
29
- switch ($name) {
30
- case 'name': return $this->{'attribute_set_name'};
31
- default: return parent::_load($name);
32
- }
33
- }
 
 
 
34
  }
35
-
36
- ?>
21
 
22
  class Owebia_Shipping2_Model_Os2_Data_AttributeSet extends Owebia_Shipping2_Model_Os2_Data_Abstract
23
  {
24
+ protected function _loadObject()
25
+ {
26
+ return Mage::getModel('eav/entity_attribute_set')->load($this->id);
27
+ }
28
 
29
+ protected function _load($name)
30
+ {
31
+ switch ($name) {
32
+ case 'name':
33
+ return $this->{'attribute_set_name'};
34
+ default:
35
+ return parent::_load($name);
36
+ }
37
+ }
38
  }
 
 
app/code/community/Owebia/Shipping2/Model/Os2/Data/Billto.php CHANGED
@@ -21,17 +21,10 @@
21
 
22
  class Owebia_Shipping2_Model_Os2_Data_Billto extends Owebia_Shipping2_Model_Os2_Data_Address
23
  {
24
- protected function _load($name) {
25
- switch ($name) {
26
- }
27
- return parent::_load($name);
28
- }
29
-
30
- protected function _loadObject() {
31
- $quote = Mage::getModel('checkout/cart')->getQuote();
32
- $address = $quote->getBillingAddress();
33
- return $address;
34
- }
35
  }
36
-
37
- ?>
21
 
22
  class Owebia_Shipping2_Model_Os2_Data_Billto extends Owebia_Shipping2_Model_Os2_Data_Address
23
  {
24
+ protected function _loadObject()
25
+ {
26
+ $quote = Mage::getModel('checkout/cart')->getQuote();
27
+ $address = $quote->getBillingAddress();
28
+ return $address;
29
+ }
 
 
 
 
 
30
  }
 
 
app/code/community/Owebia/Shipping2/Model/Os2/Data/Cart.php CHANGED
@@ -21,132 +21,132 @@
21
 
22
  class Owebia_Shipping2_Model_Os2_Data_Cart extends Owebia_Shipping2_Model_Os2_Data_Abstract
23
  {
24
- protected $additional_attributes = array('coupon_code', 'weight_unit', 'weight_for_charge', 'free_shipping');
25
- protected $_free_shipping;
26
- protected $_items;
27
- protected $_quote;
28
- protected $_options;
29
 
30
- public function __construct($arguments)
31
- {
32
- parent::__construct();
33
- $request = $arguments['request'];
34
- $this->_options = $arguments['options'];
35
 
36
- $this->_data = array(
37
- // Do not use quote to retrieve values, totals are not available
38
- 'price-tax+discount' => null,//(double)$request->getData('package_value_with_discount'), // Bad value in backoffice orders
39
- 'price-tax-discount' => null,//(double)$request->getData('package_value'),
40
- 'price+tax+discount' => null,
41
- 'price+tax-discount' => null,
42
- 'weight' => $request->getData('package_weight'),
43
- 'qty' => $request->getData('package_qty'),
44
- 'free_shipping' => $request->getData('free_shipping'),
45
- );
46
 
47
- $cart_items = array();
48
- $items = $request->getAllItems();
49
- $quote_total_collected = false;
50
- $bundle_process_children = isset($this->_options['bundle']['process_children']) && $this->_options['bundle']['process_children'];
51
- foreach ($items as $item) {
52
- $product = $item->getProduct();
53
- if ($product instanceof Mage_Catalog_Model_Product) {
54
- $key = null;
55
- if ($item instanceof Mage_Sales_Model_Quote_Address_Item) { // Multishipping
56
- $key = $item->getQuoteItemId();
57
- } else if ($item instanceof Mage_Sales_Model_Quote_Item) { // Onepage checkout
58
- $key = $item->getId();
59
- }
60
- $cart_items[$key] = $item;
61
- }
62
- }
63
 
64
- // Do not use quote to retrieve values, totals are not available
65
- $total_incl_tax_without_discount = 0;
66
- $total_excl_tax_without_discount = 0;
67
- $total_incl_tax_with_discount = 0;
68
- $total_excl_tax_with_discount = 0;
69
- $this->_items = array();
70
- foreach ($cart_items as $item) {
71
- $type = $item->getProduct()->getTypeId();
72
- //echo $item->getProduct()->getTypeId().', '.$item->getQty().'<br/>';
73
- $parent_item_id = $item->getData('parent_item_id');
74
- $parent_item = isset($cart_items[$parent_item_id]) ? $cart_items[$parent_item_id] : null;
75
- $parent_type = isset($parent_item) ? $parent_item->getProduct()->getTypeId() : null;
76
- if ($type!='configurable') {
77
- if ($type=='bundle' && $bundle_process_children) {
78
- $this->_data['qty'] -= $item->getQty();
79
- continue;
80
- }
81
- if ($parent_type=='bundle') {
82
- if (!$bundle_process_children) continue;
83
- else $this->_data['qty'] += $item->getQty();
84
- }
85
- $this->_items[] = Mage::getModel('owebia_shipping2/Os2_Data_CartItem', array('item' => $item, 'parent_item' => $parent_item, 'options' => $this->_options));
86
- }
87
- //foreach ($item->getData() as $index => $value) echo "$index = $value<br/>\n";
88
- $total_excl_tax_without_discount += $item->getData('base_row_total');
89
- $total_excl_tax_with_discount += $item->getData('base_row_total') - $item->getData('base_discount_amount');
90
- $total_incl_tax_with_discount += $item->getData('base_row_total') - $item->getData('base_discount_amount') + $item->getData('tax_amount');
91
- $total_incl_tax_without_discount += $item->getData('base_row_total_incl_tax');
92
- }
93
- $this->_data['price-tax+discount'] = $total_excl_tax_with_discount;
94
- $this->_data['price-tax-discount'] = $total_excl_tax_without_discount;
95
- $this->_data['price+tax+discount'] = $total_incl_tax_with_discount;
96
- $this->_data['price+tax-discount'] = $total_incl_tax_without_discount;
97
 
98
- //echo '<pre>Owebia_Shipping2_Model_Os2_Data_Abstract::__construct<br/>';foreach ($this->_data as $n => $v){echo "\t$n => ".(is_object($v) ? get_class($v) : (is_array($v) ? 'array' : $v))."<br/>";}echo '</pre>';
99
- }
100
 
101
  protected function _getQuote()
102
  {
103
  return Mage::getModel('owebia_shipping2/Os2_Data_Quote');
104
  }
105
 
106
- protected function _load($name)
107
- {
108
- switch ($name) {
109
- case 'weight_for_charge':
110
- $weight_for_charge = $this->weight;
111
- foreach ($this->_items as $item) {
112
- if ($item->free_shipping) $weight_for_charge -= $item->weight;
113
- }
114
- return $weight_for_charge;
115
- case 'coupon_code':
116
- $coupon_code = null;
117
- $quote = $this->_getQuote();
118
- return $quote->coupon_code;
119
- case 'weight_unit':
120
- return Mage::getStoreConfig('owebia_shipping2/general/weight_unit');
121
- }
122
- return parent::_load($name);
123
- }
124
 
125
- public function __set($name, $value)
126
- {
127
- switch ($name) {
128
- case 'items':
129
- return $this->_items = $value;
130
- }
131
- return parent::__set($name, $value);
132
- }
133
 
134
- public function __get($name)
135
- {
136
- switch ($name) {
137
- case 'items':
138
- return $this->_items;
139
- case 'free_shipping':
140
- if (isset($this->_free_shipping)) return $this->_free_shipping;
141
- $free_shipping = parent::__get('free_shipping');
142
- if (!$free_shipping) {
143
- foreach ($this->_items as $item) {
144
- $free_shipping = $item->free_shipping;
145
- if (!$free_shipping) break;
146
- }
147
- }
148
- return $this->_free_shipping = $free_shipping;
149
- }
150
- return parent::__get($name);
151
- }
152
  }
21
 
22
  class Owebia_Shipping2_Model_Os2_Data_Cart extends Owebia_Shipping2_Model_Os2_Data_Abstract
23
  {
24
+ protected $additional_attributes = array('coupon_code', 'weight_unit', 'weight_for_charge', 'free_shipping');
25
+ protected $_free_shipping;
26
+ protected $_items;
27
+ protected $_quote;
28
+ protected $_options;
29
 
30
+ public function __construct($arguments)
31
+ {
32
+ parent::__construct();
33
+ $request = $arguments['request'];
34
+ $this->_options = $arguments['options'];
35
 
36
+ $this->_data = array(
37
+ // Do not use quote to retrieve values, totals are not available
38
+ 'price-tax+discount' => null,//(double)$request->getData('package_value_with_discount'), // Bad value in backoffice orders
39
+ 'price-tax-discount' => null,//(double)$request->getData('package_value'),
40
+ 'price+tax+discount' => null,
41
+ 'price+tax-discount' => null,
42
+ 'weight' => $request->getData('package_weight'),
43
+ 'qty' => $request->getData('package_qty'),
44
+ 'free_shipping' => $request->getData('free_shipping'),
45
+ );
46
 
47
+ $cart_items = array();
48
+ $items = $request->getAllItems();
49
+ $quote_total_collected = false;
50
+ $bundle_process_children = isset($this->_options['bundle']['process_children']) && $this->_options['bundle']['process_children'];
51
+ foreach ($items as $item) {
52
+ $product = $item->getProduct();
53
+ if ($product instanceof Mage_Catalog_Model_Product) {
54
+ $key = null;
55
+ if ($item instanceof Mage_Sales_Model_Quote_Address_Item) { // Multishipping
56
+ $key = $item->getQuoteItemId();
57
+ } else if ($item instanceof Mage_Sales_Model_Quote_Item) { // Onepage checkout
58
+ $key = $item->getId();
59
+ }
60
+ $cart_items[$key] = $item;
61
+ }
62
+ }
63
 
64
+ // Do not use quote to retrieve values, totals are not available
65
+ $total_incl_tax_without_discount = 0;
66
+ $total_excl_tax_without_discount = 0;
67
+ $total_incl_tax_with_discount = 0;
68
+ $total_excl_tax_with_discount = 0;
69
+ $this->_items = array();
70
+ foreach ($cart_items as $item) {
71
+ $type = $item->getProduct()->getTypeId();
72
+ //echo $item->getProduct()->getTypeId().', '.$item->getQty().'<br/>';
73
+ $parent_item_id = $item->getData('parent_item_id');
74
+ $parent_item = isset($cart_items[$parent_item_id]) ? $cart_items[$parent_item_id] : null;
75
+ $parent_type = isset($parent_item) ? $parent_item->getProduct()->getTypeId() : null;
76
+ if ($type!='configurable') {
77
+ if ($type=='bundle' && $bundle_process_children) {
78
+ $this->_data['qty'] -= $item->getQty();
79
+ continue;
80
+ }
81
+ if ($parent_type=='bundle') {
82
+ if (!$bundle_process_children) continue;
83
+ else $this->_data['qty'] += $item->getQty();
84
+ }
85
+ $this->_items[] = Mage::getModel('owebia_shipping2/Os2_Data_CartItem', array('item' => $item, 'parent_item' => $parent_item, 'options' => $this->_options));
86
+ }
87
+ //foreach ($item->getData() as $index => $value) echo "$index = $value<br/>\n";
88
+ $total_excl_tax_without_discount += $item->getData('base_row_total');
89
+ $total_excl_tax_with_discount += $item->getData('base_row_total') - $item->getData('base_discount_amount');
90
+ $total_incl_tax_with_discount += $item->getData('base_row_total') - $item->getData('base_discount_amount') + $item->getData('tax_amount');
91
+ $total_incl_tax_without_discount += $item->getData('base_row_total_incl_tax');
92
+ }
93
+ $this->_data['price-tax+discount'] = $total_excl_tax_with_discount;
94
+ $this->_data['price-tax-discount'] = $total_excl_tax_without_discount;
95
+ $this->_data['price+tax+discount'] = $total_incl_tax_with_discount;
96
+ $this->_data['price+tax-discount'] = $total_incl_tax_without_discount;
97
 
98
+ //echo '<pre>Owebia_Shipping2_Model_Os2_Data_Abstract::__construct<br/>';foreach ($this->_data as $n => $v){echo "\t$n => ".(is_object($v) ? get_class($v) : (is_array($v) ? 'array' : $v))."<br/>";}echo '</pre>';
99
+ }
100
 
101
  protected function _getQuote()
102
  {
103
  return Mage::getModel('owebia_shipping2/Os2_Data_Quote');
104
  }
105
 
106
+ protected function _load($name)
107
+ {
108
+ switch ($name) {
109
+ case 'weight_for_charge':
110
+ $weight_for_charge = $this->weight;
111
+ foreach ($this->_items as $item) {
112
+ if ($item->free_shipping) $weight_for_charge -= $item->weight;
113
+ }
114
+ return $weight_for_charge;
115
+ case 'coupon_code':
116
+ $coupon_code = null;
117
+ $quote = $this->_getQuote();
118
+ return $quote->coupon_code;
119
+ case 'weight_unit':
120
+ return Mage::getStoreConfig('owebia_shipping2/general/weight_unit');
121
+ }
122
+ return parent::_load($name);
123
+ }
124
 
125
+ public function __set($name, $value)
126
+ {
127
+ switch ($name) {
128
+ case 'items':
129
+ return $this->_items = $value;
130
+ }
131
+ return parent::__set($name, $value);
132
+ }
133
 
134
+ public function __get($name)
135
+ {
136
+ switch ($name) {
137
+ case 'items':
138
+ return $this->_items;
139
+ case 'free_shipping':
140
+ if (isset($this->_free_shipping)) return $this->_free_shipping;
141
+ $free_shipping = parent::__get('free_shipping');
142
+ if (!$free_shipping) {
143
+ foreach ($this->_items as $item) {
144
+ $free_shipping = $item->free_shipping;
145
+ if (!$free_shipping) break;
146
+ }
147
+ }
148
+ return $this->_free_shipping = $free_shipping;
149
+ }
150
+ return parent::__get($name);
151
+ }
152
  }
app/code/community/Owebia/Shipping2/Model/Os2/Data/CartItem.php CHANGED
@@ -21,133 +21,138 @@
21
 
22
  class Owebia_Shipping2_Model_Os2_Data_CartItem extends Owebia_Shipping2_Model_Os2_Data_Abstract
23
  {
24
- private $parent_cart_item;
25
- private $cart_product;
26
- private $loaded_product;
27
- private $quantity;
28
- private $categories;
29
-
30
- protected $_product;
31
- protected $_item;
32
- protected $_parent_item;
33
- protected $_type;
34
- protected $_options;
35
- protected $_get_options;
36
 
37
- public function __construct($arguments) {
38
- parent::__construct();
39
- $this->_item = $item = $arguments['item'];
40
- $this->_parent_item = $parent_item = $arguments['parent_item'];
41
- $this->_get_options = $options = $arguments['options'];
42
- $this->_product = null;
43
- $this->_type = $parent_item ? $parent_item->getProduct()->getTypeId() : $item->getProduct()->getTypeId();
44
- $this->_loaded_object = $this->_getItem('load_item_data_on_parent');
 
45
 
46
- if (false) {
47
- echo '---------------------------------<br/>';
48
- foreach ($this->_item->getData() as $index => $value) {
49
- $value = is_object($value) ? get_class($value) : (is_array($value) ? 'array' : $value);
50
- echo "$index = $value<br/>";
51
- }
52
- if ($parent_item) {
53
- echo '----- parent -----<br/>';
54
- foreach ($parent_item->getData() as $index => $value) echo "$index = $value<br/>";
55
- }
56
- echo 'type:'.$this->_type.'<br/>';
57
- echo 'sku:'.$this->sku.'<br/>';
58
- }
59
- }
60
 
61
- public function getProduct() {
62
- if (!isset($this->_product)) {
63
- //echo $this->_loaded_object->getData('product_id').', '.$this->_getItem('load_product_data_on_parent')->getData('product_id').'<br/>';
64
- $product_id = $this->_getItem('load_product_data_on_parent')->getData('product_id');
65
- $this->_product = Mage::getModel('owebia_shipping2/Os2_Data_Product', array('id' => $product_id));
66
- }
67
- return $this->_product;
68
- }
 
69
 
70
- protected function _load($name) {
71
- $elems = explode('.', $name, $limit=2);
72
- $count = count($elems);
73
- $last_index = $count-1;
74
- if ($count==2) {
75
- switch ($elems[0]) {
76
- case 'o':
77
- case 'option':
78
- return $this->_getOption($elems[1]);
79
- }
80
- }
81
- switch ($name) {
82
- case 'price-tax+discount': return (double)$this->base_original_price-$this->discount_amount/$this->qty;
83
- case 'price-tax-discount': return (double)$this->base_original_price;
84
- case 'price+tax+discount':
85
- /*echo 'base_original_price '.$this->base_original_price.'';
86
- echo ' + (tax_amount '.$this->tax_amount.'';
87
- echo ' - discount_amount '.$this->discount_amount.')';
88
- echo '/ '.$this->qty.'<br>';
89
- echo ' ::: = '.($this->base_original_price+($this->tax_amount-$this->discount_amount)/$this->qty).'<br>';*/
90
- return (double)$this->base_original_price+($this->tax_amount-$this->discount_amount)/$this->qty;
91
- case 'price+tax-discount': return (double)$this->price_incl_tax;
92
- case 'weight':
93
- if ($this->_type=='bundle' && $this->getProduct()->weight_type==0) {
94
- return (double)parent::_load($name);
95
- }
96
- return $this->qty*$this->getProduct()->weight;
97
- default:
98
- return parent::_load($name);
99
- }
100
- }
 
101
 
102
- public function __toString() {
103
- return $this->name.' (id:'.$this->product_id.', sku:'.$this->sku.')';
104
- }
 
105
 
106
- protected function _getOption($option_name, $get_by_id=false) {
107
- $options = $this->_getOptions();
108
- if (isset($options[$option_name])) return $get_by_id ? $options[$option_name]['value_id'] : $options[$option_name]['value'];
109
- else return null;
110
- }
 
111
 
112
- protected function _getItem($what) {
113
- $get_parent = isset($this->_get_options[$this->_type][$what]) && $this->_get_options[$this->_type][$what]==true;
114
- /*echo 'getItem('.$what.')['.$this->_type.'] = '.($get_parent ? 'parent' : 'self').'<br/>';
115
- print_r($this->_get_options[$this->_type]);*/
116
- return $get_parent ? $this->_parent_item : $this->_item;
117
- }
 
118
 
119
- protected function _getOptions() {
120
- if (isset($this->_options)) return $this->_options;
121
- $item = $this->_getItem('load_item_option_on_parent');
122
- $options = array();
123
- if ($optionIds = $item->getOptionByCode('option_ids')) {
124
- foreach (explode(',', $optionIds->getValue()) as $optionId) {
125
- if ($option = $item->getProduct()->getOptionById($optionId)) {
126
- $quoteItemOption = $item->getOptionByCode('option_' . $option->getId());
 
127
 
128
- $group = $option->groupFactory($option->getType())
129
- ->setOption($option)
130
- ->setQuoteItemOption($quoteItemOption);
131
 
132
- $label = $option->getTitle();
133
- $options[$label] = array(
134
- 'label' => $label,
135
- 'value' => $group->getFormattedOptionValue($quoteItemOption->getValue()),
136
- 'print_value' => $group->getPrintableOptionValue($quoteItemOption->getValue()),
137
- 'value_id' => $quoteItemOption->getValue(),
138
- 'option_id' => $option->getId(),
139
- 'option_type' => $option->getType(),
140
- 'custom_view' => $group->isCustomizedView()
141
- );
142
- }
143
- }
144
- }
145
- if ($addOptions = $item->getOptionByCode('additional_options')) {
146
- $options = array_merge($options, unserialize($addOptions->getValue()));
147
- }
148
- $this->_options = $options;
149
- return $this->_options;
150
- }
151
  }
152
-
153
- ?>
21
 
22
  class Owebia_Shipping2_Model_Os2_Data_CartItem extends Owebia_Shipping2_Model_Os2_Data_Abstract
23
  {
24
+ private $parent_cart_item;
25
+ private $cart_product;
26
+ private $loaded_product;
27
+ private $quantity;
28
+ private $categories;
29
+
30
+ protected $_product;
31
+ protected $_item;
32
+ protected $_parent_item;
33
+ protected $_type;
34
+ protected $_options;
35
+ protected $_get_options;
36
 
37
+ public function __construct($arguments)
38
+ {
39
+ parent::__construct();
40
+ $this->_item = $item = $arguments['item'];
41
+ $this->_parent_item = $parent_item = $arguments['parent_item'];
42
+ $this->_get_options = $options = $arguments['options'];
43
+ $this->_product = null;
44
+ $this->_type = $parent_item ? $parent_item->getProduct()->getTypeId() : $item->getProduct()->getTypeId();
45
+ $this->_loaded_object = $this->_getItem('load_item_data_on_parent');
46
 
47
+ if (false) {
48
+ echo '---------------------------------<br/>';
49
+ foreach ($this->_item->getData() as $index => $value) {
50
+ $value = is_object($value) ? get_class($value) : (is_array($value) ? 'array' : $value);
51
+ echo "$index = $value<br/>";
52
+ }
53
+ if ($parent_item) {
54
+ echo '----- parent -----<br/>';
55
+ foreach ($parent_item->getData() as $index => $value) echo "$index = $value<br/>";
56
+ }
57
+ echo 'type:'.$this->_type.'<br/>';
58
+ echo 'sku:'.$this->sku.'<br/>';
59
+ }
60
+ }
61
 
62
+ public function getProduct()
63
+ {
64
+ if (!isset($this->_product)) {
65
+ //echo $this->_loaded_object->getData('product_id').', '.$this->_getItem('load_product_data_on_parent')->getData('product_id').'<br/>';
66
+ $product_id = $this->_getItem('load_product_data_on_parent')->getData('product_id');
67
+ $this->_product = Mage::getModel('owebia_shipping2/Os2_Data_Product', array('id' => $product_id));
68
+ }
69
+ return $this->_product;
70
+ }
71
 
72
+ protected function _load($name)
73
+ {
74
+ $elems = explode('.', $name, $limit=2);
75
+ $count = count($elems);
76
+ $last_index = $count-1;
77
+ if ($count==2) {
78
+ switch ($elems[0]) {
79
+ case 'o':
80
+ case 'option':
81
+ return $this->_getOption($elems[1]);
82
+ }
83
+ }
84
+ switch ($name) {
85
+ case 'price-tax+discount': return (double)$this->base_original_price-$this->discount_amount/$this->qty;
86
+ case 'price-tax-discount': return (double)$this->base_original_price;
87
+ case 'price+tax+discount':
88
+ /*echo 'base_original_price '.$this->base_original_price.'';
89
+ echo ' + (tax_amount '.$this->tax_amount.'';
90
+ echo ' - discount_amount '.$this->discount_amount.')';
91
+ echo '/ '.$this->qty.'<br>';
92
+ echo ' ::: = '.($this->base_original_price+($this->tax_amount-$this->discount_amount)/$this->qty).'<br>';*/
93
+ return (double)$this->base_original_price+($this->tax_amount-$this->discount_amount)/$this->qty;
94
+ case 'price+tax-discount': return (double)$this->price_incl_tax;
95
+ case 'weight':
96
+ if ($this->_type=='bundle' && $this->getProduct()->weight_type==0) {
97
+ return (double)parent::_load($name);
98
+ }
99
+ return $this->qty*$this->getProduct()->weight;
100
+ default:
101
+ return parent::_load($name);
102
+ }
103
+ }
104
 
105
+ public function __toString()
106
+ {
107
+ return $this->name.' (id:'.$this->product_id.', sku:'.$this->sku.')';
108
+ }
109
 
110
+ protected function _getOption($option_name, $get_by_id = false)
111
+ {
112
+ $options = $this->_getOptions();
113
+ if (isset($options[$option_name])) return $get_by_id ? $options[$option_name]['value_id'] : $options[$option_name]['value'];
114
+ else return null;
115
+ }
116
 
117
+ protected function _getItem($what)
118
+ {
119
+ $get_parent = isset($this->_get_options[$this->_type][$what]) && $this->_get_options[$this->_type][$what]==true;
120
+ /*echo 'getItem('.$what.')['.$this->_type.'] = '.($get_parent ? 'parent' : 'self').'<br/>';
121
+ print_r($this->_get_options[$this->_type]);*/
122
+ return $get_parent ? $this->_parent_item : $this->_item;
123
+ }
124
 
125
+ protected function _getOptions()
126
+ {
127
+ if (isset($this->_options)) return $this->_options;
128
+ $item = $this->_getItem('load_item_option_on_parent');
129
+ $options = array();
130
+ if ($optionIds = $item->getOptionByCode('option_ids')) {
131
+ foreach (explode(',', $optionIds->getValue()) as $optionId) {
132
+ if ($option = $item->getProduct()->getOptionById($optionId)) {
133
+ $quoteItemOption = $item->getOptionByCode('option_' . $option->getId());
134
 
135
+ $group = $option->groupFactory($option->getType())
136
+ ->setOption($option)
137
+ ->setQuoteItemOption($quoteItemOption);
138
 
139
+ $label = $option->getTitle();
140
+ $options[$label] = array(
141
+ 'label' => $label,
142
+ 'value' => $group->getFormattedOptionValue($quoteItemOption->getValue()),
143
+ 'print_value' => $group->getPrintableOptionValue($quoteItemOption->getValue()),
144
+ 'value_id' => $quoteItemOption->getValue(),
145
+ 'option_id' => $option->getId(),
146
+ 'option_type' => $option->getType(),
147
+ 'custom_view' => $group->isCustomizedView()
148
+ );
149
+ }
150
+ }
151
+ }
152
+ if ($addOptions = $item->getOptionByCode('additional_options')) {
153
+ $options = array_merge($options, unserialize($addOptions->getValue()));
154
+ }
155
+ $this->_options = $options;
156
+ return $this->_options;
157
+ }
158
  }
 
 
app/code/community/Owebia/Shipping2/Model/Os2/Data/Category.php CHANGED
@@ -21,13 +21,13 @@
21
 
22
  class Owebia_Shipping2_Model_Os2_Data_Category extends Owebia_Shipping2_Model_Os2_Data_Abstract
23
  {
24
- protected function _loadObject() {
25
- return Mage::getModel('catalog/category')->load($this->id);
26
- }
 
27
 
28
- public function __toString() {
29
- return $this->name.' (id:'.$this->id.', url_key:'.$this->url_key.')';
30
- }
 
31
  }
32
-
33
- ?>
21
 
22
  class Owebia_Shipping2_Model_Os2_Data_Category extends Owebia_Shipping2_Model_Os2_Data_Abstract
23
  {
24
+ protected function _loadObject()
25
+ {
26
+ return Mage::getModel('catalog/category')->load($this->id);
27
+ }
28
 
29
+ public function __toString()
30
+ {
31
+ return $this->name.' (id:'.$this->id.', url_key:'.$this->url_key.')';
32
+ }
33
  }
 
 
app/code/community/Owebia/Shipping2/Model/Os2/Data/Customer.php CHANGED
@@ -21,22 +21,22 @@
21
 
22
  class Owebia_Shipping2_Model_Os2_Data_Customer extends Owebia_Shipping2_Model_Os2_Data_AbstractWithAttributes
23
  {
24
- protected $additional_attributes = array('*');
25
 
26
- public function __construct($arguments=null)
27
- {
28
- parent::__construct(array(
29
- 'id' => Mage::getModel('owebia_shipping2/Os2_Data_Quote')->customer_id,
30
- ));
31
- }
32
 
33
- protected function _loadObject()
34
- {
35
- return Mage::getModel('customer/customer')->load($this->id);
36
- }
37
 
38
- public function __toString()
39
- {
40
- return $this->firstname.' '.$this->lastname.' (id:'.$this->id.')';
41
- }
42
  }
21
 
22
  class Owebia_Shipping2_Model_Os2_Data_Customer extends Owebia_Shipping2_Model_Os2_Data_AbstractWithAttributes
23
  {
24
+ protected $additional_attributes = array('*');
25
 
26
+ public function __construct($arguments=null)
27
+ {
28
+ parent::__construct(array(
29
+ 'id' => Mage::getModel('owebia_shipping2/Os2_Data_Quote')->customer_id,
30
+ ));
31
+ }
32
 
33
+ protected function _loadObject()
34
+ {
35
+ return Mage::getModel('customer/customer')->load($this->id);
36
+ }
37
 
38
+ public function __toString()
39
+ {
40
+ return $this->firstname.' '.$this->lastname.' (id:'.$this->id.')';
41
+ }
42
  }
app/code/community/Owebia/Shipping2/Model/Os2/Data/CustomerGroup.php CHANGED
@@ -21,61 +21,61 @@
21
 
22
  class Owebia_Shipping2_Model_Os2_Data_CustomerGroup extends Owebia_Shipping2_Model_Os2_Data_Abstract
23
  {
24
- protected static $_customer_groups = null;
25
 
26
- public static function getCollection()
27
- {
28
- if (!self::$_customer_groups) {
29
- $collection = Mage::getModel('customer/group')->getCollection();
30
- $customer_groups = array();
31
- foreach ($collection as $customer_group) {
32
- $customer_groups[$customer_group->getId()] = $customer_group->getCustomerGroupCode();
33
- }
34
- self::$_customer_groups = $customer_groups;
35
- }
36
- return self::$_customer_groups;
37
- }
38
 
39
- public static function readable($input)
40
- {
41
- $customer_groups = self::getCollection();
42
- $elems = preg_split('/\b/', $input);
43
- $output = '';
44
- foreach ($elems as $elem) {
45
- $output .= isset($customer_groups[$elem]) ? $customer_groups[$elem] : $elem;
46
- }
47
- return $output;
48
- }
49
 
50
- protected $additional_attributes = array('*');
51
 
52
- public function __construct($arguments=null)
53
- {
54
- $customer_group_id = Mage::getSingleton('customer/session')->getCustomerGroupId();
55
- if ($customer_group_id==0) { // Pour les commandes depuis Adminhtml
56
- $customer_group_id2 = Mage::getSingleton('adminhtml/session_quote')->getQuote()->getCustomerGroupId();
57
- if (isset($customer_group_id2)) $customer_group_id = $customer_group_id2;
58
- }
59
- parent::__construct(array(
60
- 'id' => $customer_group_id,
61
- ));
62
- }
63
 
64
- protected function _load($name)
65
- {
66
- switch ($name) {
67
- case 'code': return $this->customer_group_code;
68
- default: return parent::_load($name);
69
- }
70
- }
71
 
72
- protected function _loadObject()
73
- {
74
- return Mage::getSingleton('customer/group')->load($this->id);
75
- }
76
 
77
- public function __toString()
78
- {
79
- return $this->code.' (id:'.$this->id.')';
80
- }
81
  }
21
 
22
  class Owebia_Shipping2_Model_Os2_Data_CustomerGroup extends Owebia_Shipping2_Model_Os2_Data_Abstract
23
  {
24
+ protected static $_customer_groups = null;
25
 
26
+ public static function getCollection()
27
+ {
28
+ if (!self::$_customer_groups) {
29
+ $collection = Mage::getModel('customer/group')->getCollection();
30
+ $customer_groups = array();
31
+ foreach ($collection as $customer_group) {
32
+ $customer_groups[$customer_group->getId()] = $customer_group->getCustomerGroupCode();
33
+ }
34
+ self::$_customer_groups = $customer_groups;
35
+ }
36
+ return self::$_customer_groups;
37
+ }
38
 
39
+ public static function readable($input)
40
+ {
41
+ $customer_groups = self::getCollection();
42
+ $elems = preg_split('/\b/', $input);
43
+ $output = '';
44
+ foreach ($elems as $elem) {
45
+ $output .= isset($customer_groups[$elem]) ? $customer_groups[$elem] : $elem;
46
+ }
47
+ return $output;
48
+ }
49
 
50
+ protected $additional_attributes = array('*');
51
 
52
+ public function __construct($arguments=null)
53
+ {
54
+ $customer_group_id = Mage::getSingleton('customer/session')->getCustomerGroupId();
55
+ if ($customer_group_id==0) { // Pour les commandes depuis Adminhtml
56
+ $customer_group_id2 = Mage::getSingleton('adminhtml/session_quote')->getQuote()->getCustomerGroupId();
57
+ if (isset($customer_group_id2)) $customer_group_id = $customer_group_id2;
58
+ }
59
+ parent::__construct(array(
60
+ 'id' => $customer_group_id,
61
+ ));
62
+ }
63
 
64
+ protected function _load($name)
65
+ {
66
+ switch ($name) {
67
+ case 'code': return $this->customer_group_code;
68
+ default: return parent::_load($name);
69
+ }
70
+ }
71
 
72
+ protected function _loadObject()
73
+ {
74
+ return Mage::getSingleton('customer/group')->load($this->id);
75
+ }
76
 
77
+ public function __toString()
78
+ {
79
+ return $this->code.' (id:'.$this->id.')';
80
+ }
81
  }
app/code/community/Owebia/Shipping2/Model/Os2/Data/Customvar.php CHANGED
@@ -21,15 +21,15 @@
21
 
22
  class Owebia_Shipping2_Model_Os2_Data_Customvar extends Owebia_Shipping2_Model_Os2_Data_Abstract
23
  {
24
- public function __sleep() {
25
- return array('*');
26
- }
 
27
 
28
- protected function _load($name) {
29
- return Mage::getModel('core/variable')
30
- ->setStoreId(Mage::app()->getStore()->getId()) // to get store value
31
- ->loadByCode($name)->getValue('text');
32
- }
 
33
  }
34
-
35
- ?>
21
 
22
  class Owebia_Shipping2_Model_Os2_Data_Customvar extends Owebia_Shipping2_Model_Os2_Data_Abstract
23
  {
24
+ public function __sleep()
25
+ {
26
+ return array('*');
27
+ }
28
 
29
+ protected function _load($name)
30
+ {
31
+ return Mage::getModel('core/variable')
32
+ ->setStoreId(Mage::app()->getStore()->getId()) // to get store value
33
+ ->loadByCode($name)->getValue('text');
34
+ }
35
  }
 
 
app/code/community/Owebia/Shipping2/Model/Os2/Data/Date.php CHANGED
@@ -21,30 +21,31 @@
21
 
22
  class Owebia_Shipping2_Model_Os2_Data_Date extends Owebia_Shipping2_Model_Os2_Data_Abstract
23
  {
24
- private $_timestamp;
25
 
26
- public function __construct() {
27
- parent::__construct();
28
- $this->_timestamp = (int)Mage::getModel('core/date')->timestamp();
29
- }
 
30
 
31
- public function __sleep() {
32
- return array('timestamp', 'year', 'month', 'day', 'hour', 'minute', 'second', 'weekday');
33
- }
 
34
 
35
- protected function _load($name) {
36
- switch ($name) {
37
- case 'timestamp': return $this->_timestamp;
38
- case 'year': return (int)date('Y', $this->_timestamp);
39
- case 'month': return (int)date('m', $this->_timestamp);
40
- case 'day': return (int)date('d', $this->_timestamp);
41
- case 'hour': return (int)date('H', $this->_timestamp);
42
- case 'minute': return (int)date('i', $this->_timestamp);
43
- case 'second': return (int)date('s', $this->_timestamp);
44
- case 'weekday': return (int)date('w', $this->_timestamp);
45
- }
46
- return null;
47
- }
 
48
  }
49
-
50
- ?>
21
 
22
  class Owebia_Shipping2_Model_Os2_Data_Date extends Owebia_Shipping2_Model_Os2_Data_Abstract
23
  {
24
+ private $_timestamp;
25
 
26
+ public function __construct()
27
+ {
28
+ parent::__construct();
29
+ $this->_timestamp = (int)Mage::getModel('core/date')->timestamp();
30
+ }
31
 
32
+ public function __sleep()
33
+ {
34
+ return array('timestamp', 'year', 'month', 'day', 'hour', 'minute', 'second', 'weekday');
35
+ }
36
 
37
+ protected function _load($name)
38
+ {
39
+ switch ($name) {
40
+ case 'timestamp': return $this->_timestamp;
41
+ case 'year': return (int)date('Y', $this->_timestamp);
42
+ case 'month': return (int)date('m', $this->_timestamp);
43
+ case 'day': return (int)date('d', $this->_timestamp);
44
+ case 'hour': return (int)date('H', $this->_timestamp);
45
+ case 'minute': return (int)date('i', $this->_timestamp);
46
+ case 'second': return (int)date('s', $this->_timestamp);
47
+ case 'weekday': return (int)date('w', $this->_timestamp);
48
+ }
49
+ return null;
50
+ }
51
  }
 
 
app/code/community/Owebia/Shipping2/Model/Os2/Data/Info.php CHANGED
@@ -22,5 +22,3 @@
22
  class Owebia_Shipping2_Model_Os2_Data_Info extends Owebia_Shipping2_Model_Os2_Data_Abstract
23
  {
24
  }
25
-
26
- ?>
22
  class Owebia_Shipping2_Model_Os2_Data_Info extends Owebia_Shipping2_Model_Os2_Data_Abstract
23
  {
24
  }
 
 
app/code/community/Owebia/Shipping2/Model/Os2/Data/Product.php CHANGED
@@ -21,99 +21,106 @@
21
 
22
  class Owebia_Shipping2_Model_Os2_Data_Product extends Owebia_Shipping2_Model_Os2_Data_AbstractWithAttributes
23
  {
24
- protected $_categories;
25
- protected $_attribute_set;
26
- protected $_stock_item;
27
-
28
- protected function _loadObject() {
29
- return Mage::getModel('catalog/product')->load($this->id);
30
- }
 
31
 
32
- protected function _load($name) {
33
- $elems = explode('.', $name, $limit=2);
34
- $count = count($elems);
35
- $last_index = $count-1;
36
- if ($count==2) {
37
- switch ($elems[0]) {
38
- case 'attribute_set':
39
- return $this->getAttributeSet()->{$elems[1]};
40
- case 'stock':
41
- return $this->_getStockItem()->{$elems[1]};
42
- case 'category':
43
- $category = $this->_getCategory();
44
- return $category ? $category->{$elems[1]} : null;
45
- }
46
- }
47
- switch ($name) {
48
- case 'attribute_set': return $this->getAttributeSet()->name; // Compatibility
49
- case 'category': // Compatibility
50
- $category = $this->_getCategory();
51
- return $category ? $category->name : null;
52
- case 'categories': // Compatibility
53
- $categories = $this->getCategories();
54
- $output = array();
55
- foreach ($categories as $category) {
56
- $output[] = $category->name;
57
- }
58
- return $output;
59
- case 'categories.id': // Compatibility
60
- $categories = $this->getCategories();
61
- $output = array();
62
- foreach ($categories as $category) {
63
- $output[] = $category->id;
64
- }
65
- return $output;
66
- default: return parent::_load($name);
67
- }
68
- }
 
69
 
70
- public function getAttributeSet() {
71
- if (isset($this->_attribute_set)) return $this->_attribute_set;
72
- return $this->_attribute_set = Mage::getModel('owebia_shipping2/Os2_Data_AttributeSet', array('id' => (int)$this->attribute_set_id));
73
- }
 
74
 
75
- protected function _getStockItem() {
76
- //foreach ($this->_loaded_object->getData() as $index => $value) echo "$index = $value<br/>";
77
- if (isset($this->_stock_item)) return $this->_stock_item;
78
- return $this->_stock_item = Mage::getModel('owebia_shipping2/Os2_Data_StockItem', array('product_id' => (int)$this->id));
79
- }
 
80
 
81
- protected function _getCategory() {
82
- $categories = $this->getCategories();
83
- return $categories ? $categories[0] : null;
84
- }
 
85
 
86
- public function getCategories() {
87
- if (isset($this->_categories)) return $this->_categories;
88
- $product = $this->_loadObject();
89
- $ids = $product->getCategoryIds();
90
- $this->_categories = array();
91
- foreach ($ids as $id) {
92
- $this->_categories[] = Mage::getModel('owebia_shipping2/Os2_Data_Category', array('id' => (int)$id));
93
- }
94
- return $this->_categories;
95
- }
 
96
 
97
- protected function _getAttribute($attribute_name) {
98
- switch ($attribute_name) {
99
- case 'weight': return (double)parent::_getAttribute($attribute_name);
100
- default: return parent::_getAttribute($attribute_name);
101
- }
102
- }
 
103
 
104
- /*public function _getAttribute($attribute_name) {
105
- return parent::_getAttribute($attribute_name);
 
106
 
107
- // Dynamic weight for bundle product
108
- if ($this->type=='bundle' && $attribute_name=='weight' && $product->getData('weight_type')==0) {
109
- // !!! Use cart_product and not product
110
- return $this->cart_product->getTypeInstance(true)->getWeight($this->cart_product);
111
- }
112
- }*/
113
 
114
- public function __toString() {
115
- return $this->name.' (id:'.$this->id.', sku:'.$this->sku.')';
116
- }
 
117
  }
118
-
119
- ?>
21
 
22
  class Owebia_Shipping2_Model_Os2_Data_Product extends Owebia_Shipping2_Model_Os2_Data_AbstractWithAttributes
23
  {
24
+ protected $_categories;
25
+ protected $_attribute_set;
26
+ protected $_stock_item;
27
+
28
+ protected function _loadObject()
29
+ {
30
+ return Mage::getModel('catalog/product')->load($this->id);
31
+ }
32
 
33
+ protected function _load($name)
34
+ {
35
+ $elems = explode('.', $name, $limit=2);
36
+ $count = count($elems);
37
+ $last_index = $count-1;
38
+ if ($count==2) {
39
+ switch ($elems[0]) {
40
+ case 'attribute_set':
41
+ return $this->getAttributeSet()->{$elems[1]};
42
+ case 'stock':
43
+ return $this->_getStockItem()->{$elems[1]};
44
+ case 'category':
45
+ $category = $this->_getCategory();
46
+ return $category ? $category->{$elems[1]} : null;
47
+ }
48
+ }
49
+ switch ($name) {
50
+ case 'attribute_set': return $this->getAttributeSet()->name; // Compatibility
51
+ case 'category': // Compatibility
52
+ $category = $this->_getCategory();
53
+ return $category ? $category->name : null;
54
+ case 'categories': // Compatibility
55
+ $categories = $this->getCategories();
56
+ $output = array();
57
+ foreach ($categories as $category) {
58
+ $output[] = $category->name;
59
+ }
60
+ return $output;
61
+ case 'categories.id': // Compatibility
62
+ $categories = $this->getCategories();
63
+ $output = array();
64
+ foreach ($categories as $category) {
65
+ $output[] = $category->id;
66
+ }
67
+ return $output;
68
+ default: return parent::_load($name);
69
+ }
70
+ }
71
 
72
+ public function getAttributeSet()
73
+ {
74
+ if (isset($this->_attribute_set)) return $this->_attribute_set;
75
+ return $this->_attribute_set = Mage::getModel('owebia_shipping2/Os2_Data_AttributeSet', array('id' => (int)$this->attribute_set_id));
76
+ }
77
 
78
+ protected function _getStockItem()
79
+ {
80
+ //foreach ($this->_loaded_object->getData() as $index => $value) echo "$index = $value<br/>";
81
+ if (isset($this->_stock_item)) return $this->_stock_item;
82
+ return $this->_stock_item = Mage::getModel('owebia_shipping2/Os2_Data_StockItem', array('product_id' => (int)$this->id));
83
+ }
84
 
85
+ protected function _getCategory()
86
+ {
87
+ $categories = $this->getCategories();
88
+ return $categories ? $categories[0] : null;
89
+ }
90
 
91
+ public function getCategories()
92
+ {
93
+ if (isset($this->_categories)) return $this->_categories;
94
+ $product = $this->_loadObject();
95
+ $ids = $product->getCategoryIds();
96
+ $this->_categories = array();
97
+ foreach ($ids as $id) {
98
+ $this->_categories[] = Mage::getModel('owebia_shipping2/Os2_Data_Category', array('id' => (int)$id));
99
+ }
100
+ return $this->_categories;
101
+ }
102
 
103
+ protected function _getAttribute($attribute_name)
104
+ {
105
+ switch ($attribute_name) {
106
+ case 'weight': return (double)parent::_getAttribute($attribute_name);
107
+ default: return parent::_getAttribute($attribute_name);
108
+ }
109
+ }
110
 
111
+ /*public function _getAttribute($attribute_name)
112
+ {
113
+ return parent::_getAttribute($attribute_name);
114
 
115
+ // Dynamic weight for bundle product
116
+ if ($this->type=='bundle' && $attribute_name=='weight' && $product->getData('weight_type')==0) {
117
+ // !!! Use cart_product and not product
118
+ return $this->cart_product->getTypeInstance(true)->getWeight($this->cart_product);
119
+ }
120
+ }*/
121
 
122
+ public function __toString()
123
+ {
124
+ return $this->name.' (id:'.$this->id.', sku:'.$this->sku.')';
125
+ }
126
  }
 
 
app/code/community/Owebia/Shipping2/Model/Os2/Data/Quote.php CHANGED
@@ -21,10 +21,10 @@
21
 
22
  class Owebia_Shipping2_Model_Os2_Data_Quote extends Owebia_Shipping2_Model_Os2_Data_Abstract
23
  {
24
- protected $additional_attributes = array('subtotal', 'subtotal_with_discount', 'grand_total', 'base_subtotal', 'base_subtotal_with_discount', 'base_grand_total', '*');
25
 
26
- protected function _loadObject()
27
- {
28
  // Backend
29
  if (Mage::app()->getStore()->isAdmin()) {
30
  $sessionQuote = Mage::getSingleton('adminhtml/session_quote');
@@ -38,6 +38,6 @@ class Owebia_Shipping2_Model_Os2_Data_Quote extends Owebia_Shipping2_Model_Os2_D
38
  $quote = $session->getQuote();
39
  }
40
 
41
- return $quote;
42
- }
43
- }
21
 
22
  class Owebia_Shipping2_Model_Os2_Data_Quote extends Owebia_Shipping2_Model_Os2_Data_Abstract
23
  {
24
+ protected $additional_attributes = array('subtotal', 'subtotal_with_discount', 'grand_total', 'base_subtotal', 'base_subtotal_with_discount', 'base_grand_total', '*');
25
 
26
+ protected function _loadObject()
27
+ {
28
  // Backend
29
  if (Mage::app()->getStore()->isAdmin()) {
30
  $sessionQuote = Mage::getSingleton('adminhtml/session_quote');
38
  $quote = $session->getQuote();
39
  }
40
 
41
+ return $quote;
42
+ }
43
+ }
app/code/community/Owebia/Shipping2/Model/Os2/Data/Selection.php CHANGED
@@ -21,9 +21,8 @@
21
 
22
  class Owebia_Shipping2_Model_Os2_Data_Selection extends Owebia_Shipping2_Model_Os2_Data_Abstract
23
  {
24
- public function set($name, $value) {
25
- $this->_data[$name] = $value;
26
- }
 
27
  }
28
-
29
- ?>
21
 
22
  class Owebia_Shipping2_Model_Os2_Data_Selection extends Owebia_Shipping2_Model_Os2_Data_Abstract
23
  {
24
+ public function set($name, $value)
25
+ {
26
+ $this->_data[$name] = $value;
27
+ }
28
  }
 
 
app/code/community/Owebia/Shipping2/Model/Os2/Data/StockItem.php CHANGED
@@ -21,19 +21,19 @@
21
 
22
  class Owebia_Shipping2_Model_Os2_Data_StockItem extends Owebia_Shipping2_Model_Os2_Data_Abstract
23
  {
24
- protected function _loadObject() {
25
- return Mage::getModel('cataloginventory/stock_item')->loadByProduct($this->product_id);
26
- }
 
27
 
28
- protected function _load($name) {
29
- switch ($name) {
30
- case 'is_in_stock': return (bool)parent::_load($name);
31
- case 'qty':
32
- $qty = parent::_load($name);
33
- return $this->is_qty_decimal ? (float)$qty : (int)$qty;
34
- default: return parent::_load($name);
35
- }
36
- }
 
37
  }
38
-
39
- ?>
21
 
22
  class Owebia_Shipping2_Model_Os2_Data_StockItem extends Owebia_Shipping2_Model_Os2_Data_Abstract
23
  {
24
+ protected function _loadObject()
25
+ {
26
+ return Mage::getModel('cataloginventory/stock_item')->loadByProduct($this->product_id);
27
+ }
28
 
29
+ protected function _load($name)
30
+ {
31
+ switch ($name) {
32
+ case 'is_in_stock': return (bool)parent::_load($name);
33
+ case 'qty':
34
+ $qty = parent::_load($name);
35
+ return $this->is_qty_decimal ? (float)$qty : (int)$qty;
36
+ default: return parent::_load($name);
37
+ }
38
+ }
39
  }
 
 
app/code/community/Owebia/Shipping2/Model/Os2/Data/Store.php CHANGED
@@ -21,32 +21,32 @@
21
 
22
  class Owebia_Shipping2_Model_Os2_Data_Store extends Owebia_Shipping2_Model_Os2_Data_Abstract
23
  {
24
- private $_store;
25
 
26
- public function __construct($arguments=null)
27
- {
28
- parent::__construct();
29
- if ($arguments && isset($argument['id'])) $this->_store = Mage::app()->getStore((int)$argument['id']);
30
- else $this->_store = Mage::app()->getStore();
31
- }
32
 
33
- public function __sleep()
34
- {
35
- return array('id', 'code', 'name', 'address', 'phone');
36
- }
37
 
38
- protected function _load($name)
39
- {
40
- switch ($name) {
41
- case 'id':
42
- return $this->_store->getId();
43
- case 'code':
44
- return $this->_store->getData($name);
45
- case 'name':
46
- case 'address':
47
- case 'phone':
48
- return $this->_store->getConfig('general/store_information/'.$name);
49
- }
50
- return null;
51
- }
52
  }
21
 
22
  class Owebia_Shipping2_Model_Os2_Data_Store extends Owebia_Shipping2_Model_Os2_Data_Abstract
23
  {
24
+ private $_store;
25
 
26
+ public function __construct($arguments=null)
27
+ {
28
+ parent::__construct();
29
+ if ($arguments && isset($argument['id'])) $this->_store = Mage::app()->getStore((int)$argument['id']);
30
+ else $this->_store = Mage::app()->getStore();
31
+ }
32
 
33
+ public function __sleep()
34
+ {
35
+ return array('id', 'code', 'name', 'address', 'phone');
36
+ }
37
 
38
+ protected function _load($name)
39
+ {
40
+ switch ($name) {
41
+ case 'id':
42
+ return $this->_store->getId();
43
+ case 'code':
44
+ return $this->_store->getData($name);
45
+ case 'name':
46
+ case 'address':
47
+ case 'phone':
48
+ return $this->_store->getConfig('general/store_information/'.$name);
49
+ }
50
+ return null;
51
+ }
52
  }
app/code/community/Owebia/Shipping2/Model/System/Config/Source/LoadOnParent.php CHANGED
@@ -21,17 +21,18 @@
21
 
22
  class Owebia_Shipping2_Model_System_Config_Source_LoadOnParent extends Mage_Adminhtml_Model_System_Config_Source_Category
23
  {
24
- public function toOptionArray($addEmpty = true) {
25
- $options = array(
26
- array(
27
- 'label' => Mage::helper('owebia_shipping2')->__('Self'),
28
- 'value' => '0'
29
- ),
30
- array(
31
- 'label' => Mage::helper('owebia_shipping2')->__('Parent'),
32
- 'value' => '1'
33
- ),
34
- );
35
- return $options;
36
- }
 
37
  }
21
 
22
  class Owebia_Shipping2_Model_System_Config_Source_LoadOnParent extends Mage_Adminhtml_Model_System_Config_Source_Category
23
  {
24
+ public function toOptionArray($addEmpty = true)
25
+ {
26
+ $options = array(
27
+ array(
28
+ 'label' => Mage::helper('owebia_shipping2')->__('Self'),
29
+ 'value' => '0'
30
+ ),
31
+ array(
32
+ 'label' => Mage::helper('owebia_shipping2')->__('Parent'),
33
+ 'value' => '1'
34
+ ),
35
+ );
36
+ return $options;
37
+ }
38
  }
app/code/community/Owebia/Shipping2/Model/System/Config/Source/ProcessChildren.php CHANGED
@@ -21,17 +21,18 @@
21
 
22
  class Owebia_Shipping2_Model_System_Config_Source_ProcessChildren extends Mage_Adminhtml_Model_System_Config_Source_Category
23
  {
24
- public function toOptionArray($addEmpty = true) {
25
- $options = array(
26
- array(
27
- 'label' => Mage::helper('owebia_shipping2')->__('Self'),
28
- 'value' => '0'
29
- ),
30
- array(
31
- 'label' => Mage::helper('owebia_shipping2')->__('Children'),
32
- 'value' => '1'
33
- ),
34
- );
35
- return $options;
36
- }
 
37
  }
21
 
22
  class Owebia_Shipping2_Model_System_Config_Source_ProcessChildren extends Mage_Adminhtml_Model_System_Config_Source_Category
23
  {
24
+ public function toOptionArray($addEmpty = true)
25
+ {
26
+ $options = array(
27
+ array(
28
+ 'label' => Mage::helper('owebia_shipping2')->__('Self'),
29
+ 'value' => '0'
30
+ ),
31
+ array(
32
+ 'label' => Mage::helper('owebia_shipping2')->__('Children'),
33
+ 'value' => '1'
34
+ ),
35
+ );
36
+ return $options;
37
+ }
38
  }
app/code/community/Owebia/Shipping2/changelog CHANGED
@@ -1,3 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
1
  [2.5.19 - 09 novembre 2015]
2
  Note: the extension is not affected by the patch SUPEE-6788 since it uses the new admin url routing syntax for 3 years (version 2.4.8.0)
3
  Fix bug: deactivation of auto-escaping by default since it can cause some bugs (ex: impossible to use {address_filter.EU-27} in shipto)
@@ -99,8 +110,8 @@ Mise
99
  Modification de la syntaxe de la configuration pour la rendre 100% compatible JSON
100
  Refonte compl�te de l'�diteur
101
  Suppression de la compatibilit� avec les propri�t�s d�pr�ci�es suivantes :
102
- 'fees_table', 'fees_formula', 'fixed_fees', 'reference_value', 'prices_range', 'weights_range', 'product_properties',
103
- 'free_shipping__fees_table', 'free_shipping__fees_formula', 'free_shipping__fixed_fees', 'free_shipping__label',
104
  Suppression de la compatibilit� avec la d�sactivation d'une m�thode de livraison � l'aide du caract�re #
105
  Suppression de la compatibilit� avec les mots r�serv�s en majuscule : TABLE, SUM, COUNT, DISTINCT et IN
106
  Ajout des fonctions array_match_any et array_match_all
@@ -125,9 +136,9 @@ Correction du code PHP pour supprimer des erreurs E_STRICT
125
  Correction d'un bug dans l'utilisation de la fonction {table ... in ...} : lorsque la variable de r�f�rence est ind�finie, le r�sultat �tait invalide (valeur pr�c�dente de la variable $replacement)
126
  Correction d'un probl�me avec les produits packag�s (bundle product) : les produits 'bundle' et les produits 'simple' �taient tous deux r�cup�r�s ce qui faussait les r�sultats
127
  Support des sets d'attributs
128
- product.attribute_set dans les conditions de boucle foreach
129
- {product.attribute_set} et {product.attribute_set.id} comme variables dans les boucles foreach
130
- product.attribute_set, product.attribute_set.id dans les conditions des op�rations sum, count, min et max
131
  Optimisation du chargement de certaines valeurs (cat�gories, attribute set, ...)
132
  Correction d'un probl�me avec les castings successifs (string), (float) qui posent probl�me lorsque la locale utilise la virgule comme s�parateur de d�cimales
133
 
@@ -154,18 +165,18 @@ Initialisation des formules sum et count
154
  Ajout des alias "a" et "attr" pour "attribute", "o" et "opt" pour "option", "p" pour "product", "c" pour "cart", "s" pour "selection"
155
  Correction de la r�cup�ration des variables personnalis�es : getValue('text') au lieu de getValue('plain')
156
  Support des cat�gories
157
- product.categories dans les conditions de boucle foreach
158
- {product.category} et {product.category.id} comme variables dans les boucles foreach
159
- product.category, product.category.id, product.categories, product.categories.id dans les conditions des op�rations sum, count, min et max
160
  Am�lioration du debug
161
 
162
  [2.4.1 - 24 ao�t 2011]
163
  Modification l�g�re du code php pour �viter un plantage avec certaines versions d'eAccelerator (cache php)
164
- $row = null;
165
- $this->addMessage('info',$row,null,'Ignored lines %s','<div class="code">'.trim($config_string).'</div>');
166
- au lieu de ;
167
- $this->addMessage('info',$row=null,null,'Ignored lines %s','<div class="code">'.trim($config_string).'</div>');
168
- (cf http://www.magentocommerce.com/boards/viewthread/233202/)
169
  Ajout des variables de debug "info.server.os" et "info.server.software"
170
  Ajout de la possibilit� de r�cup�rer la valeur minimum ou maximum de la quantit� (ex: "{max product.quantity}")
171
 
1
+ [2.5.22 - July 18, 2016]
2
+ Add composer.json and modman files
3
+
4
+ [2.5.21 - May 9, 2016]
5
+ Fix replacement of special functions, thanks to S�bastien L.
6
+
7
+ [2.5.20 - 25 avril 2016]
8
+ Fix code indentation
9
+ Fix version number
10
+ Add readme file in package
11
+
12
  [2.5.19 - 09 novembre 2015]
13
  Note: the extension is not affected by the patch SUPEE-6788 since it uses the new admin url routing syntax for 3 years (version 2.4.8.0)
14
  Fix bug: deactivation of auto-escaping by default since it can cause some bugs (ex: impossible to use {address_filter.EU-27} in shipto)
110
  Modification de la syntaxe de la configuration pour la rendre 100% compatible JSON
111
  Refonte compl�te de l'�diteur
112
  Suppression de la compatibilit� avec les propri�t�s d�pr�ci�es suivantes :
113
+ 'fees_table', 'fees_formula', 'fixed_fees', 'reference_value', 'prices_range', 'weights_range', 'product_properties',
114
+ 'free_shipping__fees_table', 'free_shipping__fees_formula', 'free_shipping__fixed_fees', 'free_shipping__label',
115
  Suppression de la compatibilit� avec la d�sactivation d'une m�thode de livraison � l'aide du caract�re #
116
  Suppression de la compatibilit� avec les mots r�serv�s en majuscule : TABLE, SUM, COUNT, DISTINCT et IN
117
  Ajout des fonctions array_match_any et array_match_all
136
  Correction d'un bug dans l'utilisation de la fonction {table ... in ...} : lorsque la variable de r�f�rence est ind�finie, le r�sultat �tait invalide (valeur pr�c�dente de la variable $replacement)
137
  Correction d'un probl�me avec les produits packag�s (bundle product) : les produits 'bundle' et les produits 'simple' �taient tous deux r�cup�r�s ce qui faussait les r�sultats
138
  Support des sets d'attributs
139
+ product.attribute_set dans les conditions de boucle foreach
140
+ {product.attribute_set} et {product.attribute_set.id} comme variables dans les boucles foreach
141
+ product.attribute_set, product.attribute_set.id dans les conditions des op�rations sum, count, min et max
142
  Optimisation du chargement de certaines valeurs (cat�gories, attribute set, ...)
143
  Correction d'un probl�me avec les castings successifs (string), (float) qui posent probl�me lorsque la locale utilise la virgule comme s�parateur de d�cimales
144
 
165
  Ajout des alias "a" et "attr" pour "attribute", "o" et "opt" pour "option", "p" pour "product", "c" pour "cart", "s" pour "selection"
166
  Correction de la r�cup�ration des variables personnalis�es : getValue('text') au lieu de getValue('plain')
167
  Support des cat�gories
168
+ product.categories dans les conditions de boucle foreach
169
+ {product.category} et {product.category.id} comme variables dans les boucles foreach
170
+ product.category, product.category.id, product.categories, product.categories.id dans les conditions des op�rations sum, count, min et max
171
  Am�lioration du debug
172
 
173
  [2.4.1 - 24 ao�t 2011]
174
  Modification l�g�re du code php pour �viter un plantage avec certaines versions d'eAccelerator (cache php)
175
+ $row = null;
176
+ $this->addMessage('info',$row,null,'Ignored lines %s','<div class="code">'.trim($config_string).'</div>');
177
+ au lieu de ;
178
+ $this->addMessage('info',$row=null,null,'Ignored lines %s','<div class="code">'.trim($config_string).'</div>');
179
+ (cf http://www.magentocommerce.com/boards/viewthread/233202/)
180
  Ajout des variables de debug "info.server.os" et "info.server.software"
181
  Ajout de la possibilit� de r�cup�rer la valeur minimum ou maximum de la quantit� (ex: "{max product.quantity}")
182
 
app/code/community/Owebia/Shipping2/controllers/Adminhtml/Os2/AjaxController.php CHANGED
@@ -21,178 +21,178 @@
21
 
22
  class Owebia_Shipping2_Adminhtml_Os2_AjaxController extends Owebia_Shipping2_Controller_Abstract
23
  {
24
- protected function _getOs2Helper($config, $autocorrection = true)
25
- {
26
- include_once $this->getModulePath('includes/OS2_AddressFilterParser.php');
27
- include_once $this->getModulePath('includes/OwebiaShippingHelper.php');
28
- $helper = new OwebiaShippingHelper($config, $autocorrection);
29
- return $helper;
30
- }
31
-
32
- protected function _getEditor($data)
33
- {
34
- $helper = $this->_getOs2Helper($data['source'], $autocorrection = true);
35
- $helper->checkConfig();
36
- $config = $helper->getConfig();
37
- $block = $this->getLayout()->createBlock('owebia_shipping2/adminhtml_os2_editor', 'os2_editor', array('config' => $config, 'opened_row_ids' => isset($data['row_ids']) ? $data['row_ids'] : array()));
38
- return /*"<pre>".print_r($config, true)."</pre>".*/$block->getHtml();
39
- }
40
 
41
- protected function _getCorrection($config, $compress = false, $html = false)
42
- {
43
- $helper = $this->_getOs2Helper($config);
44
- return $helper->formatConfig($compress, $keys_to_remove = array('*id'), $html);
45
- }
46
-
47
- protected function _processHelp($help_id, $content)
48
- {
49
- $block = $this->getLayout()->createBlock('owebia_shipping2/adminhtml_os2_help', 'os2_help', array(
50
- 'controller' => $this,
51
- 'help_id' => $help_id,
52
- 'content' => $content,
53
- 'helper' => $this->_getOs2Helper(''),
54
- ));
55
- return $block->getHtml();
56
- }
57
-
58
- public function indexAction()
59
- {
60
- header('Content-Type: text/html; charset=UTF-8');
61
 
62
- switch ($_POST['what']) {
63
- case 'page':
64
- $with_dialog = (bool)$_POST['with_dialog'];
65
- $page = $_POST['page'];
66
- $layout_content = array();
67
- //$page_header_buttons = null;
68
- switch ($page) {
69
- case 'source':
70
- $layout_content['north'] = "<div class=\"os2-page-header ui-layout-center\">"
71
- .$this->button__('Apply', "os2editor.save();", 'save')
72
- .$this->button__('Export', "os2editor.saveToFile();", '')
73
- .$this->button__('Add a shipping method',"os2editor.addRow();",'add')
74
- ."</div>"
75
- ;
76
- $layout_content['west'] = "<div class=ui-layout-north><h4 class=os2-section-title>{$this->__('Editor')}</h4></div><div id=os2-editor class=ui-layout-center></div>";
77
- $layout_content['center'] = "<div class=ui-layout-north><h4 class=os2-section-title>{$this->__('Source')}</h4></div><textarea id=os2-source class=ui-layout-center></textarea>";
78
- $layout_content['east'] = "<div class=ui-layout-north><h4 class=os2-section-title>{$this->__('Correction')}</h4></div><div id=os2-correction class=ui-layout-center></div>";
79
- $layout_content['south'] = "<div class=ui-layout-north><h4 class=os2-section-title>{$this->__('Debug')}</h4></div><div id=os2-debug class=ui-layout-center></div>";
80
- break;
81
- case 'help':
82
- $output = $this->__('{os2editor.help.'.$_POST['input'].'}');
83
- $layout_content['center'] = $this->_processHelp($_POST['input'], $output);
84
- break;
85
- case 'donate':
86
- $layout_content['center'] = "<div class=\"ui-layout-north os2-help-header\"><h4>".$this->__('You appreciate this extension and would like to help?')."</h4></div>"
87
- ."<div id=os2-help class=ui-layout-center>".$this->__('{os2editor.donate-page.content}')."</div>";
88
- break;
89
- }
90
- echo $this->page($page, $layout_content, $with_dialog);
91
- exit;
92
- case 'correction':
93
- $helper = $this->_getOs2Helper($_POST['source']);
94
- $helper->checkConfig();
95
- echo json_encode(array(
96
- 'correction' => $helper->formatConfig($compress = false, $keys_to_remove = array('*id'), $html = true),
97
- 'debug' => $helper->getDebug(),
98
- 'editor' => $this->_getEditor($_POST),
99
- ));
100
- exit;
101
- case 'property-tools':
102
- $block = $this->getLayout()->createBlock('owebia_shipping2/adminhtml_os2_editor');
103
- echo $block->getPropertyTools($this, $_POST['property']);
104
- exit;
105
- case 'update-property':
106
- $helper = $this->_getOs2Helper($_POST['source']);
107
- $config = $helper->getConfig();
108
- $row_id = $_POST['row'];
109
- $property = $_POST['property'];
110
- $value = $_POST['value'];
111
- if ($property==='type' && $value=='method' || $property==='enabled' && $value=='1' || $property!=='enabled' && empty($value)) {
112
- unset($config[$row_id][$property]);
113
- } else if ($property==='enabled') {
114
- $config[$row_id][$property]['value'] = (bool)$value;
115
- } else {
116
- $config[$row_id][$property]['value'] = $value;
117
- }
118
- if ($property=='*id' && $value!=$row_id) {
119
- $config[$value] = $config[$row_id];
120
- unset($config[$row_id]);
121
- }
122
- $helper->setConfig($config);
123
- echo json_encode(array(
124
- 'source' => $helper->formatConfig($compress = false, $keys_to_remove = array('*id'), $html = false),
125
- ));
126
- exit;
127
- case 'add-row':
128
- $helper = $this->_getOs2Helper($_POST['source']);
129
- $row = array('label' => array('value' => $this->__('New shipping method')), 'fees' => array('value' => 0)); // By reference
130
- $helper->addRow('new'.time(), $row);
131
- echo json_encode(array(
132
- 'source' => $helper->formatConfig($compress = false, $keys_to_remove = array('*id'), $html = false),
133
- ));
134
- exit;
135
- case 'remove-row':
136
- $helper = $this->_getOs2Helper($_POST['source']);
137
- $config = $helper->getConfig();
138
- unset($config[$_POST['id']]);
139
- $helper->setConfig($config);
140
- echo json_encode(array(
141
- 'source' => $helper->formatConfig($compress = false, $keys_to_remove = array('*id'), $html = false),
142
- ));
143
- exit;
144
- case 'row-ui':
145
- $helper = $this->_getOs2Helper($_POST['source']);
146
- $row = $helper->getConfigRow($_POST['id']);
147
- $block = $this->getLayout()->createBlock('owebia_shipping2/adminhtml_os2_editor');
148
- echo $block->getRowUI($row, true);
149
- exit;
150
- case 'readable-selection':
151
- switch ($_POST['property']) {
152
- case 'shipto':
153
- case 'billto':
154
- case 'origin':
155
- echo Mage::getModel('owebia_shipping2/Os2_Data_AddressFilter')->readable($_POST['input']);
156
- break;
157
- case 'customer_groups':
158
- echo Mage::getModel('owebia_shipping2/Os2_Data_CustomerGroup')->readable($_POST['input']);
159
- break;
160
- }
161
- exit;
162
- case 'save-config':
163
- $compress = (bool)Mage::getStoreConfig('carriers/'.$_POST['shipping_code'].'/compression');
164
- $config = $compress ? $this->_getCorrection($_POST['source'], $compress) : $_POST['source'];
165
- //Mage::getConfig()->saveConfig('carriers/'.$_POST['shipping_code'].'/config',$output);
166
- echo $config;
167
- exit;
168
- case 'save-to-file':
169
- $config = $_POST['source'];
170
- $this->forceDownload('owebia-shipping-config.txt', $config);
171
- exit;
172
- }
173
 
174
- echo "<script type=\"text/javascript\">".$script."</script>";
175
- exit;
176
- }
177
 
178
- public function docAction()
179
- {
180
- header('Content-Type: text/html; charset=UTF-8');
181
 
182
- $file_handler = fopen(Mage::getBaseDir('locale').'/fr_FR/Owebia_Shipping2.csv', 'r');
183
- $output = "<style>.new{color:blue}strike,.deprecated{color:maroon}</style>";
184
- while ($row = fgetcsv($file_handler,4096,',','"')) {
185
- if (isset($row[0])) {
186
- $key = $row[0];
187
- $data[$key] = isset($row[1]) ? $row[1] : null;
188
- if (substr($key,0,16)=='{os2editor.help.') {
189
- $id = preg_replace('/[^a-z]/','_',substr($key,16,-1));
190
- $content = $this->_processHelp($id, $data[$key]);
191
- $output .= "<div class=\"field\"><a name=\"".$id."\"></a>".$content."</div>";
192
- }
193
- }
194
- }
195
- echo $output;
196
- exit;
197
- }
198
  }
21
 
22
  class Owebia_Shipping2_Adminhtml_Os2_AjaxController extends Owebia_Shipping2_Controller_Abstract
23
  {
24
+ protected function _getOs2Helper($config, $autocorrection = true)
25
+ {
26
+ include_once $this->getModulePath('includes/OS2_AddressFilterParser.php');
27
+ include_once $this->getModulePath('includes/OwebiaShippingHelper.php');
28
+ $helper = new OwebiaShippingHelper($config, $autocorrection);
29
+ return $helper;
30
+ }
31
+
32
+ protected function _getEditor($data)
33
+ {
34
+ $helper = $this->_getOs2Helper($data['source'], $autocorrection = true);
35
+ $helper->checkConfig();
36
+ $config = $helper->getConfig();
37
+ $block = $this->getLayout()->createBlock('owebia_shipping2/adminhtml_os2_editor', 'os2_editor', array('config' => $config, 'opened_row_ids' => isset($data['row_ids']) ? $data['row_ids'] : array()));
38
+ return /*"<pre>".print_r($config, true)."</pre>".*/$block->getHtml();
39
+ }
40
 
41
+ protected function _getCorrection($config, $compress = false, $html = false)
42
+ {
43
+ $helper = $this->_getOs2Helper($config);
44
+ return $helper->formatConfig($compress, $keys_to_remove = array('*id'), $html);
45
+ }
46
+
47
+ protected function _processHelp($help_id, $content)
48
+ {
49
+ $block = $this->getLayout()->createBlock('owebia_shipping2/adminhtml_os2_help', 'os2_help', array(
50
+ 'controller' => $this,
51
+ 'help_id' => $help_id,
52
+ 'content' => $content,
53
+ 'helper' => $this->_getOs2Helper(''),
54
+ ));
55
+ return $block->getHtml();
56
+ }
57
+
58
+ public function indexAction()
59
+ {
60
+ header('Content-Type: text/html; charset=UTF-8');
61
 
62
+ switch ($_POST['what']) {
63
+ case 'page':
64
+ $with_dialog = (bool)$_POST['with_dialog'];
65
+ $page = $_POST['page'];
66
+ $layout_content = array();
67
+ //$page_header_buttons = null;
68
+ switch ($page) {
69
+ case 'source':
70
+ $layout_content['north'] = "<div class=\"os2-page-header ui-layout-center\">"
71
+ .$this->button__('Apply', "os2editor.save();", 'save')
72
+ .$this->button__('Export', "os2editor.saveToFile();", '')
73
+ .$this->button__('Add a shipping method',"os2editor.addRow();",'add')
74
+ ."</div>"
75
+ ;
76
+ $layout_content['west'] = "<div class=ui-layout-north><h4 class=os2-section-title>{$this->__('Editor')}</h4></div><div id=os2-editor class=ui-layout-center></div>";
77
+ $layout_content['center'] = "<div class=ui-layout-north><h4 class=os2-section-title>{$this->__('Source')}</h4></div><textarea id=os2-source class=ui-layout-center></textarea>";
78
+ $layout_content['east'] = "<div class=ui-layout-north><h4 class=os2-section-title>{$this->__('Correction')}</h4></div><div id=os2-correction class=ui-layout-center></div>";
79
+ $layout_content['south'] = "<div class=ui-layout-north><h4 class=os2-section-title>{$this->__('Debug')}</h4></div><div id=os2-debug class=ui-layout-center></div>";
80
+ break;
81
+ case 'help':
82
+ $output = $this->__('{os2editor.help.'.$_POST['input'].'}');
83
+ $layout_content['center'] = $this->_processHelp($_POST['input'], $output);
84
+ break;
85
+ case 'donate':
86
+ $layout_content['center'] = "<div class=\"ui-layout-north os2-help-header\"><h4>".$this->__('You appreciate this extension and would like to help?')."</h4></div>"
87
+ ."<div id=os2-help class=ui-layout-center>".$this->__('{os2editor.donate-page.content}')."</div>";
88
+ break;
89
+ }
90
+ echo $this->page($page, $layout_content, $with_dialog);
91
+ exit;
92
+ case 'correction':
93
+ $helper = $this->_getOs2Helper($_POST['source']);
94
+ $helper->checkConfig();
95
+ echo json_encode(array(
96
+ 'correction' => $helper->formatConfig($compress = false, $keys_to_remove = array('*id'), $html = true),
97
+ 'debug' => $helper->getDebug(),
98
+ 'editor' => $this->_getEditor($_POST),
99
+ ));
100
+ exit;
101
+ case 'property-tools':
102
+ $block = $this->getLayout()->createBlock('owebia_shipping2/adminhtml_os2_editor');
103
+ echo $block->getPropertyTools($this, $_POST['property']);
104
+ exit;
105
+ case 'update-property':
106
+ $helper = $this->_getOs2Helper($_POST['source']);
107
+ $config = $helper->getConfig();
108
+ $row_id = $_POST['row'];
109
+ $property = $_POST['property'];
110
+ $value = $_POST['value'];
111
+ if ($property==='type' && $value=='method' || $property==='enabled' && $value=='1' || $property!=='enabled' && empty($value)) {
112
+ unset($config[$row_id][$property]);
113
+ } else if ($property==='enabled') {
114
+ $config[$row_id][$property]['value'] = (bool)$value;
115
+ } else {
116
+ $config[$row_id][$property]['value'] = $value;
117
+ }
118
+ if ($property=='*id' && $value!=$row_id) {
119
+ $config[$value] = $config[$row_id];
120
+ unset($config[$row_id]);
121
+ }
122
+ $helper->setConfig($config);
123
+ echo json_encode(array(
124
+ 'source' => $helper->formatConfig($compress = false, $keys_to_remove = array('*id'), $html = false),
125
+ ));
126
+ exit;
127
+ case 'add-row':
128
+ $helper = $this->_getOs2Helper($_POST['source']);
129
+ $row = array('label' => array('value' => $this->__('New shipping method')), 'fees' => array('value' => 0)); // By reference
130
+ $helper->addRow('new'.time(), $row);
131
+ echo json_encode(array(
132
+ 'source' => $helper->formatConfig($compress = false, $keys_to_remove = array('*id'), $html = false),
133
+ ));
134
+ exit;
135
+ case 'remove-row':
136
+ $helper = $this->_getOs2Helper($_POST['source']);
137
+ $config = $helper->getConfig();
138
+ unset($config[$_POST['id']]);
139
+ $helper->setConfig($config);
140
+ echo json_encode(array(
141
+ 'source' => $helper->formatConfig($compress = false, $keys_to_remove = array('*id'), $html = false),
142
+ ));
143
+ exit;
144
+ case 'row-ui':
145
+ $helper = $this->_getOs2Helper($_POST['source']);
146
+ $row = $helper->getConfigRow($_POST['id']);
147
+ $block = $this->getLayout()->createBlock('owebia_shipping2/adminhtml_os2_editor');
148
+ echo $block->getRowUI($row, true);
149
+ exit;
150
+ case 'readable-selection':
151
+ switch ($_POST['property']) {
152
+ case 'shipto':
153
+ case 'billto':
154
+ case 'origin':
155
+ echo Mage::getModel('owebia_shipping2/Os2_Data_AddressFilter')->readable($_POST['input']);
156
+ break;
157
+ case 'customer_groups':
158
+ echo Mage::getModel('owebia_shipping2/Os2_Data_CustomerGroup')->readable($_POST['input']);
159
+ break;
160
+ }
161
+ exit;
162
+ case 'save-config':
163
+ $compress = (bool)Mage::getStoreConfig('carriers/'.$_POST['shipping_code'].'/compression');
164
+ $config = $compress ? $this->_getCorrection($_POST['source'], $compress) : $_POST['source'];
165
+ //Mage::getConfig()->saveConfig('carriers/'.$_POST['shipping_code'].'/config',$output);
166
+ echo $config;
167
+ exit;
168
+ case 'save-to-file':
169
+ $config = $_POST['source'];
170
+ $this->forceDownload('owebia-shipping-config.txt', $config);
171
+ exit;
172
+ }
173
 
174
+ echo "<script type=\"text/javascript\">".$script."</script>";
175
+ exit;
176
+ }
177
 
178
+ public function docAction()
179
+ {
180
+ header('Content-Type: text/html; charset=UTF-8');
181
 
182
+ $file_handler = fopen(Mage::getBaseDir('locale').'/fr_FR/Owebia_Shipping2.csv', 'r');
183
+ $output = "<style>.new{color:blue}strike,.deprecated{color:maroon}</style>";
184
+ while ($row = fgetcsv($file_handler,4096,',','"')) {
185
+ if (isset($row[0])) {
186
+ $key = $row[0];
187
+ $data[$key] = isset($row[1]) ? $row[1] : null;
188
+ if (substr($key,0,16)=='{os2editor.help.') {
189
+ $id = preg_replace('/[^a-z]/','_',substr($key,16,-1));
190
+ $content = $this->_processHelp($id, $data[$key]);
191
+ $output .= "<div class=\"field\"><a name=\"".$id."\"></a>".$content."</div>";
192
+ }
193
+ }
194
+ }
195
+ echo $output;
196
+ exit;
197
+ }
198
  }
app/code/community/Owebia/Shipping2/controllers/Checkout/CartController.php CHANGED
@@ -43,11 +43,11 @@ class Owebia_Shipping2_Checkout_CartController extends Mage_Checkout_CartControl
43
  ->setRegionId($regionId)
44
  ->setRegion($region)
45
  ->setCollectShippingRates(true);
46
-
47
- /*<owebia>*/
48
- // Recalcul des totaux
49
- $this->_getQuote()->collectTotals();
50
- /*</owebia>*/
51
 
52
  $this->_getQuote()->save();
53
  $this->_goBack();
43
  ->setRegionId($regionId)
44
  ->setRegion($region)
45
  ->setCollectShippingRates(true);
46
+
47
+ /*<owebia>*/
48
+ // Recalcul des totaux
49
+ $this->_getQuote()->collectTotals();
50
+ /*</owebia>*/
51
 
52
  $this->_getQuote()->save();
53
  $this->_goBack();
app/code/community/Owebia/Shipping2/doc_en_US.html CHANGED
@@ -2,7 +2,7 @@
2
  <html>
3
  <head lang="fr">
4
  <meta charset="utf-8"/>
5
- <title>Documentation of Owebia-Shipping 2.5.13 extension for Magento</title>
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
  <link href="http://netdna.bootstrapcdn.com/bootstrap/3.0.0-rc1/css/bootstrap.min.css" rel="stylesheet">
8
  <style>
@@ -39,811 +39,833 @@ pre.changelog{white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre
39
  .sidebar .nav .nav {display: none; /* Hide by default, but at >768px, show it */margin-bottom: 8px;}
40
  .sidebar .nav .nav > li > a {padding-top:3px;padding-bottom:3px;padding-left:30px;font-size:90%;}
41
  @media screen and (min-width: 768px) {
42
- .sidebar{display:block}
43
- .sidebar .nav > .active > ul {display:block}
44
- .bs-navbar-top-example .navbar-fixed-top,
45
- .bs-navbar-bottom-example .navbar-fixed-bottom {position:absolute}
46
  }
47
  @media screen and (min-width: 992px) {
48
- .sidebar.affix,
49
- .sidebar.affix-bottom {width:213px}
50
- .sidebar.affix {position:fixed;top:80px}
51
- .sidebar.affix-bottom {position:absolute}
52
- .sidebar.affix-bottom .sidenav,
53
- .sidebar.affix .sidenav {margin-top:0;margin-bottom:0}
54
  }
55
  @media screen and (min-width: 1200px) {
56
- .sidebar.affix-bottom,
57
- .sidebar.affix {width:270px}
58
  }
59
  </style>
60
  </head>
61
  <body>
62
  <div class="navbar navbar-inverse navbar-fixed-top">
63
- <div class="container">
64
- <a href="http://www.owebia.com" class="navbar-brand">Owebia</a>
65
- <ul class="nav navbar-nav">
66
- </ul>
67
- </div>
68
  </div>
69
  <div class="container">
70
- <div class="row">
71
- <div class="col-lg-3">
72
- <div class="affix sidebar">
73
- <!-- doc sidebar start -->
74
- <ul class="nav sidenav">
75
- <li><a href="#introduction">Introduction</a></li>
76
- <li><a href="#examples">Examples</a>
77
- <ul class="nav">
78
- <li><a href="#examples_simple">Simple example: free shipping</a></li>
79
- <li><a href="#examples_using_address_filters">Fees related to the destination</a></li>
80
- <li><a href="#examples_using_customer_groups">Fees related to customer group</a></li>
81
- <li><a href="#examples_using_formulas">Using formulas</a></li>
82
- <li><a href="#examples_using_special_functions">Using special functions</a></li>
83
- <li><a href="#examples_using_foreach">Using <code>{foreach …}</code> loops</a></li>
84
- <li><a href="#examples_using_array_functions">Manipulate arrays</a></li>
85
- <li><a href="#examples_more">Other examples</a></li>
86
- </ul>
87
- </li>
88
- <li><a href="#definitions">Definitions</a>
89
- <ul class="nav">
90
- <li><a href="#definitions_element">Elements</a></li>
91
- <li><a href="#definitions_property">Properties</a></li>
92
- <li><a href="#definitions_unique_id">The unique identifier</a></li>
93
- </ul>
94
- </li>
95
- <li><a href="#formulas">Formulas</a>
96
- <ul class="nav">
97
- <li><a href="#formulas_variables">Variables</a></li>
98
- <li><a href="#formulas_functions">Functions</a></li>
99
- <li><a href="#formulas_special_functions">Special functions</a></li>
100
- <li><a href="#formulas_foreach"><code>foreach</code> loops</a></li>
101
- <li><a href="#formulas_deprecated_variables">Deprecated variables</a></li>
102
- </ul>
103
- </li>
104
- <li><a href="#more">Miscellaneous</a>
105
- <ul class="nav">
106
- <li><a href="#more_tracking_url">The tracking URL</a></li>
107
- </ul>
108
- </li>
109
- <li><a href="#changelog">Changelog</a></li>
110
- <li><a href="#index">Index</a></li>
111
- </ul>
112
- <!-- doc sidebar end -->
113
- </div>
114
- </div>
115
- <div class="col-lg-9">
116
- <!-- doc content start -->
117
- <h1>Documentation of Owebia-Shipping 2.5.13 extension for Magento</h1>
118
- <div id="introduction">
119
- <h2>Introduction</h2>
120
-
121
- <p>Owebia Shipping is an extension for the e-commerce solution <a href="http://www.magentocommerce.com/" target="_blank">Magento</a>.</p>
122
- <p>Thanks to its syntax using <a href="http://fr.wikipedia.org/wiki/JavaScript_Object_Notation" target=_blank>JSON</a>, this extension allows great flexibility in setting delivery charges.</p>
123
-
124
- <p>This documentation explains how to create a configuration for one of the proposed shipping modes.</p>
125
-
126
- <p class="alert alert-info">New documentation, simpler and clearer.<br/>
127
- <strong>Use the <a href="#index">index</a></strong> to find more easily something in the documentation.</p>
128
- </div>
129
-
130
- <div id="examples">
131
- <h2>Examples</h2>
132
-
133
- <div id="examples_simple">
134
- <h3>Simple example: free shipping</h3>
135
- <div class="json">{
136
- "__auto__":{"label":"Free shipping","fees": 0}
137
- }</div>
138
- </div>
139
-
140
- <div id="examples_using_address_filters">
141
- <h3>Fees related to the destination</h3>
142
- <div class="json">{
143
- "__auto__":{"label":"France, Germany, Switzerland, Spain, Italy","shipto":"FR,DE,CH,ES,IT","fees":10},
144
- "__auto__":{"label":"France except Corsica","shipto":"FR-(2A,2B)","fees":10},
145
- "__auto__":{"label":"Corsica","shipto":"FR(2A,2B)","fees":10},
146
- "__auto__":{"label":"Worldwide except Germany and Corsica","shipto":"* - ( DE, FR(2A,2B) )","fees":10}
147
- }</div>
148
-
149
- <h4>Use the wildcard character <code>*</code> or regular expressions</h4>
150
- <div class="json">{
151
- "__auto__":{"label":"Wildcard character allowing postal codes beginning with 25","shipto":"FR(25*)","fees":10},
152
- "__auto__":{"label":"Regular expressions allowing postal codes beginning with 'PO', 'po', 'Po' or 'pO'","shipto":"GB(/^PO.*$/i)","fees":10}
153
- }</div>
154
-
155
- <div id="examples_excluding_domtom_postcode">
156
- <h4>Block delivery to France but with a postal code for DOM/TOM</h4>
157
- <p>With the following regular expression, you block the postal codes that starts with 97 or 98 (with or without interspersed zeros and spaces).</p>
158
- <div class="json">{
159
- "__auto__":{"label":"Regular Expression refusing postal codes beginning with 97 and 98","shipto":"FR-(/^[0\\s]*9\\s*[78].*/)","fees":10}
160
- }</div>
161
- </div>
162
-
163
- <div id="examples_using_address_filters_shortcuts">
164
- <h4>Using shortcuts <code>address_filter</code></h4>
165
- <div class="json">{
166
- "__auto__":{"label":"Europe except France","shipto":"({address_filter.EU-27}) - (FR)","fees":10}
167
- }</div>
168
- </div>
169
- </div>
170
-
171
- <div id="examples_using_customer_groups">
172
- <h3>Fees related to customer group</h3>
173
- <p>You can use the name or ID of the customer groups.</p>
174
- <div class="json">{
175
- "__auto__":{"label":"NOT LOGGED IN and General groups","customer_groups":"NOT LOGGED IN,General","fees":10},
176
- "__auto__":{"label":"NOT LOGGED IN and General groups by their ID","customer_groups":"0,1","fees":10},
177
- "__auto__":{"label":"Retailer group","customer_groups":"Retailer","fees":10}
178
- }</div>
179
- </div>
180
-
181
- <div id="examples_using_formulas">
182
- <h3>Using formulas</h3>
183
- <p>Formulas can be used in properties <code>conditions</code> and <code>fees</code>.</p>
184
- <div class="json">{
185
- "__auto__":{"label":"Shipping","fees":"0.1 * {cart.price-tax+discount} + 10.00"}
186
- }</div>
187
-
188
- <h4>Copying the property of another element</h4>
189
- <div class="json">{
190
- "standard":{"label":"Standard Shipping","conditions":"{cart.price-tax+discount} < 1000.00","fees":10},
191
- "express":{"label":"Express Shipping","conditions":"( {standard.conditions} ) && ( {cart.weight} < 10 )","fees":12}
192
- }</div>
193
-
194
- <h4>Using the function <code>min()</code></h4>
195
- <div class="json">{
196
- "__auto__":{"label":"Shipping","fees":"min({cart.weight}, {cart.price+tax+discount}, {cart.qty})"}
197
- }</div>
198
-
199
- <h4>Using the function <code>range()</code></h4>
200
- <div class="json">{
201
- "__auto__":{"label":"Shipping","conditions":"range({cart.weight}, 1.0, 3.0)","fees":10}
202
- }</div>
203
-
204
- <h4>Using the function <code>substr()</code></h4>
205
- <p>A variable of type string must be surrounded by single quotes unless the auto-quoting is used with the characters <code>{{</code> and <code>}}</code>.</p>
206
- <div class="json">{
207
- "__auto__":{"label":"Without auto-quoting","conditions":"substr('{cart.coupon_code}', 0, 5)=='free_'","fees":10},
208
- "__auto__":{"label":"With auto-quoting","conditions":"substr({{cart.coupon_code}}, 0, 5)=='free_'","fees":10}
209
- }</div>
210
-
211
- </div>
212
-
213
- <div id="examples_using_special_functions">
214
- <h3>Using special functions</h3>
215
-
216
- <div id="examples_special_table">
217
- <h4>Using the special function <code>{table … in …}</code></h4>
218
- <div class="json">{
219
- "__auto__":{"label":"Shipping","fees":"{table {cart.weight} in 0.5:5.30, 1.0:6.50, 2.0:7.40, 3.0:8.30, 5.0:10.10}"}
220
- }</div>
221
- <p>
222
- In a <code>table</code>, you can include or exclude a limit value with the characters <code>[</code> and <code>]</code>:
223
- </p>
224
- <div class="json">{
225
- "__auto__":{"label":"Upper limit included","fees":"{table {cart.weight} in 1.0]:5.00}"},
226
- "__auto__":{"label":"Upper limit excluded","fees":"{table {cart.weight} in 1.0[:5.00}"}
227
- }</div>
228
-
229
- <p>
230
- In a <code>table</code>, you must specify the reference value. To do this, you can use one of the <a href="#formulas_variables">variables</a> available.<br/>
231
- You can also use a formula to define another reference value.
232
- </p>
233
-
234
- <div class="json">{
235
- "__auto__":{"label":"Table with cart weight","fees":"{table {cart.weight} in 0.5:5.30, 1.0:6.50}"},
236
- "__auto__":{"label":"Table with items quantity","fees":"{table {cart.qty} in 10:5.30, 20:6.50}"},
237
- "__auto__":{"label":"Table with price including tax","fees":"{table {cart.price+tax+discount} in 15.00:5.30, 30.00:6.50, *:10.00}"},
238
- "__auto__":{"label":"Table with price excluding tax","fees":"{table {cart.price-tax+discount} in 15.00:5.30, 30.00:6.50, *:10.00}"},
239
- "__auto__":{"label":"Table with custom value","fees":"{table ceil({cart.weight}/10) in 1:5.30, 2:6.50}"}
240
- }</div>
241
- </div>
242
-
243
- <div id="examples_special_switch">
244
- <h4>Using the special function <code>{switch … in …}</code> (associative table)</h4>
245
- <p>
246
- In a <code>switch</code>, you must specify the reference value. To do this, you can use one of the <a href="#formulas_variables">variables</a> available.<br/>
247
- You can also use a formula to define another reference value.
248
- </p>
249
- <div class="json">{
250
- "__auto__":{"label":"Switch with coupon code","fees":"{switch {{cart.coupon_code}} in 'coupon1':5.30, 'coupon2':6.50, null:10.00, *:7.50}"},
251
- "__auto__":{"label":"Switch with delivery country","fees":"{switch {{shipto.country_id}} in 'FR':5.30, 'BE':6.50, 'DE':10.00, *:7.50}"}
252
- }</div>
253
- </div>
254
-
255
- <div id="examples_special_count">
256
- <h4>Using the special function <code>{count …}</code></h4>
257
- <div class="json">{
258
- "__auto__":{"label":"If at least one product has the attribute 'color' equal to 'Bleu'","conditions":"{count items where product.attribute.color=='Bleu'} > 0","fees":10},
259
- "__auto__":{"label":"If all items have the option 'size' greater or equal to '1'","conditions":"{count items where item.option.size>='1'} == {cart.qty}","fees":10}
260
- }</div>
261
-
262
- <p>
263
- If the property is of type <strong>Yes/No</strong>, you must use the values <code>true</code>/<code>false</code> or <code>1</code>/<code>0</code> without quotes.
264
- </p>
265
- <div class="json">{
266
- "__auto__":{"label":"Example of property of type Yes/No: 1","conditions":"{count items where product.attribute.colissimo_allowed==1}","fees":10},
267
- "__auto__":{"label":"Example of property of type Yes/No: true","conditions":"{count items where product.attribute.colissimo_allowed==true}","fees":10}
268
- }</div>
269
- </div>
270
-
271
- <div id="examples_special_count_distinct">
272
- <h4>Using the special function <code>{count distinct …}</code></h4>
273
- <div class="json">{
274
- "__auto__":{"label":"Count of different SKU","conditions":"{count distinct product.attribute.sku}","fees":10}
275
- }</div>
276
- </div>
277
-
278
- <div id="examples_special_sum">
279
- <h4>Using the special function <code>{sum …}</code></h4>
280
- <div class="json">{
281
- "__auto__":{"label":"Sum of all options 'size' is greater than 30","conditions":"{sum item.option.size} > 30","fees":10}
282
- }</div>
283
- </div>
284
-
285
- <div id="examples_special_min">
286
- <h4>Using the special function <code>{min …}</code></h4>
287
- <div class="json">{
288
- "__auto__":{"label":"Minimum price excluding tax without discount is greater to 10","conditions":"{min item.price-tax-discount} > 10","fees":10}
289
- }</div>
290
- </div>
291
-
292
- <div id="examples_special_max">
293
- <h4>Using the special function <code>{max …}</code></h4>
294
- <div class="json">{
295
- "__auto__":{"label":"Maximum value of the option 'size' is lower than 50","conditions":"{max item.option.size} < 50","fees":10}
296
- }</div>
297
- </div>
298
- </div>
299
-
300
- <div id="examples_using_foreach">
301
- <h3>Using <code>{foreach …}</code> loops</h3>
302
- <div class="json">{
303
- "__auto__":{"label":"Grouping products by origin and process groups seperately","fees":"{foreach product.attribute.code_origin}{table {selection.weight} in 0.0:0.00, 1.0:11.00, 3.0:12.00, 5.0:13.00}{/foreach}"},
304
- "__auto__":{"label":" Calculate shipping fees by product","fees":"{foreach product.attribute.sku}{product.attribute.shipping}*{item.qty}{/foreach}"}
305
- }</div>
306
- </div>
307
-
308
- <div id="examples_using_array_functions">
309
- <h3>Manipulate arrays</h3>
310
-
311
- <h4>Using the function <code>in_array()</code></h4>
312
- <div class="json">{
313
- "__auto__":{"label":"Shipping","conditions":"in_array({cart.qty}, array(10, 20, 30))","fees":10}
314
- }</div>
315
-
316
- <h4>Using the function <code>in_array()</code> avec des chaînes de caractères *</h4>
317
- <div class="json">{
318
- "__auto__":{"label":"Shipping","conditions":"in_array({{cart.coupon_code}}, array('free1', 'free2'))","fees":10}
319
- }</div>
320
-
321
- <h4>Using the function <code>array_match_any()</code></h4>
322
- <div class="json">{
323
- "__auto__":{"label":"Shipping","about":"5 x weight of products that are in category 2 or category 3","fees":"{sum product.weight where array_match_any(product.categories.id, array(2, 3))} * 5.0"}
324
- }</div>
325
-
326
- <h4>Using the function <code>array_match_all()</code></h4>
327
- <div class="json">{
328
- "__auto__":{"label":"Shipping","about":"5 x weight of products that are in both category 2 and category 3","fees":"{sum product.weight where array_match_all(product.categories.id, array(2, 3))} * 5.0"}
329
- }</div>
330
- </div>
331
-
332
- <div id="examples_more">
333
- <h3>Other examples</h3>
334
-
335
- <div id="examples_product_categories">
336
- <h4>Using product category</h4>
337
- <p class="alert alert-danger">Warning: you must notice that in Magento, <strong>a product can be in multiple categories</strong>. So be particularly careful how you use this property.</p>
338
- <div class="json">{
339
- "__auto__":{"label":"Foreach loop with an iteration on the category","fees":"{foreach product.categories}{selection.weight}{/foreach}"},
340
- "__auto__":{"label":"Using the category inside a foreach loop","fees":"{foreach product.sku}({{product.category}}=='Test' ? 2.00 : 1.00)*{item.qty}{/foreach}"},
341
- "__auto__":{"label":"Using the id of the category inside a foreach loop","fees":"{foreach product.sku}({product.category.id}==12 ? 2.00 : 1.00)*{item.qty}{/foreach}"},
342
- "__auto__":{"about":"The function in_array() is used because product.categories returns an array","label":"Sum of weight attributes of products in category 'Test' ","fees":"{sum product.weight where in_array('Test', product.categories)}"},
343
- "__auto__":{"about":"The function in_array() is used because product.categories.id returns an array","label":"Sum of weight attributes of products in category 12 ","fees":"{sum product.weight where in_array(12, product.categories.id)}"},
344
- "__auto__":{"about":"The function array_match_any() is used because product.categories.id returns an array","label":"Sum of weight attributes of products in categories whose id is 11 and 12","fees":"{sum product.weight where array_match_any(product.categories.id, array(11, 12))}"},
345
- "__auto__":{"label":"Sum of weights of products having for first category 'Test'","fees":"{sum product.weight where product.category=='Test'}"},
346
- "__auto__":{"label":"Sum of weights of products having for first category id 12","fees":"{sum product.weight where product.category.id==12}"}
347
- }</div>
348
- </div>
349
-
350
- <div id="examples_data">
351
- <h4>Adding and using a <code>data</code> element</h4>
352
- <p>An element of type <code>data</code> allow to define data that can be used in shipping methods.</p>
353
- <div class="json">{
354
- "mydata":{"type":"data","var1":"12"},
355
- "__auto__":{"label":"Shipping","shipto":"FR","fees": "{mydata.var1}"},
356
- "__auto__":{"label":"Shipping","shipto":"DE","fees": "{mydata.var1}*1.5"}
357
- }</div>
358
- </div>
359
-
360
- <div id="examples_meta">
361
- <h4>Adding a <code>meta</code> element</h4>
362
- <p>An element of type <code>meta</code> allow to specify informative data (author, date…).</p>
363
- <div class="json">{
364
- "about":{"type":"meta","author":"Owebia","date":"15/07/2013","about":"2013 rates"}
365
- }</div>
366
- </div>
367
- </div>
368
- </div>
369
-
370
- <div id="definitions">
371
- <h2>Definitions</h2>
372
- <p>
373
- The configuration of a shipping mode is a JSON object containing <strong><a href="#definitions_property">properties</a></strong>.<br/>
374
- Each property has a unique name, wich will serve as <a href="#definitions_unique_id">unique identifier</a>.<br/>
375
- Each property will consiste on a configuration <strong><a href="#definitions_element">element</a></strong> (also a JSON object).<br/>
376
- </p>
377
- <div id="definitions_element">
378
- <h3>Elements</h3>
379
-
380
- <p>
381
- There are three different types of configuration <strong>element</strong>:
382
- </p>
383
- <ul>
384
- <li><code>method</code>: shipping method (default if not specified)</li>
385
- <li><code>data</code>: data that can be used in one or more shipping methods (<a href="#examples_data">examples</a>)</li>
386
- <li><code>meta</code>: informative data (<a href="#examples_meta">examples</a>)</li>
387
- </ul>
388
- </div>
389
-
390
- <div id="definitions_property">
391
- <h3>Properties</h3>
392
-
393
- <p>
394
- Each element has several <strong>properties</strong>:
395
- </p>
396
- <ul>
397
- <li id="property_about"><code>about</code>: comment about the element</li>
398
- <li id="property_type"><code>type</code>: element type (<code>method</code>, <code>meta</code> or <code>data</code>)</li>
399
- </ul>
400
-
401
- <p>
402
- Properties specific to the element type <code>method</code>:
403
- </p>
404
- <ul>
405
- <li id="property_label"><code>label</code>: name of shipping method</li>
406
- <li id="property_description"><code>description</code> (visible only if the template displays it)</li>
407
- <li id="property_enabled"><code>enabled</code>: shipping method enabled or not</li>
408
- <li id="property_fees"><code>fees</code>: shipping fees</li>
409
- <li id="property_conditions"><code>conditions</code>: activation conditions</li>
410
- <li id="property_shipto"><code>shipto</code>: countries (regions, postal codes) allowed for delivery</li>
411
- <li id="property_billto"><code>billto</code>: countries (regions, postal codes) allowed for billing</li>
412
- <li id="property_origin"><code>origin</code>: countries (regions, postal codes) allowed for origin</li>
413
- <li id="property_customer_groups"><code>customer_groups</code>: customer groups allowed</li>
414
- <li id="property_tracking_url"><code>tracking_url</code> (<a href="#more_tracking_url">more informations</a>)</li>
415
- </ul>
416
-
417
- <p><a href="#examples">See examples</a></p>
418
-
419
- <h4>Using properties of type address (<code>shipto</code>, <code>billto</code> and <code>origin</code>)</h4>
420
- <p>
421
- The country codes used are those of Magento (apparently they are the same as the <a href="http://fr.wikipedia.org/wiki/ISO_3166-1" target=_blank>ISO 3166-1 alpha-2 codes</a>).<br/>
422
- It is possible to specify region codes (only with <code>shipto</code>) or zip codes that you want to filter or exclude.
423
- </p>
424
- <p class=new>
425
- You can use the <strong>wildcard</strong> character <code>*</code> or <strong>regular expressions</strong> for postal codes.<br/>
426
- A regular expression must start and end with the character <code>/</code>. If you want to use the characters <code>(</code>, <code>)</code> or <code>.</code>, you must escape them with the character <code>\</code> (ex: <code><span class=string>"FR(/^25\([0-9]{3}\)$/)"</span></code>).<br/>
427
- You can use the insensitivity modifier (ex: <code><span class=string>"GB(/^PO.*$/i)"</span></code>).
428
- </p>
429
-
430
- <p><a href="#examples_using_address_filters">See examples</a></p>
431
-
432
- <div id="address_filter" class="alert alert-info">
433
- <p><strong>Tip</strong><br/>To shorten the seizure of countries, you can use the following variables:</p>
434
- <ul>
435
- <li><code>{address_filter.AF}</code>: African countries</li>
436
- <li><code>{address_filter.AS}</code>: Asian countries</li>
437
- <li><code>{address_filter.EU}</code>: European countries</li>
438
- <li><code>{address_filter.NA}</code>: North American countries</li>
439
- <li><code>{address_filter.SA}</code>: South American countries</li>
440
- <li><code>{address_filter.OC}</code>: Oceanian countries</li>
441
- <li><code>{address_filter.AN}</code>: countries of Antarctica</li>
442
- <li><code>{address_filter.EU-27}</code>: countries of the European Union</li>
443
- <li><code>{address_filter.DOM}</code>: country codes of French Overseas "Départements"</li>
444
- <li><code>{address_filter.COM}</code>: country codes of French Overseas "Collectivités"</li>
445
- </ul>
446
- <p><a href="#examples_using_address_filters_shortcuts">See examples</a></p>
447
- </div>
448
- </div>
449
-
450
- <div id="definitions_unique_id">
451
- <h3>The unique identifier</h3>
452
-
453
- <p>Each configuration element has a <strong>unique identifier</strong>. This identifier can be used to refer to the element.</p>
454
- <p>Example:</p>
455
- <div class="json">{
456
- "europa":{"label":"Shipping to Europa","fees":10},
457
- "us":{"label":"Shipping to US","fees":"{europa.fees}+20"}
458
- }</div>
459
-
460
- <p class="alert alert-danger"><strong><u>Warning</u>:</strong> to avoid conflicts, use only the characters <code>a-z</code>, <code>A-Z</code>, <code>0-9</code>, <code>-</code> and <code>_</code> for the unique identifier.<br/>You should also avoid identifiers that already correspond to variable names (<code>cart</code>, <code>product</code>, <code>item</code>…).</p>
461
- </div>
462
- </div>
463
-
464
- <div id="formulas">
465
- <h2>Formulas</h2>
466
- <p>
467
- The properties <code>fees</code> and <code>conditions</code> are defined using formulas.<br/>
468
- </p>
469
- <p>
470
- A formula uses <a href="#formulas_variables">variables</a>, <a href="#formulas_functions">functions</a>, <a href="#formulas_special_functions">special functions</a> and mathematical operators.
471
- </p>
472
- <p>
473
- Available mathematical operators:
474
- </p>
475
- <ul>
476
- <li>operators: <code>*</code>, <code>/</code>, <code>+</code> and <code>-</code></li>
477
- <li>modulo: <code>%</code></li>
478
- <li>parentheses: <code>(</code> and <code>)</code></li>
479
- <li>boolean operators <code>&amp;&amp;</code>, <code>and</code>, <code>||</code>, <code>or</code>, <code>==</code>, <code>&lt;</code>, <code>&gt;</code>, <code>&lt;=</code>, <code>&gt;=</code></li>
480
- <li>binary operators <code>&amp;</code> and <code>|</code></li>
481
- <li>the operator group <code>C ? X : Y</code> (ex: <code><span class=string>"{cart.price_exluding_tax}&gt;100 ? 15*{cart.weight} : 20*{cart.weight}"</span></code>)</li>
482
- </ul>
483
- <p>
484
- You can put spaces and line breaks in formulas (for lightening).
485
- </p>
486
- <p>
487
- You can use the following advanced features: casting to interger <code>(int)</code> or floatting numbers <code>(float)</code>,
488
- comparison with the <code>null</code> value or with boolean values <code>true</code> and <code>false</code>.
489
- </p>
490
-
491
- <div id="formulas_variables">
492
- <h3>Variables</h3>
493
-
494
- <p class="alert alert-info">
495
- When you use variables of type string, you must escape them with single quotes or use the auto-quoting syntax <code>{{ }}</code>.
496
- </p>
497
-
498
- <p>
499
- The following variables can be used in <a href="#formulas">formulas</a>.
500
- </p>
501
- <ul>
502
- <li id="formulas_variables_cart">The cart:
503
- <ul>
504
- <li><code>{cart.weight}</code>: weight of goods</li>
505
- <li><code>{cart.qty}</code>: the quantity of items</li>
506
- <li><code>{cart.price-tax+discount}</code>: price excluding tax with discount</li>
507
- <li><code>{cart.price+tax+discount}</code>: price including tax with discount</li>
508
- <li><code>{cart.price-tax-discount}</code>: price excluding tax without discount</li>
509
- <li><code>{cart.price+tax-discount}</code>: price including tax without discount</li>
510
- <li><code>{cart.coupon_code}</code>: coupon code</li>
511
- <li><code>{cart.free_shipping}</code>: delivery offered (by rules in Magento) [true/false]</li>
512
- <li><code>{cart.weight_unit}</code></li>
513
- <li><code>{cart.weight_for_charge}</code>: weight of goods whose delivery is not offered (by cart pricing rules in Magento)</li>
514
- </ul>
515
- </li>
516
- <li id="formulas_variables_quote">The quote:
517
- <ul>
518
- <li><code>{quote.subtotal}</code>: subtotal (excluding tax)</li>
519
- <li><code>{quote.subtotal_with_discount}</code>: subtotal (excluding tax) with discount</li>
520
- <li><code>{quote.grand_total}</code>: total (including tax) with discount</li>
521
- <li><code>{quote.base_subtotal}</code>: subtotal (excluding tax) in base currency</li>
522
- <li><code>{quote.base_subtotal_with_discount}</code>: subtotal (excluding tax) with discount in base currency</li>
523
- <li><code>{quote.base_grand_total}</code>: total (including tax) with discount in base currency</li>
524
- </ul>
525
- </li>
526
- <li id="formulas_variables_customer_group">The customer group:
527
- <ul>
528
- <li><code>{customer_group.id}</code>: id of customer group</li>
529
- <li><code>{customer_group.code}</code>: name of customer group</li>
530
- <li><code>{customer_group.*}</code>: property of the customer group (ex: <code>{customer_group.tax_class_id}</code>)</li>
531
- </ul>
532
- </li>
533
- <li id="formulas_variables_customer">The customer:
534
- <ul>
535
- <li><code>{customer.id}</code>: id of customer</li>
536
- <li><code>{customer.attribute.*}</code>: attribute of the customer (ex: lastname, firstname, group_id…)</li>
537
- <li><code>{customer.attribute.*.value}</code>: in case of an attribute of type selection list, <code>{customer.attribute.*}</code> returns the id, to get the value, you have to use <code>{customer.attribute.*.value}</code></li>
538
- <li><code>{customer.*}</code>: same as <code>{customer.attribute.*}</code>, unless the variable is already defined (ex: <code>{customer.id}</code> is already defined)</li>
539
- </ul>
540
- </li>
541
- <li id="formulas_variables_customvar">Custom Variables (since Magento 1.4.0.1):
542
- <ul>
543
- <li><code>{customvar.*}</code>: custome variable defined in Magento (ex: <code>{customvar.my_var}</code>)</li>
544
- </ul>
545
- </li>
546
- <li id="formulas_variables_shipto">The delivery address:
547
- <ul>
548
- <li><code>{shipto.country_name}</code></li>
549
- <li><code>{shipto.country_id}</code>: the country code</li>
550
- <li><code>{shipto.region_id}</code></li>
551
- <li><code>{shipto.region_code}</code></li>
552
- <li><code>{shipto.street}</code></li>
553
- <li><code>{shipto.city}</code></li>
554
- <li><code>{shipto.postcode}</code></li>
555
- </ul>
556
- </li>
557
- <li id="formulas_variables_billto">The billing address:
558
- <ul>
559
- <li><code>{billto.country_name}</code></li>
560
- <li><code>{billto.country_id}</code>: the country code</li>
561
- <li><code>{billto.postcode}</code></li>
562
- <li><code>{billto.*}</code>: property of the billing address (ex: <code>{billto.city}</code>)</li>
563
- </ul>
564
- </li>
565
- <li id="formulas_variables_origin">The origin address:
566
- <ul>
567
- <li><code>{origin.country_name}</code></li>
568
- <li><code>{origin.country_id}</code>: the country code</li>
569
- <li><code>{origin.region_id}</code></li>
570
- <li><code>{origin.city}</code></li>
571
- <li><code>{origin.postcode}</code></li>
572
- </ul>
573
- </li>
574
- <li id="formulas_variables_store">The store:
575
- <ul>
576
- <li><code>{store.id}</code> <code>{store.code}</code> <code>{store.name}</code> <code>{store.address}</code> <code>{store.phone}</code></li>
577
- </ul>
578
- </li>
579
- <li id="formulas_variables_date">The current date:
580
- <ul>
581
- <li><code>{date.timestamp}</code>: UNIX timestamp of the current date</li>
582
- <li><code>{date.year}</code> <code>{date.month}</code> <code>{date.day}</code> <code>{date.hour}</code> <code>{date.minute}</code> <code>{date.second}</code></li>
583
- <li><code>{date.weekday}</code>: day of the week for the current date from 0 (Sunday) to 6 (Saturday)</li>
584
- </ul>
585
- </li>
586
- <li id="formulas_variables_request">The <code>request</code> object:
587
- <ul>
588
- <li><code>{request.*}</code>: property of the request object (Mage_Shipping_Model_Rate_Request) given by Magento (ex: <code>{request.package_qty}</code>). Use "Debug" option to get more details on available properties.</li>
589
- </ul>
590
- </li>
591
- </ul>
592
-
593
- <div id="formulas_variables_for_special_functions">
594
- <h4>Variables that can be used in special functions</h4>
595
-
596
- <p>The following variables can be used in <a href="#formulas_special_functions">special functions</a>.</p>
597
-
598
- <p class="alert alert-danger">Unlike elsewhere, the following variables should not be surrounded by the characters <code>{</code> and <code>}</code>.</p>
599
-
600
- <p>
601
- An <code>item</code> is a variation of a <code>product</code> to which some options have been added. Each <code>item</code> has a quantity.
602
- </p>
603
- <ul>
604
- <li id="formulas_variables_item">The <code>item</code>:
605
- <ul>
606
- <li><code>item.qty</code>: quantity in the cart</li>
607
- <li><code>item.price-tax+discount</code>: price excluding tax with discount</li>
608
- <li><code>item.price-tax-discount</code>: price excluding tax without discount</li>
609
- <li><code>item.price+tax+discount</code>: price including tax with discount</li>
610
- <li><code>item.price+tax-discount</code>: price including tax without discount</li>
611
- <li><code>item.option.*</code>: option (the available options depend on the product)</li>
612
- </ul>
613
- </li>
614
- <li id="formulas_variables_product">The <code>product</code>:
615
- <ul>
616
- <li><code>product.attribute.*</code><br/>
617
- Interesting attributes:
618
- <ul>
619
- <li><code>sku</code></li>
620
- <li><code>name</code></li>
621
- <li><code>weight</code></li>
622
- <li><code>price</code> (as defined in Magento backoffice)</li>
623
- <li><code>special_price</code>: (as defined in Magento backoffice)</li>
624
- <li>…</li>
625
- </ul>
626
- </li>
627
- <li><code>product.attribute.*.value</code>: value of the attribute<br/>
628
- In case of an attribute of type selection list, <code>product.attribute.*</code> returns the id. To get the value, you have to use <code>product.attribute.*.value</code></li>
629
- <li><code>product.*</code>: same as <code>product.attribute.*</code> unless the variable is already defined (ex: <code>product.category</code>)</li>
630
- <li>First category of the product:
631
- <ul>
632
- <li><code>product.category</code>: name of the category</li>
633
- <li><code>product.category.id</code></li>
634
- <li><code>product.category.*</code>: attribute of the category (ex: <code>product.category.is_active</code>)<br/>
635
- Interesting attributes:
636
- <ul>
637
- <li><code>is_active</code></li>
638
- <li><code>name</code></li>
639
- <li>…</li>
640
- </ul>
641
- </li>
642
- </ul>
643
- </li>
644
- <li>All product categories (returns an array, <a href="#examples_product_categories">examples</a>):
645
- <ul>
646
- <li><code>product.categories</code>: array of name of the categories</li>
647
- <li><code>product.categories.id</code>: array of id of the categories</li>
648
- </ul>
649
- </li>
650
- <li>The attribute set:
651
- <ul>
652
- <li><code>product.attribute_set</code>: name of the attribute set</li>
653
- <li><code>product.attribute_set.id</code></li>
654
- <li><code>product.attribute_set.*</code>: attribute of the attribute set (ex: <code>product.attribute_set.attribute_set_name</code>)</li>
655
- </ul>
656
- </li>
657
- <li><code>product.stock.*</code>: attribute of the product stock<br/>
658
- Interesting attributes:
659
- <ul>
660
- <li><code>is_in_stock</code></li>
661
- <li><code>qty</code>: quantity in stock</li>
662
- <li>…</li>
663
- </ul>
664
- </li>
665
- </ul>
666
- </li>
667
- </ul>
668
- </div>
669
-
670
- <div id="formulas_variables_for_foreach">
671
- <h4>Variables that can be used in <code>foreach</code> loops</h4>
672
-
673
- <p>The following variables can be used in <a href="#formulas_foreach"><code>foreach</code> loops</a>.</p>
674
-
675
- <ul>
676
- <li><code>{selection.weight}</code></li>
677
- <li><code>{selection.qty}</code>: items count in the selection</li>
678
- </ul>
679
- <p>
680
- When the selection is made on the sku, each selection consists of a single article.
681
- We can therefore use the <a href="#formulas_variables_for_special_functions">item and product variables</a>.
682
- </p>
683
- <ul>
684
- <li><code>{item.*}</code>: item property</li>
685
- <li><code>{product.*}</code>: product property</li>
686
- </ul>
687
- <p class="alert alert-info">
688
- Item and product variables are identical to <a href="#formulas_variables_for_special_functions">variables that can be used in special functions</a> with the only difference that they must be surrounded by the characters <code>{</code> and <code>}</code>.
689
- </p>
690
- </div>
691
- </div>
692
-
693
- <div id="formulas_functions">
694
- <h3>Functions</h3>
695
-
696
- <h4>Numerical functions</h4>
697
- <ul>
698
- <li><code>abs(x)</code>: absolute value</li>
699
- <li><code>ceil(x)</code>: round up</li>
700
- <li><code>exp(x)</code>: exponent</li>
701
- <li><code>floor(x)</code>: round down</li>
702
- <li><code>log(x)</code>: logarithm</li>
703
- <li><code>log(x, base)</code>: natural logarithm</li>
704
- <li><code>max(x, y, …)</code>: maximum, null values ignored</li>
705
- <li><code>min(x, y, …)</code>: minimum, null values ignored</li>
706
- <li><code>pi()</code>: PI number</li>
707
- <li><code>pow(x, puissance)</code>: pow</li>
708
- <li><code>rand(min, max)</code>: random integer</li>
709
- <li><code>round(x)</code></li>
710
- <li><code>sqrt(x)</code>: square root</li>
711
- </ul>
712
-
713
- <h4>Functions to manipulate strings</h4>
714
- <ul>
715
- <li><code>substr(string, start, length)</code>: returns a string segment.</li>
716
- </ul>
717
-
718
- <h4>Functions to manipulate arrays</h4>
719
- <ul>
720
- <li><code>in_array(value, array(value1, value2, …))</code>: returns true if the value is found in the array.</li>
721
- <li><code>array_match_any(array(value1, value2, …), array(value1, value2, …))</code>: returns true if at least one value is found in both arrays.</li>
722
- <li><code>array_match_all(array(value1, value2, …), array(value1, value2, …))</code>: returns true if both arrays are identical.</li>
723
- </ul>
724
-
725
- <h4>More functions</h4>
726
- <ul>
727
- <li><code>range(value, min, max, include_min, include_max)</code>: returns true if <code>value</code> is greater than <code>min</code> and lower than <code>max</code>. By default, <code>include_min</code> and <code>include_max</code> are equal to <code>true</code>.</li>
728
- </ul>
729
- </div>
730
-
731
- <div id="formulas_special_functions">
732
- <h3>Special functions</h3>
733
-
734
- <ul>
735
- <li><code>{table … in …}</code>: defining values based on thresholds (<a href="#examples_special_table">examples</a>)</li>
736
- <li><code>{switch … in …}</code>: defining an associative table (<a href="#examples_special_switch">examples</a>)</li>
737
- </ul>
738
- <p>
739
- The first parameter <code>…</code> of <code>table</code> and <code>switch</code> functions is the reference value, it can be either a variable or a formula.
740
- </p>
741
- <ul>
742
- <li><code>{count items[ where …]}</code>: counts eligible items (<a href="#examples_special_count">examples</a>)</li>
743
- <li><code>{count distinct …[ where …]}</code>: counts all different values of a property for eligible items (<a href="#examples_special_count_distinct">examples</a>)</li>
744
- <li><code>{sum …[ where …]}</code>: calculates the sum of the values of a property for eligible items (<a href="#examples_special_sum">examples</a>)</li>
745
- <li><code>{min …[ where …]}</code>: returns the minimum value of a property for eligible items (<a href="#examples_special_min">examples</a>)</li>
746
- <li><code>{max …[ where …]}</code>: returns the maximum value of a property for eligible items (<a href="#examples_special_max">examples</a>)</li>
747
- </ul>
748
- <p>
749
- The first parameter <code>…</code> of <code>count distinct</code>, <code>sum</code>, <code>min</code> and <code>max</code> functions must be a property (ex: <code>product.attribute.weight</code>).
750
- </p>
751
- <p>The condition <code>where</code> is optional. If specified, it will be in the form of a formula.</p>
752
- </div>
753
-
754
- <div id="formulas_foreach">
755
- <h3>Using <code>foreach</code> loops</h3>
756
-
757
- <p>
758
- <code>foreach</code> loops can perform a calculation on groups of products rather than consider all the products in the cart. <br/>
759
- The overall result of a <code>foreach</code> loop is the sum of the results of each pass through the loop.
760
- </p>
761
- <p>
762
- Inside a <code>foreach</code> loop, you can use <a href="#formulas_variables_for_foreach">new variables</a>.
763
- </p>
764
- <p>
765
- <a href="#examples_using_foreach">Examples</a>
766
- </p>
767
- </div>
768
-
769
- <div id="formulas_deprecated_variables">
770
- <h3>Deprecated variables</h3>
771
-
772
- <p>The following variables must be replaced by their equivalent.</p>
773
-
774
- <ul>
775
- <li><a href="#formulas_variables"><code><span class=strike>{cart.coupon}</span> {cart.coupon_code}</code></a></li>
776
- <li><a href="#formulas_variables"><code><span class=strike>{cart.quantity}</span> {cart.qty}</code></a></li>
777
- <li><a href="#formulas_variables"><code><span class=strike>{cart.price_excluding_tax}</span> {cart.price-tax+discount}</code></a></li>
778
- <li><a href="#formulas_variables"><code><span class=strike>{cart.price_including_tax}</span> {cart.price+tax+discount}</code></a></li>
779
- <li><a href="#formulas_variables"><code><span class=strike>{cart.weight.for-charge}</span> {cart.weight_for_charge}</code></a></li>
780
- <li><a href="#formulas_variables"><code><span class=strike>{cart.weight.unit}</span> {cart.weight_unit}</code></a></li>
781
- <li><a href="#formulas_variables"><code><span class=strike>{customer.group.code}</span> {customer_group.code}</code></a></li>
782
- <li><a href="#formulas_variables"><code><span class=strike>{customer.group.id}</span> {customer_group.id}</code></a></li>
783
- <li><a href="#formulas_variables"><code><span class=strike>{{customVar code=*}}</span> {customvar.*}</code></a></li>
784
- <li><a href="#formulas_variables"><code><span class=strike>{destination.country.code}</span> {shipto.country_id}</code></a></li>
785
- <li><a href="#formulas_variables"><code><span class=strike>{destination.country.name}</span> {shipto.country_name}</code></a></li>
786
- <li><a href="#formulas_variables"><code><span class=strike>{destination.postcode}</span> {shipto.postcode}</code></a></li>
787
- <li><a href="#formulas_variables"><code><span class=strike>{destination.region.code}</span> {shipto.region_code}</code></a></li>
788
- <li><a href="#formulas_variables"><code><span class=strike>{free_shipping}</span> {cart.free_shipping}</code></a></li>
789
- <li><a href="#formulas_variables"><code><span class=strike>{origin.country.code}</span> {origin.country_id}</code></a></li>
790
- <li><a href="#formulas_variables"><code><span class=strike>{origin.country.name}</span> {origin.country_name}</code></a></li>
791
- <li><a href="#formulas_variables"><code><span class=strike>{origin.region.code}</span> {origin.region_id}</code></a></li>
792
- <li><a href="#formulas_variables_for_foreach"><code><span class=strike>{selection.quantity}</span> {selection.qty}</code></a></li>
793
- </ul>
794
- <ul>
795
- <li><a href="#formulas_variables_for_special_functions"><code><span class=strike>product.quantity</span> item.qty</code></a></li>
796
- <li><a href="#formulas_variables_for_special_functions"><code><span class=strike>product.price-tax+discount</span> item.price-tax+discount</code></a></li>
797
- <li><a href="#formulas_variables_for_special_functions"><code><span class=strike>product.price-tax-discount</span> item.price-tax-discount</code></a></li>
798
- <li><a href="#formulas_variables_for_special_functions"><code><span class=strike>product.price+tax+discount</span> item.price+tax+discount</code></a></li>
799
- <li><a href="#formulas_variables_for_special_functions"><code><span class=strike>product.price+tax-discount</span> item.price+tax-discount</code></a></li>
800
- <li><a href="#formulas_variables_for_special_functions"><code><span class=strike>product.option.*</span> item.option.*</code></a></li>
801
- <li><a href="#formulas_variables_for_special_functions"><code><span class=strike>product.option.*</span> item.option.*</code></a></li>
802
- </ul>
803
- </div>
804
- </div>
805
-
806
- <div id="more">
807
- <h2>Miscellaneous</h2>
808
-
809
- <div id="more_tracking_url">
810
- <h3>The tracking URL</h3>
811
-
812
- <p class="alert alert-danger">
813
- The use of <code>tracking_url</code> property is reserved for experienced users. If you don't understand the instructions below, it is recommended that you avoid using this feature.
814
- </p>
815
- <p>
816
- The <code>tracking_url</code> property overrides the field "Tracking URL" of an Owebia Shipping shipping mode. So you can specify a tracking URL <strong>foreach shipping method</strong> rather than one for all shipping mode.
817
- </p>
818
- <p>
819
- To automatically insert the tracking number in the tracking URL, you must use <code>{tracking_number}</code>.
820
- </p>
821
-
822
- <div class="json">{
823
- "__auto__":{"label":"Example of tracking URL for the carrier Colissimo","fees":10,"tracking_url":"http://www.coliposte.net/particulier/suivi_particulier.jsp?colispart={tracking_number}"}
824
- }</div>
825
-
826
- <p>
827
- Magento does not support tracking links but tracking statuses. The extension Owebia Shipping 2 provides an HTML link instead of the status, link allowing you to go on the carrier's website and follow the progress of the parcel.
828
- </p>
829
- <p>
830
- When the tracking URL is built by the extension, the only information available is the tracking number and there was nowhere an access to the shipping method selected. In order to find the tracking URL in the configuration, you must specify the shipping method inside the tracking number, for example: <code>colissimo:8Lxxxxxxxxxxx</code> where <code>colissimo</code> is the code of the shipping method selected.<br/>
831
- If no code is specified (if you enter only the tracking number), the URL used will be the one of the shipping mode.
832
- </p>
833
- <p class="alert alert-danger">
834
- To answer a recurrent question, Magento displays the tracking status from the back office or front office. If you want to insert the tracking URL in shipping mails, <strong>you need to develop yourself</strong> the retrieval of tracking URL and its incorporation in the mail, in fact, the Owebia Shipping extension simply provides customizable shipping methods without making big changes to Magento core to reduce incompatibility and update problems.
835
- </p>
836
- <p class="alert alert-danger">
837
- If you get a blank popup when you click on the tracking link, your problem is most likely related to the fact that you did not specify the code of the shipping method in the tracking number (see instructions above) and your global field "Tracking URL" is empty.
838
- </p>
839
- <p class="alert alert-danger">There are currently no plans to change this feature.</p>
840
- </div>
841
- </div>
842
-
843
- <div id="changelog">
844
- <h2>Changelog</h2>
845
-
846
- <pre class=changelog>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
847
  [2.5.18 - 24 juillet 2014]
848
  Pas de modification, nouvelle version pour Magento Connect
849
 
@@ -934,8 +956,8 @@ Mise à jour de la syntaxe de la configuration par défaut
934
  Modification de la syntaxe de la configuration pour la rendre 100% compatible JSON
935
  Refonte complète de l'éditeur
936
  Suppression de la compatibilité avec les propriétés dépréciées suivantes :
937
- 'fees_table', 'fees_formula', 'fixed_fees', 'reference_value', 'prices_range', 'weights_range', 'product_properties',
938
- 'free_shipping__fees_table', 'free_shipping__fees_formula', 'free_shipping__fixed_fees', 'free_shipping__label',
939
  Suppression de la compatibilité avec la désactivation d'une méthode de livraison à l'aide du caractère #
940
  Suppression de la compatibilité avec les mots réservés en majuscule : TABLE, SUM, COUNT, DISTINCT et IN
941
  Ajout des fonctions array_match_any et array_match_all
@@ -960,9 +982,9 @@ Correction du code PHP pour supprimer des erreurs E_STRICT
960
  Correction d'un bug dans l'utilisation de la fonction {table ... in ...} : lorsque la variable de référence est indéfinie, le résultat était invalide (valeur précédente de la variable $replacement)
961
  Correction d'un problème avec les produits packagés (bundle product) : les produits 'bundle' et les produits 'simple' étaient tous deux récupérés ce qui faussait les résultats
962
  Support des sets d'attributs
963
- product.attribute_set dans les conditions de boucle foreach
964
- {product.attribute_set} et {product.attribute_set.id} comme variables dans les boucles foreach
965
- product.attribute_set, product.attribute_set.id dans les conditions des opérations sum, count, min et max
966
  Optimisation du chargement de certaines valeurs (catégories, attribute set, ...)
967
  Correction d'un problème avec les castings successifs (string), (float) qui posent problème lorsque la locale utilise la virgule comme séparateur de décimales
968
 
@@ -989,18 +1011,18 @@ Initialisation des formules sum et count à 0 au lieu de null (pour éviter les
989
  Ajout des alias &quot;a&quot; et &quot;attr&quot; pour &quot;attribute&quot;, &quot;o&quot; et &quot;opt&quot; pour &quot;option&quot;, &quot;p&quot; pour &quot;product&quot;, &quot;c&quot; pour &quot;cart&quot;, &quot;s&quot; pour &quot;selection&quot;
990
  Correction de la récupération des variables personnalisées : getValue('text') au lieu de getValue('plain')
991
  Support des catégories
992
- product.categories dans les conditions de boucle foreach
993
- {product.category} et {product.category.id} comme variables dans les boucles foreach
994
- product.category, product.category.id, product.categories, product.categories.id dans les conditions des opérations sum, count, min et max
995
  Amélioration du debug
996
 
997
  [2.4.1 - 24 août 2011]
998
  Modification légère du code php pour éviter un plantage avec certaines versions d'eAccelerator (cache php)
999
- $row = null;
1000
- $this-&gt;addMessage('info',$row,null,'Ignored lines %s','&lt;div class=&quot;code&quot;&gt;'.trim($config_string).'&lt;/div&gt;');
1001
- au lieu de ;
1002
- $this-&gt;addMessage('info',$row=null,null,'Ignored lines %s','&lt;div class=&quot;code&quot;&gt;'.trim($config_string).'&lt;/div&gt;');
1003
- (cf http://www.magentocommerce.com/boards/viewthread/233202/)
1004
  Ajout des variables de debug &quot;info.server.os&quot; et &quot;info.server.software&quot;
1005
  Ajout de la possibilité de récupérer la valeur minimum ou maximum de la quantité (ex: &quot;{max product.quantity}&quot;)
1006
 
@@ -1227,279 +1249,279 @@ Corrections de bugs
1227
  [2.0 - 3 avril 2009]
1228
  Création de la version 2.0 du module Owebia Shipping qui n'est plus compatible avec les anciennes versions
1229
 
1230
- </pre>
1231
- </div>
1232
-
1233
- <div id="index">
1234
- <h2>Index</h2>
1235
- <div class="panel">
1236
- <div class="row">
1237
- <div class="col-lg-6">
1238
- <h3>A</h3>
1239
- <ul>
1240
- <li><code>about</code>: <a href="#property_about">property</a></li>
1241
- <li>activation: see <code>enabled</code></li>
1242
- <li>address of origin: see <code>origin</code></li>
1243
- <li>address of billing: see <code>billto</code></li>
1244
- <li>address of delivery: see <code>shipto</code></li>
1245
- <li><code>address_filter</code>: <a href="#address_filter">shortcuts</a>, <a href="#examples_using_address_filters_shortcuts">examples</a></li>
1246
- <li>associative table: see <code>switch</code></li>
1247
- <li>attribute of product: see <code>product.attribute.*</code></li>
1248
- </ul>
1249
-
1250
- <h3>B</h3>
1251
- <ul>
1252
- <li><code>billto</code>:
1253
- <ul>
1254
- <li><a href="#property_billto">property</a></li>
1255
- <li><a href="#formulas_variables_billto">variables</a></li>
1256
- </ul>
1257
- </li>
1258
- </ul>
1259
-
1260
- <h3>C</h3>
1261
- <ul>
1262
- <li><code>cart</code>: <a href="#formulas_variables_cart">variables</a></li>
1263
- <li>comment: see <code>about</code></li>
1264
- <li><code>conditions</code>: <a href="#property_conditions">property</a></li>
1265
- <li><code>count</code>: <a href="#formulas_special_functions">special functions</a></li>
1266
- <li><code>count distinct</code>: <a href="#formulas_special_functions">special functions</a></li>
1267
- <li><code>customer</code>: <a href="#formulas_variables_customer">variables</a></li>
1268
- <li><code>customer_group</code>: <a href="#formulas_variables_customer_group">variables</a></li>
1269
- <li><code>customer_groups</code>: <a href="#property_customer_groups">property</a></li>
1270
- <li><code>customvar</code>: <a href="#formulas_variables_customvar">variables</a></li>
1271
- </ul>
1272
-
1273
- <h3>D</h3>
1274
- <ul>
1275
- <li><code>data</code>: <a href="#definitions_element">element type</a>, <a href="#examples_data">examples</a></li>
1276
- <li><code>date</code>: <a href="#formulas_variables_date">variables</a></li>
1277
- <li>deactivation: see <code>enabled</code></li>
1278
- <li><code>description</code>: <a href="#property_description">property</a></li>
1279
- <li>destination: see <code>shipto</code></li>
1280
- <li>DOM/TOM: <a href="#examples_excluding_domtom_postcode">excluding postal codes</a></li>
1281
- </ul>
1282
-
1283
- <h3>E</h3>
1284
- <ul>
1285
- <li>element: <a href="#definitions_element">definition</a></li>
1286
- <li><code>enabled</code>: <a href="#property_enabled">property</a></li>
1287
- </ul>
1288
-
1289
- <h3>F</h3>
1290
- <ul>
1291
- <li><code>fees</code>: <a href="#property_fees">property</a></li>
1292
- <li><code>foreach</code>: <a href="#formulas_foreach">loop</a>, <a href="#examples_using_foreach">examples</a></li>
1293
- <li><a href="#formulas">Formulas</a></li>
1294
- <li>free shipping: <a href="#examples_simple">examples</a></li>
1295
- <li><a href="#formulas_functions">Functions</a></li>
1296
- </ul>
1297
-
1298
- <h3>I</h3>
1299
- <ul>
1300
- <li>identifier (unique): <a href="#definitions_unique_id">definition</a></li>
1301
- <li><code>item</code>: <a href="#formulas_variables_item">variables</a></li>
1302
- <li><code>item.option.*</code>: <a href="#formulas_variables_item">variables</a></li>
1303
- </ul>
1304
- </div>
1305
- <div class="col-lg-6">
1306
- <h3>L</h3>
1307
- <ul>
1308
- <li><code>label</code>: <a href="#property_label">property</a></li>
1309
- </ul>
1310
-
1311
- <h3>M</h3>
1312
- <ul>
1313
- <li><code>max</code>:
1314
- <ul>
1315
- <li><a href="#formulas_functions">function</a></li>
1316
- <li><a href="#formulas_special_functions">special functions</a>, <a href="#examples_special_max">examples</a></li>
1317
- </ul>
1318
- </li>
1319
- <li><code>meta</code>: <a href="#definitions_element">element type</a>, <a href="#examples_meta">examples</a></li>
1320
- <li><code>method</code>: <a href="#definitions_element">element type</a></li>
1321
- <li><code>min</code>:
1322
- <ul>
1323
- <li><a href="#formulas_functions">function</a></li>
1324
- <li><a href="#formulas_special_functions">special functions</a>, <a href="#examples_special_min">examples</a></li>
1325
- </ul>
1326
- </li>
1327
- </ul>
1328
-
1329
- <h3>O</h3>
1330
- <ul>
1331
- <li>option of item: see <code>item.option.*</code></li>
1332
- <li><code>origin</code>:
1333
- <ul>
1334
- <li><a href="#property_origin">property</a></li>
1335
- <li><a href="#formulas_variables_origin">variables</a></li>
1336
- </ul>
1337
- </li>
1338
- </ul>
1339
-
1340
- <h3>P</h3>
1341
- <ul>
1342
- <li><code>product</code>: <a href="#formulas_variables_product">variables</a></li>
1343
- <li><code>product.attribute.*</code>: <a href="#formulas_variables_product">variables</a></li>
1344
- <li><code>product.categories</code>: <a href="#formulas_variables_product">variables</a>, <a href="#examples_product_categories">examples</a></li>
1345
- <li>property: <a href="#definitions_property">definition</a></li>
1346
- </ul>
1347
-
1348
- <h3>Q</h3>
1349
- <ul>
1350
- <li><code>quote</code> : <a href="#formulas_variables_quote">variables</a></li>
1351
- </ul>
1352
-
1353
- <h3>R</h3>
1354
- <ul>
1355
- <li>regular expression: see property <code>shipto</code></li>
1356
- <li><code>request</code>: <a href="#formulas_variables_request">variables</a></li>
1357
- </ul>
1358
-
1359
- <h3>S</h3>
1360
- <ul>
1361
- <li><code>shipto</code>:
1362
- <ul>
1363
- <li><a href="#property_shipto">property</a>, <a href="#examples_using_address_filters">examples</a></li>
1364
- <li><a href="#formulas_variables_shipto">variables</a></li>
1365
- </ul>
1366
- </li>
1367
- <li><code>store</code>: <a href="#formulas_variables_store">variables</a></li>
1368
- <li><code>sum</code>: <a href="#formulas_special_functions">special functions</a></li>
1369
- <li><code>switch</code>: <a href="#formulas_special_functions">special functions</a>, <a href="#examples_special_switch">examples</a></li>
1370
- </ul>
1371
-
1372
- <h3>T</h3>
1373
- <ul>
1374
- <li><code>table</code>: <a href="#formulas_special_functions">special functions</a>, <a href="#examples_special_table">examples</a></li>
1375
- <li>title: see <code>label</code></li>
1376
- <li><code>tracking_url</code>: <a href="#property_tracking_url">property</a>, <a href="#more_tracking_url">more informations</a></li>
1377
- <li><code>type</code>: <a href="#property_type">property</a></li>
1378
- </ul>
1379
-
1380
- <h3>V</h3>
1381
- <ul>
1382
- <li>Variables: <a href="#formulas_variables">available</a>, <a href="#formulas_deprecated_variables">deprecated</a></li>
1383
- </ul>
1384
- </div>
1385
- </div>
1386
- </div>
1387
- </div>
1388
- <!-- doc content end -->
1389
- </div>
1390
- </div>
1391
  </div>
1392
  <script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
1393
  <script src="http://netdna.bootstrapcdn.com/bootstrap/3.0.0-rc1/js/bootstrap.min.js"></script>
1394
  <script>
1395
  <!-- doc scripts start -->
1396
  function jsonEncode(data, beautify, html, level, current_indent) {
1397
- if (typeof beautify == 'undefined') beautify = false;
1398
- if (typeof html == 'undefined') html = false;
1399
- if (typeof level == 'undefined') level = 0;
1400
- if (typeof current_indent == 'undefined') current_indent = '';
1401
-
1402
- var indent = html ? '&nbsp;&nbsp;&nbsp;' : "\t";
1403
- var line_break = html ? '<br/>' : "\n";
1404
- var new_indent = current_indent + indent;
1405
- switch (typeof(data)) {
1406
- case 'undefined':
1407
- return (html ? '<span class=json-reserved>' : '') + 'null' + (html ? '</span>' : '');
1408
- case 'boolean':
1409
- return (html ? '<span class=json-reserved>' : '') + (data ? 'true' : 'false') + (html ? '</span>' : '');
1410
- case 'number':
1411
- return (html ? '<span class=json-numeric>' : '') + data + (html ? '</span>' : '');
1412
- case 'string':
1413
- var output = JSON.stringify(data);
1414
- return html ? '<span class=json-string>' + output + '</span>' : output;
1415
- case 'object':
1416
- var output_index_count = 0;
1417
- var output = [];
1418
- for (var key in data) {
1419
- var value = data[key];
1420
- if (output_index_count!==null && output_index_count++!==key) {
1421
- output_index_count = null;
1422
- }
1423
- }
1424
- var is_associative = output_index_count===null;
1425
- for (var key in data) {
1426
- var value = data[key];
1427
- if (is_associative) {
1428
- var classes = [];
1429
- if (key=='about') classes.push('json-about');
1430
- if (key=='conditions' || key=='fees') classes.push('json-formula');
1431
- var property_classes = ['json-property'];
1432
- if (level==0) property_classes.push('json-id');
1433
- output.push(
1434
- (html && classes.length ? '<span class="' + classes.join(' ') + '">' : '')
1435
- + (html ? '<span' + (property_classes.length ? ' class="' + property_classes.join(' ') + '"' : '') + '>' : '')
1436
- + jsonEncode('' + key)
1437
- + (html ? '</span>' : '') + ':'
1438
- + (beautify ? ' ' : '')
1439
- + jsonEncode(value, beautify, html, level+1, new_indent)
1440
- + (html && classes.length ? '</span>' : '')
1441
- );
1442
- } else {
1443
- output.push(jsonEncode(value, beautify, html, level+1, current_indent));
1444
- }
1445
- }
1446
- if (is_associative) {
1447
- var classes = [];
1448
- if (data.type == 'meta') classes.push('json-meta');
1449
- output = (html && classes.length ? '<span class="' + classes.join(' ') + '">' : '')
1450
- + '{'
1451
- + (beautify ? line_break + new_indent : '')
1452
- + output.join(',' + (beautify ? line_break + new_indent : ''))
1453
- + (beautify ? line_break + current_indent : '')
1454
- + '}'
1455
- + (html && classes.length ? '</span>' : '');
1456
- return output;
1457
- } else {
1458
- return '[' + output.join(',' + (beautify ? ' ' : '')) + ']';
1459
- }
1460
- default:
1461
- return ''; // Not supported
1462
- }
1463
  }
1464
 
1465
  $(function(){
1466
- var navHeight = $('.navbar').outerHeight(true) + 10;
1467
-
1468
- $('a[href^="#"]').click(function (e) {
1469
- $('.highlight').removeClass('highlight');
1470
- var anchor = $(this).attr('href').replace('#', '');
1471
- window.location.hash = '#' + anchor;
1472
- var jelem = $('#' + anchor);
1473
- jelem.addClass('highlight');
1474
- $('body,html').scrollTop(Math.round(jelem.offset().top - navHeight + 10));
1475
- e.preventDefault()
1476
- });
1477
-
1478
- $('a[href^="#"]').each(function (e) {
1479
- var anchor = $(this).attr('href').replace('#', '');
1480
- if (anchor == '') return;
1481
- var jelem = $('#' + anchor);
1482
- if (!jelem.length) {
1483
- $(this).css('border', 'solid 1px red').css('padding', 3);
1484
- }
1485
- });
1486
-
1487
- var index = 0;
1488
- $('div.json').each(function(){
1489
- var text = $(this).text();
1490
- while (text.match(/"__auto__"/)) {
1491
- text = text.replace(/"__auto__"/, '"id_' + ('000' + index).slice(-3) + '"');
1492
- index++;
1493
- }
1494
- var obj = $.parseJSON(text);
1495
- var beautified = jsonEncode(obj, true, true);
1496
- $(this).html('<pre>' + beautified + '</pre>');
1497
- $(this).addClass('code');
1498
- });
1499
- $('body').scrollspy({
1500
- target: '.sidebar',
1501
- offset: navHeight
1502
- });
1503
 
1504
  });
1505
  <!-- doc scripts end -->
2
  <html>
3
  <head lang="fr">
4
  <meta charset="utf-8"/>
5
+ <title>Documentation of Owebia-Shipping 2.5.22 extension for Magento</title>
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
  <link href="http://netdna.bootstrapcdn.com/bootstrap/3.0.0-rc1/css/bootstrap.min.css" rel="stylesheet">
8
  <style>
39
  .sidebar .nav .nav {display: none; /* Hide by default, but at >768px, show it */margin-bottom: 8px;}
40
  .sidebar .nav .nav > li > a {padding-top:3px;padding-bottom:3px;padding-left:30px;font-size:90%;}
41
  @media screen and (min-width: 768px) {
42
+ .sidebar{display:block}
43
+ .sidebar .nav > .active > ul {display:block}
44
+ .bs-navbar-top-example .navbar-fixed-top,
45
+ .bs-navbar-bottom-example .navbar-fixed-bottom {position:absolute}
46
  }
47
  @media screen and (min-width: 992px) {
48
+ .sidebar.affix,
49
+ .sidebar.affix-bottom {width:213px}
50
+ .sidebar.affix {position:fixed;top:80px}
51
+ .sidebar.affix-bottom {position:absolute}
52
+ .sidebar.affix-bottom .sidenav,
53
+ .sidebar.affix .sidenav {margin-top:0;margin-bottom:0}
54
  }
55
  @media screen and (min-width: 1200px) {
56
+ .sidebar.affix-bottom,
57
+ .sidebar.affix {width:270px}
58
  }
59
  </style>
60
  </head>
61
  <body>
62
  <div class="navbar navbar-inverse navbar-fixed-top">
63
+ <div class="container">
64
+ <a href="http://www.owebia.com" class="navbar-brand">Owebia</a>
65
+ <ul class="nav navbar-nav">
66
+ </ul>
67
+ </div>
68
  </div>
69
  <div class="container">
70
+ <div class="row">
71
+ <div class="col-lg-3">
72
+ <div class="affix sidebar">
73
+ <!-- doc sidebar start -->
74
+ <ul class="nav sidenav">
75
+ <li><a href="#introduction">Introduction</a></li>
76
+ <li><a href="#examples">Examples</a>
77
+ <ul class="nav">
78
+ <li><a href="#examples_simple">Simple example: free shipping</a></li>
79
+ <li><a href="#examples_using_address_filters">Fees related to the destination</a></li>
80
+ <li><a href="#examples_using_customer_groups">Fees related to customer group</a></li>
81
+ <li><a href="#examples_using_formulas">Using formulas</a></li>
82
+ <li><a href="#examples_using_special_functions">Using special functions</a></li>
83
+ <li><a href="#examples_using_foreach">Using <code>{foreach …}</code> loops</a></li>
84
+ <li><a href="#examples_using_array_functions">Manipulate arrays</a></li>
85
+ <li><a href="#examples_more">Other examples</a></li>
86
+ </ul>
87
+ </li>
88
+ <li><a href="#definitions">Definitions</a>
89
+ <ul class="nav">
90
+ <li><a href="#definitions_element">Elements</a></li>
91
+ <li><a href="#definitions_property">Properties</a></li>
92
+ <li><a href="#definitions_unique_id">The unique identifier</a></li>
93
+ </ul>
94
+ </li>
95
+ <li><a href="#formulas">Formulas</a>
96
+ <ul class="nav">
97
+ <li><a href="#formulas_variables">Variables</a></li>
98
+ <li><a href="#formulas_functions">Functions</a></li>
99
+ <li><a href="#formulas_special_functions">Special functions</a></li>
100
+ <li><a href="#formulas_foreach"><code>foreach</code> loops</a></li>
101
+ <li><a href="#formulas_deprecated_variables">Deprecated variables</a></li>
102
+ </ul>
103
+ </li>
104
+ <li><a href="#more">Miscellaneous</a>
105
+ <ul class="nav">
106
+ <li><a href="#more_tracking_url">The tracking URL</a></li>
107
+ </ul>
108
+ </li>
109
+ <li><a href="#changelog">Changelog</a></li>
110
+ <li><a href="#index">Index</a></li>
111
+ </ul>
112
+ <!-- doc sidebar end -->
113
+ </div>
114
+ </div>
115
+ <div class="col-lg-9">
116
+ <!-- doc content start -->
117
+ <h1>Documentation of Owebia-Shipping 2.5.20 extension for Magento</h1>
118
+ <div id="introduction">
119
+ <h2>Introduction</h2>
120
+
121
+ <p>Owebia Shipping is an extension for the e-commerce solution <a href="http://www.magentocommerce.com/" target="_blank">Magento</a>.</p>
122
+ <p>Thanks to its syntax using <a href="http://fr.wikipedia.org/wiki/JavaScript_Object_Notation" target=_blank>JSON</a>, this extension allows great flexibility in setting delivery charges.</p>
123
+
124
+ <p>This documentation explains how to create a configuration for one of the proposed shipping modes.</p>
125
+
126
+ <p class="alert alert-info">New documentation, simpler and clearer.<br/>
127
+ <strong>Use the <a href="#index">index</a></strong> to find more easily something in the documentation.</p>
128
+ </div>
129
+
130
+ <div id="examples">
131
+ <h2>Examples</h2>
132
+
133
+ <div id="examples_simple">
134
+ <h3>Simple example: free shipping</h3>
135
+ <div class="json">{
136
+ "__auto__":{"label":"Free shipping","fees": 0}
137
+ }</div>
138
+ </div>
139
+
140
+ <div id="examples_using_address_filters">
141
+ <h3>Fees related to the destination</h3>
142
+ <div class="json">{
143
+ "__auto__":{"label":"France, Germany, Switzerland, Spain, Italy","shipto":"FR,DE,CH,ES,IT","fees":10},
144
+ "__auto__":{"label":"France except Corsica","shipto":"FR-(2A,2B)","fees":10},
145
+ "__auto__":{"label":"Corsica","shipto":"FR(2A,2B)","fees":10},
146
+ "__auto__":{"label":"Worldwide except Germany and Corsica","shipto":"* - ( DE, FR(2A,2B) )","fees":10}
147
+ }</div>
148
+
149
+ <h4>Use the wildcard character <code>*</code> or regular expressions</h4>
150
+ <div class="json">{
151
+ "__auto__":{"label":"Wildcard character allowing postal codes beginning with 25","shipto":"FR(25*)","fees":10},
152
+ "__auto__":{"label":"Regular expressions allowing postal codes beginning with 'PO', 'po', 'Po' or 'pO'","shipto":"GB(/^PO.*$/i)","fees":10}
153
+ }</div>
154
+
155
+ <div id="examples_excluding_domtom_postcode">
156
+ <h4>Block delivery to France but with a postal code for DOM/TOM</h4>
157
+ <p>With the following regular expression, you block the postal codes that starts with 97 or 98 (with or without interspersed zeros and spaces).</p>
158
+ <div class="json">{
159
+ "__auto__":{"label":"Regular Expression refusing postal codes beginning with 97 and 98","shipto":"FR-(/^[0\\s]*9\\s*[78].*/)","fees":10}
160
+ }</div>
161
+ </div>
162
+
163
+ <div id="examples_using_address_filters_shortcuts">
164
+ <h4>Using shortcuts <code>address_filter</code></h4>
165
+ <div class="json">{
166
+ "__auto__":{"label":"Europe except France","shipto":"({address_filter.EU-27}) - (FR)","fees":10}
167
+ }</div>
168
+ </div>
169
+ </div>
170
+
171
+ <div id="examples_using_customer_groups">
172
+ <h3>Fees related to customer group</h3>
173
+ <p>You can use the name or ID of the customer groups.</p>
174
+ <div class="json">{
175
+ "__auto__":{"label":"NOT LOGGED IN and General groups","customer_groups":"NOT LOGGED IN,General","fees":10},
176
+ "__auto__":{"label":"NOT LOGGED IN and General groups by their ID","customer_groups":"0,1","fees":10},
177
+ "__auto__":{"label":"Retailer group","customer_groups":"Retailer","fees":10}
178
+ }</div>
179
+ </div>
180
+
181
+ <div id="examples_using_formulas">
182
+ <h3>Using formulas</h3>
183
+ <p>Formulas can be used in properties <code>conditions</code> and <code>fees</code>.</p>
184
+ <div class="json">{
185
+ "__auto__":{"label":"Shipping","fees":"0.1 * {cart.price-tax+discount} + 10.00"}
186
+ }</div>
187
+
188
+ <h4>Copying the property of another element</h4>
189
+ <div class="json">{
190
+ "standard":{"label":"Standard Shipping","conditions":"{cart.price-tax+discount} < 1000.00","fees":10},
191
+ "express":{"label":"Express Shipping","conditions":"( {standard.conditions} ) && ( {cart.weight} < 10 )","fees":12}
192
+ }</div>
193
+
194
+ <h4>Using the function <code>min()</code></h4>
195
+ <div class="json">{
196
+ "__auto__":{"label":"Shipping","fees":"min({cart.weight}, {cart.price+tax+discount}, {cart.qty})"}
197
+ }</div>
198
+
199
+ <h4>Using the function <code>range()</code></h4>
200
+ <div class="json">{
201
+ "__auto__":{"label":"Shipping","conditions":"range({cart.weight}, 1.0, 3.0)","fees":10}
202
+ }</div>
203
+
204
+ <h4>Using the function <code>substr()</code></h4>
205
+ <p>A variable of type string must be surrounded by single quotes unless the auto-quoting is used with the characters <code>{{</code> and <code>}}</code>.</p>
206
+ <div class="json">{
207
+ "__auto__":{"label":"Without auto-quoting","conditions":"substr('{cart.coupon_code}', 0, 5)=='free_'","fees":10},
208
+ "__auto__":{"label":"With auto-quoting","conditions":"substr({{cart.coupon_code}}, 0, 5)=='free_'","fees":10}
209
+ }</div>
210
+
211
+ </div>
212
+
213
+ <div id="examples_using_special_functions">
214
+ <h3>Using special functions</h3>
215
+
216
+ <div id="examples_special_table">
217
+ <h4>Using the special function <code>{table … in …}</code></h4>
218
+ <div class="json">{
219
+ "__auto__":{"label":"Shipping","fees":"{table {cart.weight} in 0.5:5.30, 1.0:6.50, 2.0:7.40, 3.0:8.30, 5.0:10.10}"}
220
+ }</div>
221
+ <p>
222
+ In a <code>table</code>, you can include or exclude a limit value with the characters <code>[</code> and <code>]</code>:
223
+ </p>
224
+ <div class="json">{
225
+ "__auto__":{"label":"Upper limit included","fees":"{table {cart.weight} in 1.0]:5.00}"},
226
+ "__auto__":{"label":"Upper limit excluded","fees":"{table {cart.weight} in 1.0[:5.00}"}
227
+ }</div>
228
+
229
+ <p>
230
+ In a <code>table</code>, you must specify the reference value. To do this, you can use one of the <a href="#formulas_variables">variables</a> available.<br/>
231
+ You can also use a formula to define another reference value.
232
+ </p>
233
+
234
+ <div class="json">{
235
+ "__auto__":{"label":"Table with cart weight","fees":"{table {cart.weight} in 0.5:5.30, 1.0:6.50}"},
236
+ "__auto__":{"label":"Table with items quantity","fees":"{table {cart.qty} in 10:5.30, 20:6.50}"},
237
+ "__auto__":{"label":"Table with price including tax","fees":"{table {cart.price+tax+discount} in 15.00:5.30, 30.00:6.50, *:10.00}"},
238
+ "__auto__":{"label":"Table with price excluding tax","fees":"{table {cart.price-tax+discount} in 15.00:5.30, 30.00:6.50, *:10.00}"},
239
+ "__auto__":{"label":"Table with custom value","fees":"{table ceil({cart.weight}/10) in 1:5.30, 2:6.50}"}
240
+ }</div>
241
+ </div>
242
+
243
+ <div id="examples_special_switch">
244
+ <h4>Using the special function <code>{switch … in …}</code> (associative table)</h4>
245
+ <p>
246
+ In a <code>switch</code>, you must specify the reference value. To do this, you can use one of the <a href="#formulas_variables">variables</a> available.<br/>
247
+ You can also use a formula to define another reference value.
248
+ </p>
249
+ <div class="json">{
250
+ "__auto__":{"label":"Switch with coupon code","fees":"{switch {{cart.coupon_code}} in 'coupon1':5.30, 'coupon2':6.50, null:10.00, *:7.50}"},
251
+ "__auto__":{"label":"Switch with delivery country","fees":"{switch {{shipto.country_id}} in 'FR':5.30, 'BE':6.50, 'DE':10.00, *:7.50}"}
252
+ }</div>
253
+ </div>
254
+
255
+ <div id="examples_special_count">
256
+ <h4>Using the special function <code>{count …}</code></h4>
257
+ <div class="json">{
258
+ "__auto__":{"label":"If at least one product has the attribute 'color' equal to 'Bleu'","conditions":"{count items where product.attribute.color=='Bleu'} > 0","fees":10},
259
+ "__auto__":{"label":"If all items have the option 'size' greater or equal to '1'","conditions":"{count items where item.option.size>='1'} == {cart.qty}","fees":10}
260
+ }</div>
261
+
262
+ <p>
263
+ If the property is of type <strong>Yes/No</strong>, you must use the values <code>true</code>/<code>false</code> or <code>1</code>/<code>0</code> without quotes.
264
+ </p>
265
+ <div class="json">{
266
+ "__auto__":{"label":"Example of property of type Yes/No: 1","conditions":"{count items where product.attribute.colissimo_allowed==1}","fees":10},
267
+ "__auto__":{"label":"Example of property of type Yes/No: true","conditions":"{count items where product.attribute.colissimo_allowed==true}","fees":10}
268
+ }</div>
269
+ </div>
270
+
271
+ <div id="examples_special_count_distinct">
272
+ <h4>Using the special function <code>{count distinct …}</code></h4>
273
+ <div class="json">{
274
+ "__auto__":{"label":"Count of different SKU","conditions":"{count distinct product.attribute.sku}","fees":10}
275
+ }</div>
276
+ </div>
277
+
278
+ <div id="examples_special_sum">
279
+ <h4>Using the special function <code>{sum …}</code></h4>
280
+ <div class="json">{
281
+ "__auto__":{"label":"Sum of all options 'size' is greater than 30","conditions":"{sum item.option.size} > 30","fees":10}
282
+ }</div>
283
+ </div>
284
+
285
+ <div id="examples_special_min">
286
+ <h4>Using the special function <code>{min …}</code></h4>
287
+ <div class="json">{
288
+ "__auto__":{"label":"Minimum price excluding tax without discount is greater to 10","conditions":"{min item.price-tax-discount} > 10","fees":10}
289
+ }</div>
290
+ </div>
291
+
292
+ <div id="examples_special_max">
293
+ <h4>Using the special function <code>{max …}</code></h4>
294
+ <div class="json">{
295
+ "__auto__":{"label":"Maximum value of the option 'size' is lower than 50","conditions":"{max item.option.size} < 50","fees":10}
296
+ }</div>
297
+ </div>
298
+ </div>
299
+
300
+ <div id="examples_using_foreach">
301
+ <h3>Using <code>{foreach …}</code> loops</h3>
302
+ <div class="json">{
303
+ "__auto__":{"label":"Grouping products by origin and process groups seperately","fees":"{foreach product.attribute.code_origin}{table {selection.weight} in 0.0:0.00, 1.0:11.00, 3.0:12.00, 5.0:13.00}{/foreach}"},
304
+ "__auto__":{"label":" Calculate shipping fees by product","fees":"{foreach product.attribute.sku}{product.attribute.shipping}*{item.qty}{/foreach}"}
305
+ }</div>
306
+ </div>
307
+
308
+ <div id="examples_using_array_functions">
309
+ <h3>Manipulate arrays</h3>
310
+
311
+ <h4>Using the function <code>in_array()</code></h4>
312
+ <div class="json">{
313
+ "__auto__":{"label":"Shipping","conditions":"in_array({cart.qty}, array(10, 20, 30))","fees":10}
314
+ }</div>
315
+
316
+ <h4>Using the function <code>in_array()</code> avec des chaînes de caractères *</h4>
317
+ <div class="json">{
318
+ "__auto__":{"label":"Shipping","conditions":"in_array({{cart.coupon_code}}, array('free1', 'free2'))","fees":10}
319
+ }</div>
320
+
321
+ <h4>Using the function <code>array_match_any()</code></h4>
322
+ <div class="json">{
323
+ "__auto__":{"label":"Shipping","about":"5 x weight of products that are in category 2 or category 3","fees":"{sum product.weight where array_match_any(product.categories.id, array(2, 3))} * 5.0"}
324
+ }</div>
325
+
326
+ <h4>Using the function <code>array_match_all()</code></h4>
327
+ <div class="json">{
328
+ "__auto__":{"label":"Shipping","about":"5 x weight of products that are in both category 2 and category 3","fees":"{sum product.weight where array_match_all(product.categories.id, array(2, 3))} * 5.0"}
329
+ }</div>
330
+ </div>
331
+
332
+ <div id="examples_more">
333
+ <h3>Other examples</h3>
334
+
335
+ <div id="examples_product_categories">
336
+ <h4>Using product category</h4>
337
+ <p class="alert alert-danger">Warning: you must notice that in Magento, <strong>a product can be in multiple categories</strong>. So be particularly careful how you use this property.</p>
338
+ <div class="json">{
339
+ "__auto__":{"label":"Foreach loop with an iteration on the category","fees":"{foreach product.categories}{selection.weight}{/foreach}"},
340
+ "__auto__":{"label":"Using the category inside a foreach loop","fees":"{foreach product.sku}({{product.category}}=='Test' ? 2.00 : 1.00)*{item.qty}{/foreach}"},
341
+ "__auto__":{"label":"Using the id of the category inside a foreach loop","fees":"{foreach product.sku}({product.category.id}==12 ? 2.00 : 1.00)*{item.qty}{/foreach}"},
342
+ "__auto__":{"about":"The function in_array() is used because product.categories returns an array","label":"Sum of weight attributes of products in category 'Test' ","fees":"{sum product.weight where in_array('Test', product.categories)}"},
343
+ "__auto__":{"about":"The function in_array() is used because product.categories.id returns an array","label":"Sum of weight attributes of products in category 12 ","fees":"{sum product.weight where in_array(12, product.categories.id)}"},
344
+ "__auto__":{"about":"The function array_match_any() is used because product.categories.id returns an array","label":"Sum of weight attributes of products in categories whose id is 11 and 12","fees":"{sum product.weight where array_match_any(product.categories.id, array(11, 12))}"},
345
+ "__auto__":{"label":"Sum of weights of products having for first category 'Test'","fees":"{sum product.weight where product.category=='Test'}"},
346
+ "__auto__":{"label":"Sum of weights of products having for first category id 12","fees":"{sum product.weight where product.category.id==12}"}
347
+ }</div>
348
+ </div>
349
+
350
+ <div id="examples_data">
351
+ <h4>Adding and using a <code>data</code> element</h4>
352
+ <p>An element of type <code>data</code> allow to define data that can be used in shipping methods.</p>
353
+ <div class="json">{
354
+ "mydata":{"type":"data","var1":"12"},
355
+ "__auto__":{"label":"Shipping","shipto":"FR","fees": "{mydata.var1}"},
356
+ "__auto__":{"label":"Shipping","shipto":"DE","fees": "{mydata.var1}*1.5"}
357
+ }</div>
358
+ </div>
359
+
360
+ <div id="examples_meta">
361
+ <h4>Adding a <code>meta</code> element</h4>
362
+ <p>An element of type <code>meta</code> allow to specify informative data (author, date…).</p>
363
+ <div class="json">{
364
+ "about":{"type":"meta","author":"Owebia","date":"15/07/2013","about":"2013 rates"}
365
+ }</div>
366
+ </div>
367
+ </div>
368
+ </div>
369
+
370
+ <div id="definitions">
371
+ <h2>Definitions</h2>
372
+ <p>
373
+ The configuration of a shipping mode is a JSON object containing <strong><a href="#definitions_property">properties</a></strong>.<br/>
374
+ Each property has a unique name, wich will serve as <a href="#definitions_unique_id">unique identifier</a>.<br/>
375
+ Each property will consiste on a configuration <strong><a href="#definitions_element">element</a></strong> (also a JSON object).<br/>
376
+ </p>
377
+ <div id="definitions_element">
378
+ <h3>Elements</h3>
379
+
380
+ <p>
381
+ There are three different types of configuration <strong>element</strong>:
382
+ </p>
383
+ <ul>
384
+ <li><code>method</code>: shipping method (default if not specified)</li>
385
+ <li><code>data</code>: data that can be used in one or more shipping methods (<a href="#examples_data">examples</a>)</li>
386
+ <li><code>meta</code>: informative data (<a href="#examples_meta">examples</a>)</li>
387
+ </ul>
388
+ </div>
389
+
390
+ <div id="definitions_property">
391
+ <h3>Properties</h3>
392
+
393
+ <p>
394
+ Each element has several <strong>properties</strong>:
395
+ </p>
396
+ <ul>
397
+ <li id="property_about"><code>about</code>: comment about the element</li>
398
+ <li id="property_type"><code>type</code>: element type (<code>method</code>, <code>meta</code> or <code>data</code>)</li>
399
+ </ul>
400
+
401
+ <p>
402
+ Properties specific to the element type <code>method</code>:
403
+ </p>
404
+ <ul>
405
+ <li id="property_label"><code>label</code>: name of shipping method</li>
406
+ <li id="property_description"><code>description</code> (visible only if the template displays it)</li>
407
+ <li id="property_enabled"><code>enabled</code>: shipping method enabled or not</li>
408
+ <li id="property_fees"><code>fees</code>: shipping fees</li>
409
+ <li id="property_conditions"><code>conditions</code>: activation conditions</li>
410
+ <li id="property_shipto"><code>shipto</code>: countries (regions, postal codes) allowed for delivery</li>
411
+ <li id="property_billto"><code>billto</code>: countries (regions, postal codes) allowed for billing</li>
412
+ <li id="property_origin"><code>origin</code>: countries (regions, postal codes) allowed for origin</li>
413
+ <li id="property_customer_groups"><code>customer_groups</code>: customer groups allowed</li>
414
+ <li id="property_tracking_url"><code>tracking_url</code> (<a href="#more_tracking_url">more informations</a>)</li>
415
+ </ul>
416
+
417
+ <p><a href="#examples">See examples</a></p>
418
+
419
+ <h4>Using properties of type address (<code>shipto</code>, <code>billto</code> and <code>origin</code>)</h4>
420
+ <p>
421
+ The country codes used are those of Magento (apparently they are the same as the <a href="http://fr.wikipedia.org/wiki/ISO_3166-1" target=_blank>ISO 3166-1 alpha-2 codes</a>).<br/>
422
+ It is possible to specify region codes (only with <code>shipto</code>) or zip codes that you want to filter or exclude.
423
+ </p>
424
+ <p class=new>
425
+ You can use the <strong>wildcard</strong> character <code>*</code> or <strong>regular expressions</strong> for postal codes.<br/>
426
+ A regular expression must start and end with the character <code>/</code>. If you want to use the characters <code>(</code>, <code>)</code> or <code>.</code>, you must escape them with the character <code>\</code> (ex: <code><span class=string>"FR(/^25\([0-9]{3}\)$/)"</span></code>).<br/>
427
+ You can use the insensitivity modifier (ex: <code><span class=string>"GB(/^PO.*$/i)"</span></code>).
428
+ </p>
429
+
430
+ <p><a href="#examples_using_address_filters">See examples</a></p>
431
+
432
+ <div id="address_filter" class="alert alert-info">
433
+ <p><strong>Tip</strong><br/>To shorten the seizure of countries, you can use the following variables:</p>
434
+ <ul>
435
+ <li><code>{address_filter.AF}</code>: African countries</li>
436
+ <li><code>{address_filter.AS}</code>: Asian countries</li>
437
+ <li><code>{address_filter.EU}</code>: European countries</li>
438
+ <li><code>{address_filter.NA}</code>: North American countries</li>
439
+ <li><code>{address_filter.SA}</code>: South American countries</li>
440
+ <li><code>{address_filter.OC}</code>: Oceanian countries</li>
441
+ <li><code>{address_filter.AN}</code>: countries of Antarctica</li>
442
+ <li><code>{address_filter.EU-27}</code>: countries of the European Union</li>
443
+ <li><code>{address_filter.DOM}</code>: country codes of French Overseas "Départements"</li>
444
+ <li><code>{address_filter.COM}</code>: country codes of French Overseas "Collectivités"</li>
445
+ </ul>
446
+ <p><a href="#examples_using_address_filters_shortcuts">See examples</a></p>
447
+ </div>
448
+ </div>
449
+
450
+ <div id="definitions_unique_id">
451
+ <h3>The unique identifier</h3>
452
+
453
+ <p>Each configuration element has a <strong>unique identifier</strong>. This identifier can be used to refer to the element.</p>
454
+ <p>Example:</p>
455
+ <div class="json">{
456
+ "europa":{"label":"Shipping to Europa","fees":10},
457
+ "us":{"label":"Shipping to US","fees":"{europa.fees}+20"}
458
+ }</div>
459
+
460
+ <p class="alert alert-danger"><strong><u>Warning</u>:</strong> to avoid conflicts, use only the characters <code>a-z</code>, <code>A-Z</code>, <code>0-9</code>, <code>-</code> and <code>_</code> for the unique identifier.<br/>You should also avoid identifiers that already correspond to variable names (<code>cart</code>, <code>product</code>, <code>item</code>…).</p>
461
+ </div>
462
+ </div>
463
+
464
+ <div id="formulas">
465
+ <h2>Formulas</h2>
466
+ <p>
467
+ The properties <code>fees</code> and <code>conditions</code> are defined using formulas.<br/>
468
+ </p>
469
+ <p>
470
+ A formula uses <a href="#formulas_variables">variables</a>, <a href="#formulas_functions">functions</a>, <a href="#formulas_special_functions">special functions</a> and mathematical operators.
471
+ </p>
472
+ <p>
473
+ Available mathematical operators:
474
+ </p>
475
+ <ul>
476
+ <li>operators: <code>*</code>, <code>/</code>, <code>+</code> and <code>-</code></li>
477
+ <li>modulo: <code>%</code></li>
478
+ <li>parentheses: <code>(</code> and <code>)</code></li>
479
+ <li>boolean operators <code>&amp;&amp;</code>, <code>and</code>, <code>||</code>, <code>or</code>, <code>==</code>, <code>&lt;</code>, <code>&gt;</code>, <code>&lt;=</code>, <code>&gt;=</code></li>
480
+ <li>binary operators <code>&amp;</code> and <code>|</code></li>
481
+ <li>the operator group <code>C ? X : Y</code> (ex: <code><span class=string>"{cart.price_exluding_tax}&gt;100 ? 15*{cart.weight} : 20*{cart.weight}"</span></code>)</li>
482
+ </ul>
483
+ <p>
484
+ You can put spaces and line breaks in formulas (for lightening).
485
+ </p>
486
+ <p>
487
+ You can use the following advanced features: casting to interger <code>(int)</code> or floatting numbers <code>(float)</code>,
488
+ comparison with the <code>null</code> value or with boolean values <code>true</code> and <code>false</code>.
489
+ </p>
490
+
491
+ <div id="formulas_variables">
492
+ <h3>Variables</h3>
493
+
494
+ <p class="alert alert-info">
495
+ When you use variables of type string, you must escape them with single quotes or use the auto-quoting syntax <code>{{ }}</code>.
496
+ </p>
497
+
498
+ <p>
499
+ The following variables can be used in <a href="#formulas">formulas</a>.
500
+ </p>
501
+ <ul>
502
+ <li id="formulas_variables_cart">The cart:
503
+ <ul>
504
+ <li><code>{cart.weight}</code>: weight of goods</li>
505
+ <li><code>{cart.qty}</code>: the quantity of items</li>
506
+ <li><code>{cart.price-tax+discount}</code>: price excluding tax with discount</li>
507
+ <li><code>{cart.price+tax+discount}</code>: price including tax with discount</li>
508
+ <li><code>{cart.price-tax-discount}</code>: price excluding tax without discount</li>
509
+ <li><code>{cart.price+tax-discount}</code>: price including tax without discount</li>
510
+ <li><code>{cart.coupon_code}</code>: coupon code</li>
511
+ <li><code>{cart.free_shipping}</code>: delivery offered (by rules in Magento) [true/false]</li>
512
+ <li><code>{cart.weight_unit}</code></li>
513
+ <li><code>{cart.weight_for_charge}</code>: weight of goods whose delivery is not offered (by cart pricing rules in Magento)</li>
514
+ </ul>
515
+ </li>
516
+ <li id="formulas_variables_quote">The quote:
517
+ <ul>
518
+ <li><code>{quote.subtotal}</code>: subtotal (excluding tax)</li>
519
+ <li><code>{quote.subtotal_with_discount}</code>: subtotal (excluding tax) with discount</li>
520
+ <li><code>{quote.grand_total}</code>: total (including tax) with discount</li>
521
+ <li><code>{quote.base_subtotal}</code>: subtotal (excluding tax) in base currency</li>
522
+ <li><code>{quote.base_subtotal_with_discount}</code>: subtotal (excluding tax) with discount in base currency</li>
523
+ <li><code>{quote.base_grand_total}</code>: total (including tax) with discount in base currency</li>
524
+ </ul>
525
+ </li>
526
+ <li id="formulas_variables_customer_group">The customer group:
527
+ <ul>
528
+ <li><code>{customer_group.id}</code>: id of customer group</li>
529
+ <li><code>{customer_group.code}</code>: name of customer group</li>
530
+ <li><code>{customer_group.*}</code>: property of the customer group (ex: <code>{customer_group.tax_class_id}</code>)</li>
531
+ </ul>
532
+ </li>
533
+ <li id="formulas_variables_customer">The customer:
534
+ <ul>
535
+ <li><code>{customer.id}</code>: id of customer</li>
536
+ <li><code>{customer.attribute.*}</code>: attribute of the customer (ex: lastname, firstname, group_id…)</li>
537
+ <li><code>{customer.attribute.*.value}</code>: in case of an attribute of type selection list, <code>{customer.attribute.*}</code> returns the id, to get the value, you have to use <code>{customer.attribute.*.value}</code></li>
538
+ <li><code>{customer.*}</code>: same as <code>{customer.attribute.*}</code>, unless the variable is already defined (ex: <code>{customer.id}</code> is already defined)</li>
539
+ </ul>
540
+ </li>
541
+ <li id="formulas_variables_customvar">Custom Variables (since Magento 1.4.0.1):
542
+ <ul>
543
+ <li><code>{customvar.*}</code>: custome variable defined in Magento (ex: <code>{customvar.my_var}</code>)</li>
544
+ </ul>
545
+ </li>
546
+ <li id="formulas_variables_shipto">The delivery address:
547
+ <ul>
548
+ <li><code>{shipto.country_name}</code></li>
549
+ <li><code>{shipto.country_id}</code>: the country code</li>
550
+ <li><code>{shipto.region_id}</code></li>
551
+ <li><code>{shipto.region_code}</code></li>
552
+ <li><code>{shipto.street}</code></li>
553
+ <li><code>{shipto.city}</code></li>
554
+ <li><code>{shipto.postcode}</code></li>
555
+ </ul>
556
+ </li>
557
+ <li id="formulas_variables_billto">The billing address:
558
+ <ul>
559
+ <li><code>{billto.country_name}</code></li>
560
+ <li><code>{billto.country_id}</code>: the country code</li>
561
+ <li><code>{billto.postcode}</code></li>
562
+ <li><code>{billto.*}</code>: property of the billing address (ex: <code>{billto.city}</code>)</li>
563
+ </ul>
564
+ </li>
565
+ <li id="formulas_variables_origin">The origin address:
566
+ <ul>
567
+ <li><code>{origin.country_name}</code></li>
568
+ <li><code>{origin.country_id}</code>: the country code</li>
569
+ <li><code>{origin.region_id}</code></li>
570
+ <li><code>{origin.city}</code></li>
571
+ <li><code>{origin.postcode}</code></li>
572
+ </ul>
573
+ </li>
574
+ <li id="formulas_variables_store">The store:
575
+ <ul>
576
+ <li><code>{store.id}</code> <code>{store.code}</code> <code>{store.name}</code> <code>{store.address}</code> <code>{store.phone}</code></li>
577
+ </ul>
578
+ </li>
579
+ <li id="formulas_variables_date">The current date:
580
+ <ul>
581
+ <li><code>{date.timestamp}</code>: UNIX timestamp of the current date</li>
582
+ <li><code>{date.year}</code> <code>{date.month}</code> <code>{date.day}</code> <code>{date.hour}</code> <code>{date.minute}</code> <code>{date.second}</code></li>
583
+ <li><code>{date.weekday}</code>: day of the week for the current date from 0 (Sunday) to 6 (Saturday)</li>
584
+ </ul>
585
+ </li>
586
+ <li id="formulas_variables_request">The <code>request</code> object:
587
+ <ul>
588
+ <li><code>{request.*}</code>: property of the request object (Mage_Shipping_Model_Rate_Request) given by Magento (ex: <code>{request.package_qty}</code>). Use "Debug" option to get more details on available properties.</li>
589
+ </ul>
590
+ </li>
591
+ </ul>
592
+
593
+ <div id="formulas_variables_for_special_functions">
594
+ <h4>Variables that can be used in special functions</h4>
595
+
596
+ <p>The following variables can be used in <a href="#formulas_special_functions">special functions</a>.</p>
597
+
598
+ <p class="alert alert-danger">Unlike elsewhere, the following variables should not be surrounded by the characters <code>{</code> and <code>}</code>.</p>
599
+
600
+ <p>
601
+ An <code>item</code> is a variation of a <code>product</code> to which some options have been added. Each <code>item</code> has a quantity.
602
+ </p>
603
+ <ul>
604
+ <li id="formulas_variables_item">The <code>item</code>:
605
+ <ul>
606
+ <li><code>item.qty</code>: quantity in the cart</li>
607
+ <li><code>item.price-tax+discount</code>: price excluding tax with discount</li>
608
+ <li><code>item.price-tax-discount</code>: price excluding tax without discount</li>
609
+ <li><code>item.price+tax+discount</code>: price including tax with discount</li>
610
+ <li><code>item.price+tax-discount</code>: price including tax without discount</li>
611
+ <li><code>item.option.*</code>: option (the available options depend on the product)</li>
612
+ </ul>
613
+ </li>
614
+ <li id="formulas_variables_product">The <code>product</code>:
615
+ <ul>
616
+ <li><code>product.attribute.*</code><br/>
617
+ Interesting attributes:
618
+ <ul>
619
+ <li><code>sku</code></li>
620
+ <li><code>name</code></li>
621
+ <li><code>weight</code></li>
622
+ <li><code>price</code> (as defined in Magento backoffice)</li>
623
+ <li><code>special_price</code>: (as defined in Magento backoffice)</li>
624
+ <li>…</li>
625
+ </ul>
626
+ </li>
627
+ <li><code>product.attribute.*.value</code>: value of the attribute<br/>
628
+ In case of an attribute of type selection list, <code>product.attribute.*</code> returns the id. To get the value, you have to use <code>product.attribute.*.value</code></li>
629
+ <li><code>product.*</code>: same as <code>product.attribute.*</code> unless the variable is already defined (ex: <code>product.category</code>)</li>
630
+ <li>First category of the product:
631
+ <ul>
632
+ <li><code>product.category</code>: name of the category</li>
633
+ <li><code>product.category.id</code></li>
634
+ <li><code>product.category.*</code>: attribute of the category (ex: <code>product.category.is_active</code>)<br/>
635
+ Interesting attributes:
636
+ <ul>
637
+ <li><code>is_active</code></li>
638
+ <li><code>name</code></li>
639
+ <li>…</li>
640
+ </ul>
641
+ </li>
642
+ </ul>
643
+ </li>
644
+ <li>All product categories (returns an array, <a href="#examples_product_categories">examples</a>):
645
+ <ul>
646
+ <li><code>product.categories</code>: array of name of the categories</li>
647
+ <li><code>product.categories.id</code>: array of id of the categories</li>
648
+ </ul>
649
+ </li>
650
+ <li>The attribute set:
651
+ <ul>
652
+ <li><code>product.attribute_set</code>: name of the attribute set</li>
653
+ <li><code>product.attribute_set.id</code></li>
654
+ <li><code>product.attribute_set.*</code>: attribute of the attribute set (ex: <code>product.attribute_set.attribute_set_name</code>)</li>
655
+ </ul>
656
+ </li>
657
+ <li><code>product.stock.*</code>: attribute of the product stock<br/>
658
+ Interesting attributes:
659
+ <ul>
660
+ <li><code>is_in_stock</code></li>
661
+ <li><code>qty</code>: quantity in stock</li>
662
+ <li>…</li>
663
+ </ul>
664
+ </li>
665
+ </ul>
666
+ </li>
667
+ </ul>
668
+ </div>
669
+
670
+ <div id="formulas_variables_for_foreach">
671
+ <h4>Variables that can be used in <code>foreach</code> loops</h4>
672
+
673
+ <p>The following variables can be used in <a href="#formulas_foreach"><code>foreach</code> loops</a>.</p>
674
+
675
+ <ul>
676
+ <li><code>{selection.weight}</code></li>
677
+ <li><code>{selection.qty}</code>: items count in the selection</li>
678
+ </ul>
679
+ <p>
680
+ When the selection is made on the sku, each selection consists of a single article.
681
+ We can therefore use the <a href="#formulas_variables_for_special_functions">item and product variables</a>.
682
+ </p>
683
+ <ul>
684
+ <li><code>{item.*}</code>: item property</li>
685
+ <li><code>{product.*}</code>: product property</li>
686
+ </ul>
687
+ <p class="alert alert-info">
688
+ Item and product variables are identical to <a href="#formulas_variables_for_special_functions">variables that can be used in special functions</a> with the only difference that they must be surrounded by the characters <code>{</code> and <code>}</code>.
689
+ </p>
690
+ </div>
691
+ </div>
692
+
693
+ <div id="formulas_functions">
694
+ <h3>Functions</h3>
695
+
696
+ <h4>Numerical functions</h4>
697
+ <ul>
698
+ <li><code>abs(x)</code>: absolute value</li>
699
+ <li><code>ceil(x)</code>: round up</li>
700
+ <li><code>exp(x)</code>: exponent</li>
701
+ <li><code>floor(x)</code>: round down</li>
702
+ <li><code>log(x)</code>: logarithm</li>
703
+ <li><code>log(x, base)</code>: natural logarithm</li>
704
+ <li><code>max(x, y, …)</code>: maximum, null values ignored</li>
705
+ <li><code>min(x, y, …)</code>: minimum, null values ignored</li>
706
+ <li><code>pi()</code>: PI number</li>
707
+ <li><code>pow(x, puissance)</code>: pow</li>
708
+ <li><code>rand(min, max)</code>: random integer</li>
709
+ <li><code>round(x)</code></li>
710
+ <li><code>sqrt(x)</code>: square root</li>
711
+ </ul>
712
+
713
+ <h4>Functions to manipulate strings</h4>
714
+ <ul>
715
+ <li><code>substr(string, start, length)</code>: returns a string segment.</li>
716
+ </ul>
717
+
718
+ <h4>Functions to manipulate arrays</h4>
719
+ <ul>
720
+ <li><code>in_array(value, array(value1, value2, …))</code>: returns true if the value is found in the array.</li>
721
+ <li><code>array_match_any(array(value1, value2, …), array(value1, value2, …))</code>: returns true if at least one value is found in both arrays.</li>
722
+ <li><code>array_match_all(array(value1, value2, …), array(value1, value2, …))</code>: returns true if both arrays are identical.</li>
723
+ </ul>
724
+
725
+ <h4>More functions</h4>
726
+ <ul>
727
+ <li><code>range(value, min, max, include_min, include_max)</code>: returns true if <code>value</code> is greater than <code>min</code> and lower than <code>max</code>. By default, <code>include_min</code> and <code>include_max</code> are equal to <code>true</code>.</li>
728
+ </ul>
729
+ </div>
730
+
731
+ <div id="formulas_special_functions">
732
+ <h3>Special functions</h3>
733
+
734
+ <ul>
735
+ <li><code>{table … in …}</code>: defining values based on thresholds (<a href="#examples_special_table">examples</a>)</li>
736
+ <li><code>{switch … in …}</code>: defining an associative table (<a href="#examples_special_switch">examples</a>)</li>
737
+ </ul>
738
+ <p>
739
+ The first parameter <code>…</code> of <code>table</code> and <code>switch</code> functions is the reference value, it can be either a variable or a formula.
740
+ </p>
741
+ <ul>
742
+ <li><code>{count items[ where …]}</code>: counts eligible items (<a href="#examples_special_count">examples</a>)</li>
743
+ <li><code>{count distinct …[ where …]}</code>: counts all different values of a property for eligible items (<a href="#examples_special_count_distinct">examples</a>)</li>
744
+ <li><code>{sum …[ where …]}</code>: calculates the sum of the values of a property for eligible items (<a href="#examples_special_sum">examples</a>)</li>
745
+ <li><code>{min …[ where …]}</code>: returns the minimum value of a property for eligible items (<a href="#examples_special_min">examples</a>)</li>
746
+ <li><code>{max …[ where …]}</code>: returns the maximum value of a property for eligible items (<a href="#examples_special_max">examples</a>)</li>
747
+ </ul>
748
+ <p>
749
+ The first parameter <code>…</code> of <code>count distinct</code>, <code>sum</code>, <code>min</code> and <code>max</code> functions must be a property (ex: <code>product.attribute.weight</code>).
750
+ </p>
751
+ <p>The condition <code>where</code> is optional. If specified, it will be in the form of a formula.</p>
752
+ </div>
753
+
754
+ <div id="formulas_foreach">
755
+ <h3>Using <code>foreach</code> loops</h3>
756
+
757
+ <p>
758
+ <code>foreach</code> loops can perform a calculation on groups of products rather than consider all the products in the cart. <br/>
759
+ The overall result of a <code>foreach</code> loop is the sum of the results of each pass through the loop.
760
+ </p>
761
+ <p>
762
+ Inside a <code>foreach</code> loop, you can use <a href="#formulas_variables_for_foreach">new variables</a>.
763
+ </p>
764
+ <p>
765
+ <a href="#examples_using_foreach">Examples</a>
766
+ </p>
767
+ </div>
768
+
769
+ <div id="formulas_deprecated_variables">
770
+ <h3>Deprecated variables</h3>
771
+
772
+ <p>The following variables must be replaced by their equivalent.</p>
773
+
774
+ <ul>
775
+ <li><a href="#formulas_variables"><code><span class=strike>{cart.coupon}</span> {cart.coupon_code}</code></a></li>
776
+ <li><a href="#formulas_variables"><code><span class=strike>{cart.quantity}</span> {cart.qty}</code></a></li>
777
+ <li><a href="#formulas_variables"><code><span class=strike>{cart.price_excluding_tax}</span> {cart.price-tax+discount}</code></a></li>
778
+ <li><a href="#formulas_variables"><code><span class=strike>{cart.price_including_tax}</span> {cart.price+tax+discount}</code></a></li>
779
+ <li><a href="#formulas_variables"><code><span class=strike>{cart.weight.for-charge}</span> {cart.weight_for_charge}</code></a></li>
780
+ <li><a href="#formulas_variables"><code><span class=strike>{cart.weight.unit}</span> {cart.weight_unit}</code></a></li>
781
+ <li><a href="#formulas_variables"><code><span class=strike>{customer.group.code}</span> {customer_group.code}</code></a></li>
782
+ <li><a href="#formulas_variables"><code><span class=strike>{customer.group.id}</span> {customer_group.id}</code></a></li>
783
+ <li><a href="#formulas_variables"><code><span class=strike>{{customVar code=*}}</span> {customvar.*}</code></a></li>
784
+ <li><a href="#formulas_variables"><code><span class=strike>{destination.country.code}</span> {shipto.country_id}</code></a></li>
785
+ <li><a href="#formulas_variables"><code><span class=strike>{destination.country.name}</span> {shipto.country_name}</code></a></li>
786
+ <li><a href="#formulas_variables"><code><span class=strike>{destination.postcode}</span> {shipto.postcode}</code></a></li>
787
+ <li><a href="#formulas_variables"><code><span class=strike>{destination.region.code}</span> {shipto.region_code}</code></a></li>
788
+ <li><a href="#formulas_variables"><code><span class=strike>{free_shipping}</span> {cart.free_shipping}</code></a></li>
789
+ <li><a href="#formulas_variables"><code><span class=strike>{origin.country.code}</span> {origin.country_id}</code></a></li>
790
+ <li><a href="#formulas_variables"><code><span class=strike>{origin.country.name}</span> {origin.country_name}</code></a></li>
791
+ <li><a href="#formulas_variables"><code><span class=strike>{origin.region.code}</span> {origin.region_id}</code></a></li>
792
+ <li><a href="#formulas_variables_for_foreach"><code><span class=strike>{selection.quantity}</span> {selection.qty}</code></a></li>
793
+ </ul>
794
+ <ul>
795
+ <li><a href="#formulas_variables_for_special_functions"><code><span class=strike>product.quantity</span> item.qty</code></a></li>
796
+ <li><a href="#formulas_variables_for_special_functions"><code><span class=strike>product.price-tax+discount</span> item.price-tax+discount</code></a></li>
797
+ <li><a href="#formulas_variables_for_special_functions"><code><span class=strike>product.price-tax-discount</span> item.price-tax-discount</code></a></li>
798
+ <li><a href="#formulas_variables_for_special_functions"><code><span class=strike>product.price+tax+discount</span> item.price+tax+discount</code></a></li>
799
+ <li><a href="#formulas_variables_for_special_functions"><code><span class=strike>product.price+tax-discount</span> item.price+tax-discount</code></a></li>
800
+ <li><a href="#formulas_variables_for_special_functions"><code><span class=strike>product.option.*</span> item.option.*</code></a></li>
801
+ <li><a href="#formulas_variables_for_special_functions"><code><span class=strike>product.option.*</span> item.option.*</code></a></li>
802
+ </ul>
803
+ </div>
804
+ </div>
805
+
806
+ <div id="more">
807
+ <h2>Miscellaneous</h2>
808
+
809
+ <div id="more_tracking_url">
810
+ <h3>The tracking URL</h3>
811
+
812
+ <p class="alert alert-danger">
813
+ The use of <code>tracking_url</code> property is reserved for experienced users. If you don't understand the instructions below, it is recommended that you avoid using this feature.
814
+ </p>
815
+ <p>
816
+ The <code>tracking_url</code> property overrides the field "Tracking URL" of an Owebia Shipping shipping mode. So you can specify a tracking URL <strong>foreach shipping method</strong> rather than one for all shipping mode.
817
+ </p>
818
+ <p>
819
+ To automatically insert the tracking number in the tracking URL, you must use <code>{tracking_number}</code>.
820
+ </p>
821
+
822
+ <div class="json">{
823
+ "__auto__":{"label":"Example of tracking URL for the carrier Colissimo","fees":10,"tracking_url":"http://www.coliposte.net/particulier/suivi_particulier.jsp?colispart={tracking_number}"}
824
+ }</div>
825
+
826
+ <p>
827
+ Magento does not support tracking links but tracking statuses. The extension Owebia Shipping 2 provides an HTML link instead of the status, link allowing you to go on the carrier's website and follow the progress of the parcel.
828
+ </p>
829
+ <p>
830
+ When the tracking URL is built by the extension, the only information available is the tracking number and there was nowhere an access to the shipping method selected. In order to find the tracking URL in the configuration, you must specify the shipping method inside the tracking number, for example: <code>colissimo:8Lxxxxxxxxxxx</code> where <code>colissimo</code> is the code of the shipping method selected.<br/>
831
+ If no code is specified (if you enter only the tracking number), the URL used will be the one of the shipping mode.
832
+ </p>
833
+ <p class="alert alert-danger">
834
+ To answer a recurrent question, Magento displays the tracking status from the back office or front office. If you want to insert the tracking URL in shipping mails, <strong>you need to develop yourself</strong> the retrieval of tracking URL and its incorporation in the mail, in fact, the Owebia Shipping extension simply provides customizable shipping methods without making big changes to Magento core to reduce incompatibility and update problems.
835
+ </p>
836
+ <p class="alert alert-danger">
837
+ If you get a blank popup when you click on the tracking link, your problem is most likely related to the fact that you did not specify the code of the shipping method in the tracking number (see instructions above) and your global field "Tracking URL" is empty.
838
+ </p>
839
+ <p class="alert alert-danger">There are currently no plans to change this feature.</p>
840
+ </div>
841
+ </div>
842
+
843
+ <div id="changelog">
844
+ <h2>Changelog</h2>
845
+
846
+ <pre class=changelog>
847
+ [2.5.22 - July 18, 2016]
848
+ Add composer.json and modman files
849
+
850
+ [2.5.21 - May 9, 2016]
851
+ Fix replacement of special functions, thanks to Sébastien L.
852
+
853
+ [2.5.20 - 25 avril 2016]
854
+ Fix code indentation
855
+ Fix version number
856
+ Add readme file in package
857
+
858
+ [2.5.19 - 09 novembre 2015]
859
+ Note: the extension is not affected by the patch SUPEE-6788 since it uses the new admin url routing syntax for 3 years (version 2.4.8.0)
860
+ Fix bug: deactivation of auto-escaping by default since it can cause some bugs (ex: impossible to use {address_filter.EU-27} in shipto)
861
+ Fix bug: fix auto-escaping of properties like {{shipto.country_name}}
862
+ Fix bug: variable replacements in labels (variables {cart.price-tax-discount}, {cart.price-tax+discount}, {cart.price+tax-discount} and {cart.price+tax+discount})
863
+ Fix bug: use items and not quote to retrieve values {cart.price-tax-discount}, {cart.price-tax+discount}, {cart.price+tax-discount} and {cart.price+tax+discount} (quote totals are not available at this time, calculating them causes duplications of addresses and a false grand_total value)
864
+ Fix bug: retrieve customer in backoffice order
865
+ Fix unicode accented chars in json_encode for PHP &lt; 5.4
866
+ Fix bug: usage of regular expressions inside {count ...}, {sum ...}, {min ...} and {max ...}
867
+ Allow usage of php functions date and strtotime (ex: "label": "'Your package will be delivered between ' . date('d/m', strtotime('+5 days')) . ' and ' . date('d/m Y', strtotime('+7 days'))",
868
+
869
  [2.5.18 - 24 juillet 2014]
870
  Pas de modification, nouvelle version pour Magento Connect
871
 
956
  Modification de la syntaxe de la configuration pour la rendre 100% compatible JSON
957
  Refonte complète de l'éditeur
958
  Suppression de la compatibilité avec les propriétés dépréciées suivantes :
959
+ 'fees_table', 'fees_formula', 'fixed_fees', 'reference_value', 'prices_range', 'weights_range', 'product_properties',
960
+ 'free_shipping__fees_table', 'free_shipping__fees_formula', 'free_shipping__fixed_fees', 'free_shipping__label',
961
  Suppression de la compatibilité avec la désactivation d'une méthode de livraison à l'aide du caractère #
962
  Suppression de la compatibilité avec les mots réservés en majuscule : TABLE, SUM, COUNT, DISTINCT et IN
963
  Ajout des fonctions array_match_any et array_match_all
982
  Correction d'un bug dans l'utilisation de la fonction {table ... in ...} : lorsque la variable de référence est indéfinie, le résultat était invalide (valeur précédente de la variable $replacement)
983
  Correction d'un problème avec les produits packagés (bundle product) : les produits 'bundle' et les produits 'simple' étaient tous deux récupérés ce qui faussait les résultats
984
  Support des sets d'attributs
985
+ product.attribute_set dans les conditions de boucle foreach
986
+ {product.attribute_set} et {product.attribute_set.id} comme variables dans les boucles foreach
987
+ product.attribute_set, product.attribute_set.id dans les conditions des opérations sum, count, min et max
988
  Optimisation du chargement de certaines valeurs (catégories, attribute set, ...)
989
  Correction d'un problème avec les castings successifs (string), (float) qui posent problème lorsque la locale utilise la virgule comme séparateur de décimales
990
 
1011
  Ajout des alias &quot;a&quot; et &quot;attr&quot; pour &quot;attribute&quot;, &quot;o&quot; et &quot;opt&quot; pour &quot;option&quot;, &quot;p&quot; pour &quot;product&quot;, &quot;c&quot; pour &quot;cart&quot;, &quot;s&quot; pour &quot;selection&quot;
1012
  Correction de la récupération des variables personnalisées : getValue('text') au lieu de getValue('plain')
1013
  Support des catégories
1014
+ product.categories dans les conditions de boucle foreach
1015
+ {product.category} et {product.category.id} comme variables dans les boucles foreach
1016
+ product.category, product.category.id, product.categories, product.categories.id dans les conditions des opérations sum, count, min et max
1017
  Amélioration du debug
1018
 
1019
  [2.4.1 - 24 août 2011]
1020
  Modification légère du code php pour éviter un plantage avec certaines versions d'eAccelerator (cache php)
1021
+ $row = null;
1022
+ $this-&gt;addMessage('info',$row,null,'Ignored lines %s','&lt;div class=&quot;code&quot;&gt;'.trim($config_string).'&lt;/div&gt;');
1023
+ au lieu de ;
1024
+ $this-&gt;addMessage('info',$row=null,null,'Ignored lines %s','&lt;div class=&quot;code&quot;&gt;'.trim($config_string).'&lt;/div&gt;');
1025
+ (cf http://www.magentocommerce.com/boards/viewthread/233202/)
1026
  Ajout des variables de debug &quot;info.server.os&quot; et &quot;info.server.software&quot;
1027
  Ajout de la possibilité de récupérer la valeur minimum ou maximum de la quantité (ex: &quot;{max product.quantity}&quot;)
1028
 
1249
  [2.0 - 3 avril 2009]
1250
  Création de la version 2.0 du module Owebia Shipping qui n'est plus compatible avec les anciennes versions
1251
 
1252
+ </pre>
1253
+ </div>
1254
+
1255
+ <div id="index">
1256
+ <h2>Index</h2>
1257
+ <div class="panel">
1258
+ <div class="row">
1259
+ <div class="col-lg-6">
1260
+ <h3>A</h3>
1261
+ <ul>
1262
+ <li><code>about</code>: <a href="#property_about">property</a></li>
1263
+ <li>activation: see <code>enabled</code></li>
1264
+ <li>address of origin: see <code>origin</code></li>
1265
+ <li>address of billing: see <code>billto</code></li>
1266
+ <li>address of delivery: see <code>shipto</code></li>
1267
+ <li><code>address_filter</code>: <a href="#address_filter">shortcuts</a>, <a href="#examples_using_address_filters_shortcuts">examples</a></li>
1268
+ <li>associative table: see <code>switch</code></li>
1269
+ <li>attribute of product: see <code>product.attribute.*</code></li>
1270
+ </ul>
1271
+
1272
+ <h3>B</h3>
1273
+ <ul>
1274
+ <li><code>billto</code>:
1275
+ <ul>
1276
+ <li><a href="#property_billto">property</a></li>
1277
+ <li><a href="#formulas_variables_billto">variables</a></li>
1278
+ </ul>
1279
+ </li>
1280
+ </ul>
1281
+
1282
+ <h3>C</h3>
1283
+ <ul>
1284
+ <li><code>cart</code>: <a href="#formulas_variables_cart">variables</a></li>
1285
+ <li>comment: see <code>about</code></li>
1286
+ <li><code>conditions</code>: <a href="#property_conditions">property</a></li>
1287
+ <li><code>count</code>: <a href="#formulas_special_functions">special functions</a></li>
1288
+ <li><code>count distinct</code>: <a href="#formulas_special_functions">special functions</a></li>
1289
+ <li><code>customer</code>: <a href="#formulas_variables_customer">variables</a></li>
1290
+ <li><code>customer_group</code>: <a href="#formulas_variables_customer_group">variables</a></li>
1291
+ <li><code>customer_groups</code>: <a href="#property_customer_groups">property</a></li>
1292
+ <li><code>customvar</code>: <a href="#formulas_variables_customvar">variables</a></li>
1293
+ </ul>
1294
+
1295
+ <h3>D</h3>
1296
+ <ul>
1297
+ <li><code>data</code>: <a href="#definitions_element">element type</a>, <a href="#examples_data">examples</a></li>
1298
+ <li><code>date</code>: <a href="#formulas_variables_date">variables</a></li>
1299
+ <li>deactivation: see <code>enabled</code></li>
1300
+ <li><code>description</code>: <a href="#property_description">property</a></li>
1301
+ <li>destination: see <code>shipto</code></li>
1302
+ <li>DOM/TOM: <a href="#examples_excluding_domtom_postcode">excluding postal codes</a></li>
1303
+ </ul>
1304
+
1305
+ <h3>E</h3>
1306
+ <ul>
1307
+ <li>element: <a href="#definitions_element">definition</a></li>
1308
+ <li><code>enabled</code>: <a href="#property_enabled">property</a></li>
1309
+ </ul>
1310
+
1311
+ <h3>F</h3>
1312
+ <ul>
1313
+ <li><code>fees</code>: <a href="#property_fees">property</a></li>
1314
+ <li><code>foreach</code>: <a href="#formulas_foreach">loop</a>, <a href="#examples_using_foreach">examples</a></li>
1315
+ <li><a href="#formulas">Formulas</a></li>
1316
+ <li>free shipping: <a href="#examples_simple">examples</a></li>
1317
+ <li><a href="#formulas_functions">Functions</a></li>
1318
+ </ul>
1319
+
1320
+ <h3>I</h3>
1321
+ <ul>
1322
+ <li>identifier (unique): <a href="#definitions_unique_id">definition</a></li>
1323
+ <li><code>item</code>: <a href="#formulas_variables_item">variables</a></li>
1324
+ <li><code>item.option.*</code>: <a href="#formulas_variables_item">variables</a></li>
1325
+ </ul>
1326
+ </div>
1327
+ <div class="col-lg-6">
1328
+ <h3>L</h3>
1329
+ <ul>
1330
+ <li><code>label</code>: <a href="#property_label">property</a></li>
1331
+ </ul>
1332
+
1333
+ <h3>M</h3>
1334
+ <ul>
1335
+ <li><code>max</code>:
1336
+ <ul>
1337
+ <li><a href="#formulas_functions">function</a></li>
1338
+ <li><a href="#formulas_special_functions">special functions</a>, <a href="#examples_special_max">examples</a></li>
1339
+ </ul>
1340
+ </li>
1341
+ <li><code>meta</code>: <a href="#definitions_element">element type</a>, <a href="#examples_meta">examples</a></li>
1342
+ <li><code>method</code>: <a href="#definitions_element">element type</a></li>
1343
+ <li><code>min</code>:
1344
+ <ul>
1345
+ <li><a href="#formulas_functions">function</a></li>
1346
+ <li><a href="#formulas_special_functions">special functions</a>, <a href="#examples_special_min">examples</a></li>
1347
+ </ul>
1348
+ </li>
1349
+ </ul>
1350
+
1351
+ <h3>O</h3>
1352
+ <ul>
1353
+ <li>option of item: see <code>item.option.*</code></li>
1354
+ <li><code>origin</code>:
1355
+ <ul>
1356
+ <li><a href="#property_origin">property</a></li>
1357
+ <li><a href="#formulas_variables_origin">variables</a></li>
1358
+ </ul>
1359
+ </li>
1360
+ </ul>
1361
+
1362
+ <h3>P</h3>
1363
+ <ul>
1364
+ <li><code>product</code>: <a href="#formulas_variables_product">variables</a></li>
1365
+ <li><code>product.attribute.*</code>: <a href="#formulas_variables_product">variables</a></li>
1366
+ <li><code>product.categories</code>: <a href="#formulas_variables_product">variables</a>, <a href="#examples_product_categories">examples</a></li>
1367
+ <li>property: <a href="#definitions_property">definition</a></li>
1368
+ </ul>
1369
+
1370
+ <h3>Q</h3>
1371
+ <ul>
1372
+ <li><code>quote</code> : <a href="#formulas_variables_quote">variables</a></li>
1373
+ </ul>
1374
+
1375
+ <h3>R</h3>
1376
+ <ul>
1377
+ <li>regular expression: see property <code>shipto</code></li>
1378
+ <li><code>request</code>: <a href="#formulas_variables_request">variables</a></li>
1379
+ </ul>
1380
+
1381
+ <h3>S</h3>
1382
+ <ul>
1383
+ <li><code>shipto</code>:
1384
+ <ul>
1385
+ <li><a href="#property_shipto">property</a>, <a href="#examples_using_address_filters">examples</a></li>
1386
+ <li><a href="#formulas_variables_shipto">variables</a></li>
1387
+ </ul>
1388
+ </li>
1389
+ <li><code>store</code>: <a href="#formulas_variables_store">variables</a></li>
1390
+ <li><code>sum</code>: <a href="#formulas_special_functions">special functions</a></li>
1391
+ <li><code>switch</code>: <a href="#formulas_special_functions">special functions</a>, <a href="#examples_special_switch">examples</a></li>
1392
+ </ul>
1393
+
1394
+ <h3>T</h3>
1395
+ <ul>
1396
+ <li><code>table</code>: <a href="#formulas_special_functions">special functions</a>, <a href="#examples_special_table">examples</a></li>
1397
+ <li>title: see <code>label</code></li>
1398
+ <li><code>tracking_url</code>: <a href="#property_tracking_url">property</a>, <a href="#more_tracking_url">more informations</a></li>
1399
+ <li><code>type</code>: <a href="#property_type">property</a></li>
1400
+ </ul>
1401
+
1402
+ <h3>V</h3>
1403
+ <ul>
1404
+ <li>Variables: <a href="#formulas_variables">available</a>, <a href="#formulas_deprecated_variables">deprecated</a></li>
1405
+ </ul>
1406
+ </div>
1407
+ </div>
1408
+ </div>
1409
+ </div>
1410
+ <!-- doc content end -->
1411
+ </div>
1412
+ </div>
1413
  </div>
1414
  <script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
1415
  <script src="http://netdna.bootstrapcdn.com/bootstrap/3.0.0-rc1/js/bootstrap.min.js"></script>
1416
  <script>
1417
  <!-- doc scripts start -->
1418
  function jsonEncode(data, beautify, html, level, current_indent) {
1419
+ if (typeof beautify == 'undefined') beautify = false;
1420
+ if (typeof html == 'undefined') html = false;
1421
+ if (typeof level == 'undefined') level = 0;
1422
+ if (typeof current_indent == 'undefined') current_indent = '';
1423
+
1424
+ var indent = html ? '&nbsp;&nbsp;&nbsp;' : "\t";
1425
+ var line_break = html ? '<br/>' : "\n";
1426
+ var new_indent = current_indent + indent;
1427
+ switch (typeof(data)) {
1428
+ case 'undefined':
1429
+ return (html ? '<span class=json-reserved>' : '') + 'null' + (html ? '</span>' : '');
1430
+ case 'boolean':
1431
+ return (html ? '<span class=json-reserved>' : '') + (data ? 'true' : 'false') + (html ? '</span>' : '');
1432
+ case 'number':
1433
+ return (html ? '<span class=json-numeric>' : '') + data + (html ? '</span>' : '');
1434
+ case 'string':
1435
+ var output = JSON.stringify(data);
1436
+ return html ? '<span class=json-string>' + output + '</span>' : output;
1437
+ case 'object':
1438
+ var output_index_count = 0;
1439
+ var output = [];
1440
+ for (var key in data) {
1441
+ var value = data[key];
1442
+ if (output_index_count!==null && output_index_count++!==key) {
1443
+ output_index_count = null;
1444
+ }
1445
+ }
1446
+ var is_associative = output_index_count===null;
1447
+ for (var key in data) {
1448
+ var value = data[key];
1449
+ if (is_associative) {
1450
+ var classes = [];
1451
+ if (key=='about') classes.push('json-about');
1452
+ if (key=='conditions' || key=='fees') classes.push('json-formula');
1453
+ var property_classes = ['json-property'];
1454
+ if (level==0) property_classes.push('json-id');
1455
+ output.push(
1456
+ (html && classes.length ? '<span class="' + classes.join(' ') + '">' : '')
1457
+ + (html ? '<span' + (property_classes.length ? ' class="' + property_classes.join(' ') + '"' : '') + '>' : '')
1458
+ + jsonEncode('' + key)
1459
+ + (html ? '</span>' : '') + ':'
1460
+ + (beautify ? ' ' : '')
1461
+ + jsonEncode(value, beautify, html, level+1, new_indent)
1462
+ + (html && classes.length ? '</span>' : '')
1463
+ );
1464
+ } else {
1465
+ output.push(jsonEncode(value, beautify, html, level+1, current_indent));
1466
+ }
1467
+ }
1468
+ if (is_associative) {
1469
+ var classes = [];
1470
+ if (data.type == 'meta') classes.push('json-meta');
1471
+ output = (html && classes.length ? '<span class="' + classes.join(' ') + '">' : '')
1472
+ + '{'
1473
+ + (beautify ? line_break + new_indent : '')
1474
+ + output.join(',' + (beautify ? line_break + new_indent : ''))
1475
+ + (beautify ? line_break + current_indent : '')
1476
+ + '}'
1477
+ + (html && classes.length ? '</span>' : '');
1478
+ return output;
1479
+ } else {
1480
+ return '[' + output.join(',' + (beautify ? ' ' : '')) + ']';
1481
+ }
1482
+ default:
1483
+ return ''; // Not supported
1484
+ }
1485
  }
1486
 
1487
  $(function(){
1488
+ var navHeight = $('.navbar').outerHeight(true) + 10;
1489
+
1490
+ $('a[href^="#"]').click(function (e) {
1491
+ $('.highlight').removeClass('highlight');
1492
+ var anchor = $(this).attr('href').replace('#', '');
1493
+ window.location.hash = '#' + anchor;
1494
+ var jelem = $('#' + anchor);
1495
+ jelem.addClass('highlight');
1496
+ $('body,html').scrollTop(Math.round(jelem.offset().top - navHeight + 10));
1497
+ e.preventDefault()
1498
+ });
1499
+
1500
+ $('a[href^="#"]').each(function (e) {
1501
+ var anchor = $(this).attr('href').replace('#', '');
1502
+ if (anchor == '') return;
1503
+ var jelem = $('#' + anchor);
1504
+ if (!jelem.length) {
1505
+ $(this).css('border', 'solid 1px red').css('padding', 3);
1506
+ }
1507
+ });
1508
+
1509
+ var index = 0;
1510
+ $('div.json').each(function(){
1511
+ var text = $(this).text();
1512
+ while (text.match(/"__auto__"/)) {
1513
+ text = text.replace(/"__auto__"/, '"id_' + ('000' + index).slice(-3) + '"');
1514
+ index++;
1515
+ }
1516
+ var obj = $.parseJSON(text);
1517
+ var beautified = jsonEncode(obj, true, true);
1518
+ $(this).html('<pre>' + beautified + '</pre>');
1519
+ $(this).addClass('code');
1520
+ });
1521
+ $('body').scrollspy({
1522
+ target: '.sidebar',
1523
+ offset: navHeight
1524
+ });
1525
 
1526
  });
1527
  <!-- doc scripts end -->
app/code/community/Owebia/Shipping2/doc_fr_FR.html CHANGED
@@ -2,7 +2,7 @@
2
  <html>
3
  <head lang="fr">
4
  <meta charset="utf-8"/>
5
- <title>Documentation de l'extension Owebia-Shipping 2.5.13</title>
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
  <link href="http://netdna.bootstrapcdn.com/bootstrap/3.0.0-rc1/css/bootstrap.min.css" rel="stylesheet">
8
  <style>
@@ -39,807 +39,829 @@ pre.changelog{white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre
39
  .sidebar .nav .nav {display: none; /* Hide by default, but at >768px, show it */margin-bottom: 8px;}
40
  .sidebar .nav .nav > li > a {padding-top:3px;padding-bottom:3px;padding-left:30px;font-size:90%;}
41
  @media screen and (min-width: 768px) {
42
- .sidebar{display:block}
43
- .sidebar .nav > .active > ul {display:block}
44
- .bs-navbar-top-example .navbar-fixed-top,
45
- .bs-navbar-bottom-example .navbar-fixed-bottom {position:absolute}
46
  }
47
  @media screen and (min-width: 992px) {
48
- .sidebar.affix,
49
- .sidebar.affix-bottom {width:213px}
50
- .sidebar.affix {position:fixed;top:80px}
51
- .sidebar.affix-bottom {position:absolute}
52
- .sidebar.affix-bottom .sidenav,
53
- .sidebar.affix .sidenav {margin-top:0;margin-bottom:0}
54
  }
55
  @media screen and (min-width: 1200px) {
56
- .sidebar.affix-bottom,
57
- .sidebar.affix {width:270px}
58
  }
59
  </style>
60
  </head>
61
  <body>
62
  <div class="navbar navbar-inverse navbar-fixed-top">
63
- <div class="container">
64
- <a href="http://www.owebia.com" class="navbar-brand">Owebia</a>
65
- <ul class="nav navbar-nav">
66
- </ul>
67
- </div>
68
  </div>
69
  <div class="container">
70
- <div class="row">
71
- <div class="col-lg-3">
72
- <div class="affix sidebar">
73
- <!-- doc sidebar start -->
74
- <ul class="nav sidenav">
75
- <li><a href="#introduction">Introduction</a></li>
76
- <li><a href="#examples">Exemples</a>
77
- <ul class="nav">
78
- <li><a href="#examples_simple">Exemple simple : port offert</a></li>
79
- <li><a href="#examples_using_address_filters">Frais relatifs à la destination</a></li>
80
- <li><a href="#examples_using_customer_groups">Frais relatifs au groupe client</a></li>
81
- <li><a href="#examples_using_formulas">Utiliser les formules</a></li>
82
- <li><a href="#examples_using_special_functions">Utiliser les fonctions spéciales</a></li>
83
- <li><a href="#examples_using_foreach">Utiliser les boucles <code>{foreach …}</code></a></li>
84
- <li><a href="#examples_using_array_functions">Manipuler les tableaux</a></li>
85
- <li><a href="#examples_more">Autres exemples</a></li>
86
- </ul>
87
- </li>
88
- <li><a href="#definitions">Définitions</a>
89
- <ul class="nav">
90
- <li><a href="#definitions_element">Les éléments</a></li>
91
- <li><a href="#definitions_property">Les propriétés</a></li>
92
- <li><a href="#definitions_unique_id">L'identifiant unique</a></li>
93
- </ul>
94
- </li>
95
- <li><a href="#formulas">Les formules</a>
96
- <ul class="nav">
97
- <li><a href="#formulas_variables">Les variables</a></li>
98
- <li><a href="#formulas_functions">Les fonctions</a></li>
99
- <li><a href="#formulas_special_functions">Les fonctions spéciales</a></li>
100
- <li><a href="#formulas_foreach">Les boucles <code>foreach</code></a></li>
101
- <li><a href="#formulas_deprecated_variables">Les variables dépréciées</a></li>
102
- </ul>
103
- </li>
104
- <li><a href="#more">Divers</a>
105
- <ul class="nav">
106
- <li><a href="#more_tracking_url">L'URL de suivi</a></li>
107
- </ul>
108
- </li>
109
- <li><a href="#changelog">Changelog</a></li>
110
- <li><a href="#index">Index</a></li>
111
- </ul>
112
- <!-- doc sidebar end -->
113
- </div>
114
- </div>
115
- <div class="col-lg-9">
116
- <!-- doc content start -->
117
- <h1>Documentation de l'extension Owebia-Shipping 2.5.13 pour Magento</h1>
118
- <div id="introduction">
119
- <h2>Introduction</h2>
120
-
121
- <p>Owebia-Shipping est une extension pour la solution de e-commerce <a href="http://www.magentocommerce.com/" target="_blank">Magento</a>.</p>
122
- <p>Grace à sa syntaxe au format <a href="http://fr.wikipedia.org/wiki/JavaScript_Object_Notation" target=_blank>JSON</a>, cette extension permet une grande souplesse dans le paramétrage des frais de livraison.</p>
123
-
124
- <p>Cette documentation explique comment créer une configuration pour l'un des modes de livraison proposé par l'extension.</p>
125
-
126
- <p class="alert alert-info">Nouvelle documentation, plus simple et plus claire.<br/>
127
- <strong>Utilisez l'<a href="#index">index</a></strong> pour vous retrouver plus facilement dans la documentation.</p>
128
- </div>
129
-
130
- <div id="examples">
131
- <h2>Exemples</h2>
132
-
133
- <div id="examples_simple">
134
- <h3>Exemple simple : port offert</h3>
135
- <div class="json">{
136
- "__auto__":{"label":"Livraison gratuite","fees": 0}
137
- }</div>
138
- </div>
139
-
140
- <div id="examples_using_address_filters">
141
- <h3>Frais relatifs à la destination</h3>
142
- <div class="json">{
143
- "__auto__":{"label":"France, Allemagne, Suisse, Espagne, Italie","shipto":"FR,DE,CH,ES,IT","fees":10},
144
- "__auto__":{"label":"France sauf la Corse","shipto":"FR-(2A,2B)","fees":10},
145
- "__auto__":{"label":"Corse","shipto":"FR(2A,2B)","fees":10},
146
- "__auto__":{"label":"Monde entier sauf l'Allemagne et la Corse","shipto":"* - ( DE, FR(2A,2B) )","fees":10}
147
- }</div>
148
-
149
- <h4>Utiliser le caractère jocker <code>*</code> ou les expressions régulières</h4>
150
- <div class="json">{
151
- "__auto__":{"label":"Caractère jocker autorisant les codes postaux commençant par 25","shipto":"FR(25*)","fees":10},
152
- "__auto__":{"label":"Expression régulière acceptant les codes postaux commençant par 'PO', 'po', 'Po' ou 'pO'","shipto":"GB(/^PO.*$/i)","fees":10}
153
- }</div>
154
-
155
- <div id="examples_excluding_domtom_postcode">
156
- <h4>Bloquer la livraison vers la France mais avec un code postal DOM/TOM</h4>
157
- <p>Avec l'expression régulière suivante, vous bloquez les codes postaux commançant par 97 ou 98 (avec ou sans zéros et espaces intercalés).</p>
158
- <div class="json">{
159
- "__auto__":{"label":"Expression régulière refusant les codes postaux commençant par 97 et 98","shipto":"FR-(/^[0\\s]*9\\s*[78].*/)","fees":10}
160
- }</div>
161
- </div>
162
-
163
- <div id="examples_using_address_filters_shortcuts">
164
- <h4>Utilisation des raccourcis <code>address_filter</code></h4>
165
- <div class="json">{
166
- "__auto__":{"label":"Europe sauf la France","shipto":"({address_filter.EU-27}) - (FR)","fees":10}
167
- }</div>
168
- </div>
169
- </div>
170
-
171
- <div id="examples_using_customer_groups">
172
- <h3>Frais relatifs au groupe client</h3>
173
- <p>On peut utiliser le nom ou l'ID des groupes client.</p>
174
- <div class="json">{
175
- "__auto__":{"label":"Groupes NOT LOGGED IN et General","customer_groups":"NOT LOGGED IN,General","fees":10},
176
- "__auto__":{"label":"Groupes NOT LOGGED IN et General par leur ID","customer_groups":"0,1","fees":10},
177
- "__auto__":{"label":"Groupe Retailer","customer_groups":"Retailer","fees":10}
178
- }</div>
179
- </div>
180
-
181
- <div id="examples_using_formulas">
182
- <h3>Utiliser les formules</h3>
183
- <p>Les formules peuvent être utilisées dans les propriétés <code>conditions</code> et <code>fees</code>.</p>
184
- <div class="json">{
185
- "__auto__":{"label":"Livraison","fees":"0.1 * {cart.price-tax+discount} + 10.00"}
186
- }</div>
187
-
188
- <h4>Copier la propriété d'un autre élément</h4>
189
- <div class="json">{
190
- "standard":{"label":"Livraison standard","conditions":"{cart.price-tax+discount} < 1000.00","fees":10},
191
- "express":{"label":"Livraison express","conditions":"( {standard.conditions} ) && ( {cart.weight} < 10 )","fees":12}
192
- }</div>
193
-
194
- <h4>Utiliser la fonction <code>min()</code></h4>
195
- <div class="json">{
196
- "__auto__":{"label":"Livraison","fees":"min({cart.weight}, {cart.price+tax+discount}, {cart.qty})"}
197
- }</div>
198
-
199
- <h4>Utiliser la fonction <code>range()</code></h4>
200
- <div class="json">{
201
- "__auto__":{"label":"Livraison","conditions":"range({cart.weight}, 1.0, 3.0)","fees":10}
202
- }</div>
203
-
204
- <h4>Utiliser la fonction <code>substr()</code></h4>
205
- <p>Une variable de type chaîne de caractères doit être entourée par des guillemets simples sauf si on utilise l'auto-échappement avec les caractères <code>{{</code> et <code>}}</code>.</p>
206
- <div class="json">{
207
- "__auto__":{"label":"Sans utiliser l'auto-échappement","conditions":"substr('{cart.coupon_code}', 0, 5)=='free_'","fees":10},
208
- "__auto__":{"label":"En utilisant l'auto-échappement","conditions":"substr({{cart.coupon_code}}, 0, 5)=='free_'","fees":10}
209
- }</div>
210
-
211
- </div>
212
-
213
- <div id="examples_using_special_functions">
214
- <h3>Utiliser les fonctions spéciales</h3>
215
-
216
- <div id="examples_special_table">
217
- <h4>Utilisation de la fonction spéciale <code>{table … in …}</code></h4>
218
- <div class="json">{
219
- "__auto__":{"label":"Livraison","fees":"{table {cart.weight} in 0.5:5.30, 1.0:6.50, 2.0:7.40, 3.0:8.30, 5.0:10.10}"}
220
- }</div>
221
- <p>
222
- Dans une <code>table</code>, on peut inclure ou exclure une valeur limite avec les caractères <code>[</code> et <code>]</code> :
223
- </p>
224
- <div class="json">{
225
- "__auto__":{"label":"Limite supérieure incluse","fees":"{table {cart.weight} in 1.0]:5.00}"},
226
- "__auto__":{"label":"Limite supérieure exclue","fees":"{table {cart.weight} in 1.0[:5.00}"}
227
- }</div>
228
-
229
- <p>
230
- Dans une <code>table</code>, on doit spécifier la valeur de référence. Pour cela, on peut utiliser une des <a href="#formulas_variables">variables</a> disponibles.<br/>
231
- On peut aussi utiliser une formule afin de définir une autre variable de référence.
232
- </p>
233
-
234
- <div class="json">{
235
- "__auto__":{"label":"Table avec poids du panier","fees":"{table {cart.weight} in 0.5:5.30, 1.0:6.50}"},
236
- "__auto__":{"label":"Table avec quantité d'articles","fees":"{table {cart.qty} in 10:5.30, 20:6.50}"},
237
- "__auto__":{"label":"Table avec prix TTC","fees":"{table {cart.price+tax+discount} in 15.00:5.30, 30.00:6.50, *:10.00}"},
238
- "__auto__":{"label":"Table avec prix HT","fees":"{table {cart.price-tax+discount} in 15.00:5.30, 30.00:6.50, *:10.00}"},
239
- "__auto__":{"label":"Table avec valeur personnalisée","fees":"{table ceil({cart.weight}/10) in 1:5.30, 2:6.50}"}
240
- }</div>
241
- </div>
242
-
243
- <div id="examples_special_switch">
244
- <h4>Utilisation de la fonction spéciale <code>{switch … in …}</code> (table de correspondance)</h4>
245
- <p>
246
- Dans un <code>switch</code>, on doit spécifier la valeur de référence. Pour cela, on peut utiliser une des <a href="#formulas_variables">variables</a> disponibles.<br/>
247
- On peut aussi utiliser une formule afin de définir une autre variable de référence.
248
- </p>
249
- <div class="json">{
250
- "__auto__":{"label":"Switch avec code promo","fees":"{switch {{cart.coupon_code}} in 'coupon1':5.30, 'coupon2':6.50, null:10.00, *:7.50}"},
251
- "__auto__":{"label":"Switch avec pays de livraison","fees":"{switch {{shipto.country_id}} in 'FR':5.30, 'BE':6.50, 'DE':10.00, *:7.50}"}
252
- }</div>
253
- </div>
254
-
255
- <div id="examples_special_count">
256
- <h4>Utiliser la fonction spéciale <code>{count …}</code></h4>
257
- <div class="json">{
258
- "__auto__":{"label":"Si au moins un produit possède l'attribut 'color' égal à 'Bleu'","conditions":"{count items where product.attribute.color=='Bleu'} > 0","fees":10},
259
- "__auto__":{"label":"Si tous les produits possèdent l'option 'size' supérieure ou égal à '1'","conditions":"{count items where item.option.size>='1'} == {cart.qty}","fees":10}
260
- }</div>
261
-
262
- <p>
263
- Si la propriété est de type <strong>Oui/Non</strong>, vous devez utiliser les valeurs <code>true</code>/<code>false</code> ou <code>1</code>/<code>0</code> sans les guillemets.
264
- </p>
265
- <div class="json">{
266
- "__auto__":{"label":"Exemple propriété de type Oui/Non : 1","conditions":"{count items where product.attribute.colissimo_allowed==1}","fees":10},
267
- "__auto__":{"label":"Exemple propriété de type Oui/Non : true","conditions":"{count items where product.attribute.colissimo_allowed==true}","fees":10}
268
- }</div>
269
- </div>
270
-
271
- <div id="examples_special_count_distinct">
272
- <h4>Utiliser la fonction spéciale <code>{count distinct …}</code></h4>
273
- <div class="json">{
274
- "__auto__":{"label":"Nombre de SKU différents","conditions":"{count distinct product.attribute.sku}","fees":10}
275
- }</div>
276
- </div>
277
-
278
- <div id="examples_special_sum">
279
- <h4>Utiliser la fonction spéciale <code>{sum …}</code></h4>
280
- <div class="json">{
281
- "__auto__":{"label":"Somme de toutes les options 'size' est supérieure à 30","conditions":"{sum item.option.size} > 30","fees":10}
282
- }</div>
283
- </div>
284
-
285
- <div id="examples_special_min">
286
- <h4>Utiliser la fonction spéciale <code>{min …}</code></h4>
287
- <div class="json">{
288
- "__auto__":{"label":"Prix HT sans remise minimum des articles dans le panier est supérieur à 10","conditions":"{min item.price-tax-discount} > 10","fees":10}
289
- }</div>
290
- </div>
291
-
292
- <div id="examples_special_max">
293
- <h4>Utiliser la fonction spéciale <code>{max …}</code></h4>
294
- <div class="json">{
295
- "__auto__":{"label":"Valeur maximum de l'option 'size' des articles dans le panier est inférieure à 50","conditions":"{max item.option.size} < 50","fees":10}
296
- }</div>
297
- </div>
298
- </div>
299
-
300
- <div id="examples_using_foreach">
301
- <h3>Utiliser les boucles <code>{foreach …}</code></h3>
302
- <div class="json">{
303
- "__auto__":{"label":"Regroupement des produits par origine puis traitement des groupes séparémment","fees":"{foreach product.attribute.code_origin}{table {selection.weight} in 0.0:0.00, 1.0:11.00, 3.0:12.00, 5.0:13.00}{/foreach}"},
304
- "__auto__":{"label":"Calcul des frais de port par produit","fees":"{foreach product.attribute.sku}{product.attribute.shipping}*{item.qty}{/foreach}"}
305
- }</div>
306
- </div>
307
-
308
- <div id="examples_using_array_functions">
309
- <h3>Manipuler les tableaux</h3>
310
-
311
- <h4>Utilisation de la fonction <code>in_array()</code></h4>
312
- <div class="json">{
313
- "__auto__":{"label":"Livraison","conditions":"in_array({cart.qty}, array(10, 20, 30))","fees":10}
314
- }</div>
315
-
316
- <h4>Utilisation de la fonction <code>in_array()</code> avec des chaînes de caractères *</h4>
317
- <div class="json">{
318
- "__auto__":{"label":"Livraison","conditions":"in_array({{cart.coupon_code}}, array('free1', 'free2'))","fees":10}
319
- }</div>
320
-
321
- <h4>Utilisation de la fonction <code>array_match_any()</code></h4>
322
- <div class="json">{
323
- "__auto__":{"label":"Livraison","about":"5 x poids des produits qui se trouvent dans la catégorie 2 ou 3","fees":"{sum product.weight where array_match_any(product.categories.id, array(2, 3))} * 5.0"}
324
- }</div>
325
-
326
- <h4>Utilisation de la fonction <code>array_match_all()</code></h4>
327
- <div class="json">{
328
- "__auto__":{"label":"Livraison","about":"5 x poids des produits qui se trouvent à la fois dans la catégorie 2 et dans la catégorie 3","fees":"{sum product.weight where array_match_all(product.categories.id, array(2, 3))} * 5.0"}
329
- }</div>
330
- </div>
331
-
332
- <div id="examples_more">
333
- <h3>Autres exemples</h3>
334
-
335
- <div id="examples_product_categories">
336
- <h4>Utiliser la catégorie des produits</h4>
337
- <p class="alert alert-danger">Attention, il est à noter que dans Magento, <strong>un produit peut être dans plusieurs catégories</strong>. Faites donc particulièrement attention à la façon dont vous utilisez cette propriété.</p>
338
- <div class="json">{
339
- "__auto__":{"label":"Boucle foreach dont l'itération se fait sur la catégorie","fees":"{foreach product.categories}{selection.weight}{/foreach}"},
340
- "__auto__":{"label":"Utilisation de la catégorie à l'intérieur d'une boucle foreach","fees":"{foreach product.sku}({{product.category}}=='Test' ? 2.00 : 1.00)*{item.qty}{/foreach}"},
341
- "__auto__":{"label":"Utilisation de l'id de la catégorie à l'intérieur d'une boucle foreach","fees":"{foreach product.sku}({product.category.id}==12 ? 2.00 : 1.00)*{item.qty}{/foreach}"},
342
- "__auto__":{"about":"La fonction in_array() est utilisée car product.categories retourne un tableau","label":"Somme des attributs weight des produits de la catégorie 'Test'","fees":"{sum product.weight where in_array('Test', product.categories)}"},
343
- "__auto__":{"about":"La fonction in_array() est utilisée car product.categories.id retourne un tableau","label":"Somme des attributs weight des produits de la catégorie dont l'id est 12","fees":"{sum product.weight where in_array(12, product.categories.id)}"},
344
- "__auto__":{"about":"La fonction array_match_any() est utilisée car product.categories.id retourne un tableau","label":"Somme des attributs weight des produits des catégories dont les id sont 11 et 12","fees":"{sum product.weight where array_match_any(product.categories.id, array(11, 12))}"},
345
- "__auto__":{"label":"Somme des poids des produits dont la première catégorie est 'Test'","fees":"{sum product.weight where product.category=='Test'}"},
346
- "__auto__":{"label":"Somme des poids des produits dont l'id de la première catégorie est 12","fees":"{sum product.weight where product.category.id==12}"}
347
- }</div>
348
- </div>
349
-
350
- <div id="examples_data">
351
- <h4>Ajout et utilisation d'un élément <code>data</code></h4>
352
- <p>Un élément de type <code>data</code> permet de spécifier des données utilisables dans les méthodes de livraison.</p>
353
- <div class="json">{
354
- "mydata":{"type":"data","var1":"12"},
355
- "__auto__":{"label":"Livraison","shipto":"FR","fees": "{mydata.var1}"},
356
- "__auto__":{"label":"Livraison","shipto":"DE","fees": "{mydata.var1}*1.5"}
357
- }</div>
358
- </div>
359
-
360
- <div id="examples_meta">
361
- <h4>Ajout d'un élément <code>meta</code></h4>
362
- <p>Un élément de type <code>meta</code> permet d'ajouter des données informatives (auteur, date…).</p>
363
- <div class="json">{
364
- "about":{"type":"meta","author":"Owebia","date":"15/07/2013","about":"Tarifs 2013"}
365
- }</div>
366
- </div>
367
- </div>
368
- </div>
369
-
370
- <div id="definitions">
371
- <h2>Définitions</h2>
372
- <p>
373
- La configuration d'un mode de livraison est un objet JSON contenant plusieurs <strong><a href="#definitions_property">propriétés</a></strong>.<br/>
374
- Comme imposé par JSON, chaque propriété a un nom unique, qui servira d'<a href="#definitions_unique_id">identifiant unique</a>.<br/>
375
- Chaque propriété constitue un <strong><a href="#definitions_element">élément</a></strong> de configuration (qui est également un objet JSON).<br/>
376
- </p>
377
- <div id="definitions_element">
378
- <h3>Les éléments</h3>
379
-
380
- <p>
381
- Il existe trois différents types d'<strong>élément</strong> de configuration :
382
- </p>
383
- <ul>
384
- <li><code>method</code> : méthode de livraison (par défaut si non spécifié)</li>
385
- <li><code>data</code> : données pouvant être utilisées dans une ou plusieurs méthodes de livraison (<a href="#examples_data">exemples</a>)</li>
386
- <li><code>meta</code> : données informatives (<a href="#examples_meta">exemples</a>)</li>
387
- </ul>
388
- </div>
389
-
390
- <div id="definitions_property">
391
- <h3>Les propriétés</h3>
392
-
393
- <p>
394
- Chaque élément possède plusieurs <strong>propriétés</strong> :
395
- </p>
396
- <ul>
397
- <li id="property_about"><code>about</code> : commentaire sur l'élément</li>
398
- <li id="property_type"><code>type</code> : type de l'élément (<code>method</code>, <code>meta</code> ou <code>data</code>)</li>
399
- </ul>
400
-
401
- <p>
402
- Propriétés spécifiques à un élément de type <code>method</code> :
403
- </p>
404
- <ul>
405
- <li id="property_label"><code>label</code> : nom de la méthode de livraison</li>
406
- <li id="property_description"><code>description</code> : description (visible seulement si le template l'affiche)</li>
407
- <li id="property_enabled"><code>enabled</code> : méthode de livraison activée ou non</li>
408
- <li id="property_fees"><code>fees</code> : frais de port</li>
409
- <li id="property_conditions"><code>conditions</code> : conditions d'activation</li>
410
- <li id="property_shipto"><code>shipto</code> : pays (régions, codes postaux) autorisés à la livraison</li>
411
- <li id="property_billto"><code>billto</code> : pays (régions, codes postaux) autorisés à la facturation</li>
412
- <li id="property_origin"><code>origin</code> : pays (régions, codes postaux) autorisés en origine</li>
413
- <li id="property_customer_groups"><code>customer_groups</code> : groupes de client autorisés</li>
414
- <li id="property_tracking_url"><code>tracking_url</code> : URL de suivi (<a href="#more_tracking_url">plus d'informations</a>)</li>
415
- </ul>
416
-
417
- <p><a href="#examples">Voir les exemples</a></p>
418
-
419
- <h4>Utiliser les propriétés de type adresse (<code>shipto</code>, <code>billto</code> et <code>origin</code>)</h4>
420
- <p>
421
- Les codes pays utilisés sont ceux de Magento (à priori ils sont les mêmes que les <a href="http://fr.wikipedia.org/wiki/ISO_3166-1" target=_blank>codes ISO 3166-1 alpha-2</a>).<br/>
422
- Il est possible de spécifier les codes régions (uniquement avec <code>shipto</code>) ou les codes postaux que l'on veut filtrer ou exclure.
423
- </p>
424
- <p class=new>
425
- Vous pouvez utiliser le caractère <strong>jocker</strong> <code>*</code> ou les <strong>expressions régulières</strong> pour les codes postaux.<br/>
426
- Une expression régulière doit commencer et se terminer par le caractère <code>/</code>. Si vous souhaitez utiliser les caractères <code>(</code>, <code>)</code> ou <code>.</code>, vous devez les échapper avec le caractère <code>\</code> (ex: <code><span class=string>"FR(/^25\([0-9]{3}\)$/)"</span></code>).<br/>
427
- Vous pouvez utiliser l'option d'insensibilité à la casse (ex: <code><span class=string>"GB(/^PO.*$/i)"</span></code>).
428
- </p>
429
-
430
- <p><a href="#examples_using_address_filters">Voir les exemples</a></p>
431
-
432
- <div id="address_filter" class="alert alert-info">
433
- <p><strong>Astuce</strong><br/>Pour raccourcir la saisie des pays, vous pouvez utiliser les variables suivantes :</p>
434
- <ul>
435
- <li><code>{address_filter.AF}</code> : pays d'Afrique</li>
436
- <li><code>{address_filter.AS}</code> : pays d'Asie</li>
437
- <li><code>{address_filter.EU}</code> : pays d'Europe</li>
438
- <li><code>{address_filter.NA}</code> : pays d'Amérique du Nord</li>
439
- <li><code>{address_filter.SA}</code> : pays d'Amérique du Sud</li>
440
- <li><code>{address_filter.OC}</code> : pays d'Océanie</li>
441
- <li><code>{address_filter.AN}</code> : pays d'Antartique</li>
442
- <li><code>{address_filter.EU-27}</code> : pays de l'Union Européenne</li>
443
- <li><code>{address_filter.DOM}</code> : codes pays des département d'Outre-Mer Français</li>
444
- <li><code>{address_filter.COM}</code> : codes pays des Collectivités d'Outre-Mer Françaises</li>
445
- </ul>
446
- <p><a href="#examples_using_address_filters_shortcuts">Voir les exemples</a></p>
447
- </div>
448
- </div>
449
-
450
- <div id="definitions_unique_id">
451
- <h3>L'identifiant unique</h3>
452
-
453
- <p>Chaque élément de configuration possède un <strong>identifiant unique</strong>. Cet identifiant permet ensuite de faire référence à l'élément.</p>
454
- <p>Exemple :</p>
455
- <div class="json">{
456
- "europe":{"label":"Livraison Europe","fees":10},
457
- "us":{"label":"Livraison US","fees":"{europe.fees}+20"}
458
- }</div>
459
-
460
- <p class="alert alert-danger"><strong><u>Attention</u> :</strong> pour éviter les conflicts, n'utiliser que les caractères <code>a-z</code>, <code>A-Z</code>, <code>0-9</code>, <code>-</code> et <code>_</code> pour former l'identifiant unique.<br/>Vous devez également éviter les identifiants qui correspondent déjà à des noms de variable (<code>cart</code>, <code>product</code>, <code>item</code>…).</p>
461
- </div>
462
- </div>
463
-
464
- <div id="formulas">
465
- <h2>Les formules</h2>
466
- <p>
467
- Les propriétés <code>fees</code> et <code>conditions</code> sont spécifiées sous la forme de formules.<br/>
468
- </p>
469
- <p>
470
- Une formule utilise des <a href="#formulas_variables">variables</a>, des <a href="#formulas_functions">fonctions</a>, des <a href="#formulas_special_functions">fonctions spéciales</a> et des opérateurs mathématiques.
471
- </p>
472
- <p>
473
- Opérateurs mathématiques disponibles :
474
- </p>
475
- <ul>
476
- <li>opérateurs : <code>*</code>, <code>/</code>, <code>+</code> et <code>-</code></li>
477
- <li>modulo : <code>%</code></li>
478
- <li>parenthèses : <code>(</code> et <code>)</code></li>
479
- <li>les opérateurs booléens <code>&amp;&amp;</code>, <code>and</code>, <code>||</code>, <code>or</code>, <code>==</code>, <code>&lt;</code>, <code>&gt;</code>, <code>&lt;=</code>, <code>&gt;=</code></li>
480
- <li>les opérateurs binaires <code>&amp;</code> et <code>|</code></li>
481
- <li>le groupe d'opérateur <code>C ? X : Y</code> (ex: <code><span class=string>"{cart.price_exluding_tax}&gt;100 ? 15*{cart.weight} : 20*{cart.weight}"</span></code>)</li>
482
- </ul>
483
- <p>
484
- Vous avez la possibilité de mettre des espaces et des retours à la ligne dans les formules (pour aérer).
485
- </p>
486
- <p>
487
- Possibilité d'utiliser les fonctionnalités avancées suivantes : casting en entier <code>(int)</code> ou en nombre flottant <code>(float)</code>,
488
- comparaison avec la valeur <code>null</code> ou les valeurs booléennes <code>true</code> et <code>false</code>.
489
- </p>
490
-
491
- <div id="formulas_variables">
492
- <h3>Les variables</h3>
493
-
494
- <p class="alert alert-info">
495
- 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 <code>{{ }}</code>.
496
- </p>
497
-
498
- <p>
499
- Les variables suivantes peuvent être utilisées dans les <a href="#formulas">formules</a>.
500
- </p>
501
- <ul>
502
- <li id="formulas_variables_cart">Le panier :
503
- <ul>
504
- <li><code>{cart.weight}</code> : poids des marchandises</li>
505
- <li><code>{cart.qty}</code> : la quantité d'articles</li>
506
- <li><code>{cart.price-tax+discount}</code> : prix HT avec remise</li>
507
- <li><code>{cart.price+tax+discount}</code> : prix TTC avec remise</li>
508
- <li><code>{cart.price-tax-discount}</code> : prix HT sans remise</li>
509
- <li><code>{cart.price+tax-discount}</code> : prix TTC sans remise</li>
510
- <li><code>{cart.coupon_code}</code> : coupon de réduction</li>
511
- <li><code>{cart.free_shipping}</code> : frais de port offert (par une règle dans Magento) [true/false]</li>
512
- <li><code>{cart.weight_unit}</code> : l'unité de poids</li>
513
- <li><code>{cart.weight_for_charge}</code> : poids des marchandises dont la livraison n'est pas offerte (par les règles de prix panier de Magento)</li>
514
- </ul>
515
- </li>
516
- <li id="formulas_variables_quote">Le bon de commande :
517
- <ul>
518
- <li><code>{quote.subtotal}</code>: sous-total HT</li>
519
- <li><code>{quote.subtotal_with_discount}</code>: sous-total HT avec remise</li>
520
- <li><code>{quote.grand_total}</code>: total TTC avec remise</li>
521
- <li><code>{quote.base_subtotal}</code>: sous-total HT dans la devise de base</li>
522
- <li><code>{quote.base_subtotal_with_discount}</code>: sous-total HT avec remise dans la devise de base</li>
523
- <li><code>{quote.base_grand_total}</code>: total TTC avec remise dans la devise de base</li>
524
- </ul>
525
- </li>
526
- <li id="formulas_variables_customer_group">Le group client :
527
- <ul>
528
- <li><code>{customer_group.id}</code> : id du groupe client</li>
529
- <li><code>{customer_group.code}</code> : nom du groupe client</li>
530
- <li><code>{customer_group.*}</code> : propriété du groupe client (ex: <code>{customer_group.tax_class_id}</code>)</li>
531
- </ul>
532
- </li>
533
- <li id="formulas_variables_customer">Le client :
534
- <ul>
535
- <li><code>{customer.id}</code> : id du client</li>
536
- <li><code>{customer.attribute.*}</code> : attribut du client (ex: lastname, firstname, group_id…)</li>
537
- <li><code>{customer.attribute.*.value}</code> : dans le cas des attributs de type liste de sélection, <code>{customer.attribute.*}</code> retourne l'id, pour obtenir la valeur il faut utiliser <code>{customer.attribute.*.value}</code></li>
538
- <li><code>{customer.*}</code> : identique à <code>{customer.attribute.*}</code>, sauf si la variable est déjà définie (ex: <code>{customer.id}</code> est déjà définie)</li>
539
- </ul>
540
- </li>
541
- <li id="formulas_variables_customvar">Les variables personnalisées ou `Custom Variables` (depuis la version 1.4.0.1 de Magento) :
542
- <ul>
543
- <li><code>{customvar.*}</code> : variable personnalisée de Magento (ex: <code>{customvar.my_var}</code>)</li>
544
- </ul>
545
- </li>
546
- <li id="formulas_variables_shipto">L'adresse de livraison :
547
- <ul>
548
- <li><code>{shipto.country_name}</code> : le nom du pays</li>
549
- <li><code>{shipto.country_id}</code> : le code du pays</li>
550
- <li><code>{shipto.region_id}</code> : l'id de la région</li>
551
- <li><code>{shipto.region_code}</code> : le code de la région</li>
552
- <li><code>{shipto.street}</code> : la rue</li>
553
- <li><code>{shipto.city}</code> : la ville</li>
554
- <li><code>{shipto.postcode}</code> : le code postal</li>
555
- </ul>
556
- </li>
557
- <li id="formulas_variables_billto">L'adresse de facturation :
558
- <ul>
559
- <li><code>{billto.country_name}</code> : le nom du pays</li>
560
- <li><code>{billto.country_id}</code> : le code du pays</li>
561
- <li><code>{billto.postcode}</code> : le code postal</li>
562
- <li><code>{billto.*}</code> : propriété de l'adresse de facturation (ex: <code>{billto.city}</code>)</li>
563
- </ul>
564
- </li>
565
- <li id="formulas_variables_origin">L'adresse d'envoi :
566
- <ul>
567
- <li><code>{origin.country_name}</code> : le nom du pays</li>
568
- <li><code>{origin.country_id}</code> : le code du pays</li>
569
- <li><code>{origin.region_id}</code> : l'id de la région</li>
570
- <li><code>{origin.city}</code> : la ville</li>
571
- <li><code>{origin.postcode}</code> : le code postal</li>
572
- </ul>
573
- </li>
574
- <li id="formulas_variables_store">Le magasin :
575
- <ul>
576
- <li><code>{store.id}</code> <code>{store.code}</code> <code>{store.name}</code> <code>{store.address}</code> <code>{store.phone}</code> : id, code, nom, adresse et téléphone du magasin</li>
577
- </ul>
578
- </li>
579
- <li id="formulas_variables_date">La date courante :
580
- <ul>
581
- <li><code>{date.timestamp}</code> : timestamp UNIX de la date actuelle</li>
582
- <li><code>{date.year}</code> <code>{date.month}</code> <code>{date.day}</code> <code>{date.hour}</code> <code>{date.minute}</code> <code>{date.second}</code> : année, mois, jour, heure, minute et seconde de la date actuelle</li>
583
- <li><code>{date.weekday}</code> : jour de la semaine de la date actuelle de 0 (dimanche) à 6 (samedi)</li>
584
- </ul>
585
- </li>
586
- <li id="formulas_variables_request">L'objet <code>request</code> :
587
- <ul>
588
- <li><code>{request.*}</code> : propriété de l'objet request (Mage_Shipping_Model_Rate_Request) passé en paramètre par Magento (ex: <code>{request.package_qty}</code>). Utiliser l'option "Déboguage" pour obtenir plus de détail sur les propriétés disponibles.</li>
589
- </ul>
590
- </li>
591
- </ul>
592
-
593
- <div id="formulas_variables_for_special_functions">
594
- <h4>Variables utilisables dans les fonctions spéciales</h4>
595
-
596
- <p>Les variables suivantes peuvent être utilisées dans les <a href="#formulas_special_functions">fonctions spéciales</a>.</p>
597
-
598
- <p class="alert alert-danger">Contrairement à ailleurs, les variables suivantes ne doivent pas être entourées par les caractères <code>{</code> et <code>}</code>.</p>
599
-
600
- <p>
601
- Un <code>item</code> est une déclinaison d'un <code>product</code> auquel on a ajouté d'éventuelles options. Chaque <code>item</code> a une quantité.
602
- </p>
603
- <ul>
604
- <li id="formulas_variables_item">L'article (ou <code>item</code>) :
605
- <ul>
606
- <li><code>item.qty</code> : quantité dans le panier</li>
607
- <li><code>item.price-tax+discount</code> : le prix HT avec remise</li>
608
- <li><code>item.price-tax-discount</code> : le prix HT sans remise</li>
609
- <li><code>item.price+tax+discount</code> : le prix TTC avec remise</li>
610
- <li><code>item.price+tax-discount</code> : le prix TTC sans remise</li>
611
- <li><code>item.option.*</code> : option (la liste des options disponibles dépendra des produits)</li>
612
- </ul>
613
- </li>
614
- <li id="formulas_variables_product">Le produit (ou <code>product</code>) :
615
- <ul>
616
- <li><code>product.attribute.*</code> : attribut<br/>Attributs intéressants :
617
- <ul>
618
- <li><code>sku</code> : la référence</li>
619
- <li><code>name</code> : le nom</li>
620
- <li><code>weight</code> : le poids</li>
621
- <li><code>price</code> : le prix (tel qu'il a été saisi sur la fiche du produit)</li>
622
- <li><code>special_price</code> : le prix promotionnel (tel qu'il a été saisi sur la fiche du produit)</li>
623
- <li>…</li>
624
- </ul>
625
- </li>
626
- <li><code>product.attribute.*.value</code> : valeur de l'attribut<br/>Dans le cas des attributs de type liste de sélection, <code>product.attribute.*</code> retourne l'id. Pour obtenir la valeur, il faut utiliser <code>product.attribute.*.value</code></li>
627
- <li><code>product.*</code> : identique à <code>product.attribute.*</code> sauf si la variable est définie (ex: <code>product.category</code>)</li>
628
- <li>Première catégorie du produit :
629
- <ul>
630
- <li><code>product.category</code> : nom de la catégorie</li>
631
- <li><code>product.category.id</code> : id de la catégorie</li>
632
- <li><code>product.category.*</code> : attribut de la catégorie (ex: <code>product.category.is_active</code>)<br/>Attributs intéressants :
633
- <ul>
634
- <li><code>is_active</code> : catégorie activée ou non</li>
635
- <li><code>name</code> : nom</li>
636
- <li>…</li>
637
- </ul>
638
- </li>
639
- </ul>
640
- </li>
641
- <li>Toutes les catégories du produit (retourne un tableau, <a href="#examples_product_categories">exemples</a>) :
642
- <ul>
643
- <li><code>product.categories</code> : tableau du nom des catégories</li>
644
- <li><code>product.categories.id</code> : tableau de l'id des catégories</li>
645
- </ul>
646
- </li>
647
- <li>Le jeu d'attributs du produit :
648
- <ul>
649
- <li><code>product.attribute_set</code> : nom du jeu d'attributs</li>
650
- <li><code>product.attribute_set.id</code> : id du jeu d'attributs</li>
651
- <li><code>product.attribute_set.*</code> : attribut du jeu d'attributs (ex: <code>product.attribute_set.attribute_set_name</code>)</li>
652
- </ul>
653
- </li>
654
- <li><code>product.stock.*</code> : attribut du stock du produit<br/>Attributs intéressants :
655
- <ul>
656
- <li><code>is_in_stock</code> : disponibilité du produit</li>
657
- <li><code>qty</code> : stock du produit</li>
658
- <li>…</li>
659
- </ul>
660
- </li>
661
- </ul>
662
- </li>
663
- </ul>
664
- </div>
665
-
666
- <div id="formulas_variables_for_foreach">
667
- <h4>Variables utilisables dans les boucles <code>foreach</code></h4>
668
-
669
- <p>Les variables suivantes peuvent être utilisées dans les <a href="#formulas_foreach">boucles <code>foreach</code></a>.</p>
670
-
671
- <ul>
672
- <li><code>{selection.weight}</code> : poids de la sélection</li>
673
- <li><code>{selection.qty}</code> : nombre d'articles dans la sélection</li>
674
- </ul>
675
- <p>
676
- Lorsque la sélection se fait sur le sku, chaque sélection est composée d'un seul article.
677
- On peut donc utiliser les <a href="#formulas_variables_for_special_functions">variables article et produit</a>.
678
- </p>
679
- <ul>
680
- <li><code>{item.*}</code> : propriété de l'article</li>
681
- <li><code>{product.*}</code> : propriété du produit</li>
682
- </ul>
683
- <p class="alert alert-info">
684
- Les variables article et produit sont identiques aux <a href="#formulas_variables_for_special_functions">variables utilisables dans les fonctions spéciales</a> à la seule différence qu'elles doivent être entourées par les caractères <code>{</code> et <code>}</code>.
685
- </p>
686
- </div>
687
- </div>
688
-
689
- <div id="formulas_functions">
690
- <h3>Les fonctions</h3>
691
-
692
- <h4>Les fonctions numériques</h4>
693
- <ul>
694
- <li><code>abs(x)</code> : valeur absolue</li>
695
- <li><code>ceil(x)</code> : arrondi supérieur</li>
696
- <li><code>exp(x)</code> : exponentiel</li>
697
- <li><code>floor(x)</code> : arrondi inférieur</li>
698
- <li><code>log(x)</code> : logarithme népérien</li>
699
- <li><code>log(x, base)</code> : logarithme</li>
700
- <li><code>max(x, y, …)</code> : maximum, valeurs nulles ignorées</li>
701
- <li><code>min(x, y, …)</code> : minimum, valeurs nulles ignorées</li>
702
- <li><code>pi()</code> : nombre PI</li>
703
- <li><code>pow(x, puissance)</code> : puissance </li>
704
- <li><code>rand(min, max)</code> : entier aléatoire</li>
705
- <li><code>round(x)</code> : arrondi</li>
706
- <li><code>sqrt(x)</code> : racine carrée</li>
707
- </ul>
708
-
709
- <h4>Les fonctions pour manipuler des chaînes de caractères</h4>
710
- <ul>
711
- <li><code>substr(string, start, length)</code> : retourne un segment de chaîne de caractères.</li>
712
- </ul>
713
-
714
- <h4>Les fonctions pour manipuler des tableaux</h4>
715
- <ul>
716
- <li><code>in_array(value, array(value1, value2, …))</code> : retourne vrai si la valeur se trouve dans le tableau.</li>
717
- <li><code>array_match_any(array(value1, value2, …), array(value1, value2, …))</code> : retourne vrai si au moins une valeur est présente dans les deux tableaux.</li>
718
- <li><code>array_match_all(array(value1, value2, …), array(value1, value2, …))</code> : retourne vrai si le contenu des tableaux est identique.</li>
719
- </ul>
720
-
721
- <h4>Fonctions diverses</h4>
722
- <ul>
723
- <li><code>range(value, min, max, include_min, include_max)</code> : retourne vrai si <code>value</code> est comprise entre <code>min</code> et <code>max</code>. Par défaut, <code>include_min</code> et <code>include_max</code> sont égales à <code>true</code>.</li>
724
- </ul>
725
- </div>
726
-
727
- <div id="formulas_special_functions">
728
- <h3>Les fonctions spéciales</h3>
729
-
730
- <ul>
731
- <li><code>{table … in …}</code> : définit des valeurs en fonction de seuils (<a href="#examples_special_table">exemples</a>)</li>
732
- <li><code>{switch … in …}</code> : définit une table de correspondance (<a href="#examples_special_switch">exemples</a>)</li>
733
- </ul>
734
- <p>
735
- Le premier paramètre <code>…</code> des fonctions <code>table</code> et <code>switch</code> est la valeur de référence, il peut s'agir soit d'une variable, soit d'une formule.
736
- </p>
737
- <ul>
738
- <li><code>{count items[ where …]}</code> : compte les articles remplissant les conditions (<a href="#examples_special_count">exemples</a>)</li>
739
- <li><code>{count distinct …[ where …]}</code> : compte les différentes valeurs d'une propriété pour les articles remplissant les conditions (<a href="#examples_special_count_distinct">exemples</a>)</li>
740
- <li><code>{sum …[ where …]}</code> : calcule la somme des valeurs d'une propriété pour les articles remplissant les conditions (<a href="#examples_special_sum">exemples</a>)</li>
741
- <li><code>{min …[ where …]}</code> : retourne la valeur minimum d'une propriété pour les articles remplissant les conditions (<a href="#examples_special_min">exemples</a>)</li>
742
- <li><code>{max …[ where …]}</code> : retourne la valeur maximum d'une propriété pour les articles remplissant les conditions (<a href="#examples_special_max">exemples</a>)</li>
743
- </ul>
744
- <p>
745
- Le premier paramètre <code>…</code> des fonctions <code>count distinct</code>, <code>sum</code>, <code>min</code> et <code>max</code> doit être une propriété (ex: <code>product.attribute.weight</code>).
746
- </p>
747
- <p>La condition <code>where</code> est facultative. Si elle est spécifiée, elle le sera sous la forme d'une formule.</p>
748
- </div>
749
-
750
- <div id="formulas_foreach">
751
- <h3>Utilisation des boucles <code>foreach</code></h3>
752
-
753
- <p>
754
- Les boucles <code>foreach</code> permettent d'effectuer un calcul sur des groupes de produits plutôt que de tenir compte de tous les produits du panier.<br/>
755
- Le résultat global d'une boucle <code>foreach</code> est la somme des résultats de chaque passage dans la boucle.
756
- </p>
757
- <p>
758
- A l'intérieur d'une boucle <code>foreach</code>, il est possible d'utiliser de <a href="#formulas_variables_for_foreach">nouvelles variables</a>.
759
- </p>
760
- <p>
761
- <a href="#examples_using_foreach">Exemples</a>
762
- </p>
763
- </div>
764
-
765
- <div id="formulas_deprecated_variables">
766
- <h3>Les variables dépréciées</h3>
767
-
768
- <p>Les variables suivantes doivent être remplacées par leur équivalente.</p>
769
-
770
- <ul>
771
- <li><a href="#formulas_variables"><code><span class=strike>{cart.coupon}</span> {cart.coupon_code}</code></a></li>
772
- <li><a href="#formulas_variables"><code><span class=strike>{cart.quantity}</span> {cart.qty}</code></a></li>
773
- <li><a href="#formulas_variables"><code><span class=strike>{cart.price_excluding_tax}</span> {cart.price-tax+discount}</code></a></li>
774
- <li><a href="#formulas_variables"><code><span class=strike>{cart.price_including_tax}</span> {cart.price+tax+discount}</code></a></li>
775
- <li><a href="#formulas_variables"><code><span class=strike>{cart.weight.for-charge}</span> {cart.weight_for_charge}</code></a></li>
776
- <li><a href="#formulas_variables"><code><span class=strike>{cart.weight.unit}</span> {cart.weight_unit}</code></a></li>
777
- <li><a href="#formulas_variables"><code><span class=strike>{customer.group.code}</span> {customer_group.code}</code></a></li>
778
- <li><a href="#formulas_variables"><code><span class=strike>{customer.group.id}</span> {customer_group.id}</code></a></li>
779
- <li><a href="#formulas_variables"><code><span class=strike>{{customVar code=*}}</span> {customvar.*}</code></a></li>
780
- <li><a href="#formulas_variables"><code><span class=strike>{destination.country.code}</span> {shipto.country_id}</code></a></li>
781
- <li><a href="#formulas_variables"><code><span class=strike>{destination.country.name}</span> {shipto.country_name}</code></a></li>
782
- <li><a href="#formulas_variables"><code><span class=strike>{destination.postcode}</span> {shipto.postcode}</code></a></li>
783
- <li><a href="#formulas_variables"><code><span class=strike>{destination.region.code}</span> {shipto.region_code}</code></a></li>
784
- <li><a href="#formulas_variables"><code><span class=strike>{free_shipping}</span> {cart.free_shipping}</code></a></li>
785
- <li><a href="#formulas_variables"><code><span class=strike>{origin.country.code}</span> {origin.country_id}</code></a></li>
786
- <li><a href="#formulas_variables"><code><span class=strike>{origin.country.name}</span> {origin.country_name}</code></a></li>
787
- <li><a href="#formulas_variables"><code><span class=strike>{origin.region.code}</span> {origin.region_id}</code></a></li>
788
- <li><a href="#formulas_variables_for_foreach"><code><span class=strike>{selection.quantity}</span> {selection.qty}</code></a></li>
789
- </ul>
790
- <ul>
791
- <li><a href="#formulas_variables_for_special_functions"><code><span class=strike>product.quantity</span> item.qty</code></a></li>
792
- <li><a href="#formulas_variables_for_special_functions"><code><span class=strike>product.price-tax+discount</span> item.price-tax+discount</code></a></li>
793
- <li><a href="#formulas_variables_for_special_functions"><code><span class=strike>product.price-tax-discount</span> item.price-tax-discount</code></a></li>
794
- <li><a href="#formulas_variables_for_special_functions"><code><span class=strike>product.price+tax+discount</span> item.price+tax+discount</code></a></li>
795
- <li><a href="#formulas_variables_for_special_functions"><code><span class=strike>product.price+tax-discount</span> item.price+tax-discount</code></a></li>
796
- <li><a href="#formulas_variables_for_special_functions"><code><span class=strike>product.option.*</span> item.option.*</code></a></li>
797
- <li><a href="#formulas_variables_for_special_functions"><code><span class=strike>product.option.*</span> item.option.*</code></a></li>
798
- </ul>
799
- </div>
800
- </div>
801
-
802
- <div id="more">
803
- <h2>Divers</h2>
804
-
805
- <div id="more_tracking_url">
806
- <h3>L'URL de suivi <code>tracking_url</code></h3>
807
-
808
- <p class="alert alert-danger">
809
- L'utilisation de la propriété <code>tracking_url</code> est réservée aux utilisateurs expérimentés. Si vous ne comprenez pas les indications ci-dessous, il est préférable que vous évitiez d'utiliser cette fonctionnalité.
810
- </p>
811
- <p>
812
- La propriété <code>tracking_url</code> permet de surcharger le champ "URL de suivi" d'un mode de livraison Owebia-Shipping et ainsi de spécifier une URL de suivi <strong>par méthode de livraison</strong> plutôt qu'une pour tout le mode de livraison.
813
- </p>
814
- <p>
815
- Pour insérer automatiquement le numéro de colis dans l'URL de suivi, vous devez utiliser <code>{tracking_number}</code>.
816
- </p>
817
-
818
- <div class="json">{
819
- "__auto__":{"label":"Exemple avec URL de suivi pour le transporteur Colissimo","fees":10,"tracking_url":"http://www.coliposte.net/particulier/suivi_particulier.jsp?colispart={tracking_number}"}
820
- }</div>
821
-
822
- <p>
823
- Magento ne gère pas les liens de tracking mais un statut de tracking. L'extension Owebia-Shipping fournit un lien HTML à la place du statut, lien qui permet d'aller sur le site du transporteur et de suivre l'avancement de la livraison du colis.
824
- </p>
825
- <p>
826
- Lorsque l'URL de suivi est construite par l'extension, la seule information disponible est le numéro de colis et on n'a nul part accès à la méthode de livraison sélectionnée. Afin de pouvoir retrouver l'url de suivi dans la configuration, il faut spécifier la méthode de livraison dans le numéro de tracking, par exemple : <code>colissimo:8Lxxxxxxxxxxx</code> où <code>colissimo</code> est le code de la méthode de livraison sélectionnée.<br/>
827
- Si aucun code n'est spécifié (si vous saisissez uniquement le numéro de tracking), l'url utilisée sera celle globale au mode de livraison.
828
- </p>
829
- <p class="alert alert-danger">
830
- Pour répondre à une question récurrente, Magento affiche le statut de livraison depuis le back office ou le front office. Si vous souhaitez insérer l'URL de suivi dans les mails d'expédition, <strong>vous devrez développer vous même</strong> la récupération de l'URL de suivi et son insertion dans le mail, en effet, l'extension Owebia-Shipping se contente de fournir des modes de livraison paramétrables sans apporter de grande modification au coeur de Magento afin de réduire les problèmes d'incompatibilité et de mise à jour.
831
- </p>
832
- <p class="alert alert-danger">
833
- Si vous obtenez un popup vide lorsque vous cliquez sur le lien de suivi, votre problème est très certainement lié au fait que vous n'avez pas spécifié le code de la méthode de livraison dans le numéro de suivi (voir indications plus haut) et que votre champ global "URL de suivi" est vide.
834
- </p>
835
- <p class="alert alert-danger">Il n'est actuellement pas prévu de modifier les fonctionnalitées de l'extension liées à l'URL de suivi.</p>
836
- </div>
837
- </div>
838
-
839
- <div id="changelog">
840
- <h2>Changelog</h2>
841
-
842
- <pre class=changelog>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
843
  [2.5.18 - 24 juillet 2014]
844
  Pas de modification, nouvelle version pour Magento Connect
845
 
@@ -930,8 +952,8 @@ Mise à jour de la syntaxe de la configuration par défaut
930
  Modification de la syntaxe de la configuration pour la rendre 100% compatible JSON
931
  Refonte complète de l'éditeur
932
  Suppression de la compatibilité avec les propriétés dépréciées suivantes :
933
- 'fees_table', 'fees_formula', 'fixed_fees', 'reference_value', 'prices_range', 'weights_range', 'product_properties',
934
- 'free_shipping__fees_table', 'free_shipping__fees_formula', 'free_shipping__fixed_fees', 'free_shipping__label',
935
  Suppression de la compatibilité avec la désactivation d'une méthode de livraison à l'aide du caractère #
936
  Suppression de la compatibilité avec les mots réservés en majuscule : TABLE, SUM, COUNT, DISTINCT et IN
937
  Ajout des fonctions array_match_any et array_match_all
@@ -956,9 +978,9 @@ Correction du code PHP pour supprimer des erreurs E_STRICT
956
  Correction d'un bug dans l'utilisation de la fonction {table ... in ...} : lorsque la variable de référence est indéfinie, le résultat était invalide (valeur précédente de la variable $replacement)
957
  Correction d'un problème avec les produits packagés (bundle product) : les produits 'bundle' et les produits 'simple' étaient tous deux récupérés ce qui faussait les résultats
958
  Support des sets d'attributs
959
- product.attribute_set dans les conditions de boucle foreach
960
- {product.attribute_set} et {product.attribute_set.id} comme variables dans les boucles foreach
961
- product.attribute_set, product.attribute_set.id dans les conditions des opérations sum, count, min et max
962
  Optimisation du chargement de certaines valeurs (catégories, attribute set, ...)
963
  Correction d'un problème avec les castings successifs (string), (float) qui posent problème lorsque la locale utilise la virgule comme séparateur de décimales
964
 
@@ -985,18 +1007,18 @@ Initialisation des formules sum et count à 0 au lieu de null (pour éviter les
985
  Ajout des alias &quot;a&quot; et &quot;attr&quot; pour &quot;attribute&quot;, &quot;o&quot; et &quot;opt&quot; pour &quot;option&quot;, &quot;p&quot; pour &quot;product&quot;, &quot;c&quot; pour &quot;cart&quot;, &quot;s&quot; pour &quot;selection&quot;
986
  Correction de la récupération des variables personnalisées : getValue('text') au lieu de getValue('plain')
987
  Support des catégories
988
- product.categories dans les conditions de boucle foreach
989
- {product.category} et {product.category.id} comme variables dans les boucles foreach
990
- product.category, product.category.id, product.categories, product.categories.id dans les conditions des opérations sum, count, min et max
991
  Amélioration du debug
992
 
993
  [2.4.1 - 24 août 2011]
994
  Modification légère du code php pour éviter un plantage avec certaines versions d'eAccelerator (cache php)
995
- $row = null;
996
- $this-&gt;addMessage('info',$row,null,'Ignored lines %s','&lt;div class=&quot;code&quot;&gt;'.trim($config_string).'&lt;/div&gt;');
997
- au lieu de ;
998
- $this-&gt;addMessage('info',$row=null,null,'Ignored lines %s','&lt;div class=&quot;code&quot;&gt;'.trim($config_string).'&lt;/div&gt;');
999
- (cf http://www.magentocommerce.com/boards/viewthread/233202/)
1000
  Ajout des variables de debug &quot;info.server.os&quot; et &quot;info.server.software&quot;
1001
  Ajout de la possibilité de récupérer la valeur minimum ou maximum de la quantité (ex: &quot;{max product.quantity}&quot;)
1002
 
@@ -1223,295 +1245,295 @@ Corrections de bugs
1223
  [2.0 - 3 avril 2009]
1224
  Création de la version 2.0 du module Owebia Shipping qui n'est plus compatible avec les anciennes versions
1225
 
1226
- </pre>
1227
- </div>
1228
-
1229
- <div id="index">
1230
- <h2>Index</h2>
1231
- <div class="panel">
1232
- <div class="row">
1233
- <div class="col-lg-6">
1234
- <h3>A</h3>
1235
- <ul>
1236
- <li><code>about</code> : <a href="#property_about">propriété</a></li>
1237
- <li>activation : voir <code>enabled</code></li>
1238
- <li>adresse d'envoi : voir <code>origin</code></li>
1239
- <li>adresse de facturation : voir <code>billto</code></li>
1240
- <li>adresse de livraison : voir <code>shipto</code></li>
1241
- <li><code>address_filter</code> : <a href="#address_filter">raccourci</a>, <a href="#examples_using_address_filters_shortcuts">exemples</a></li>
1242
- <li>attribut produit : voir <code>product.attribute.*</code></li>
1243
- </ul>
1244
-
1245
- <h3>B</h3>
1246
- <ul>
1247
- <li><code>billto</code> :
1248
- <ul>
1249
- <li><a href="#property_billto">propriété</a></li>
1250
- <li><a href="#formulas_variables_billto">variables</a></li>
1251
- </ul>
1252
- </li>
1253
- <li>bon de commande : voir <code>quote</code></li>
1254
- </ul>
1255
-
1256
- <h3>C</h3>
1257
- <ul>
1258
- <li><code>cart</code> : <a href="#formulas_variables_cart">variables</a></li>
1259
- <li>commentaire : voir <code>about</code></li>
1260
- <li><code>conditions</code> : <a href="#property_conditions">propriété</a></li>
1261
- <li><code>count</code> : <a href="#formulas_special_functions">fonction spéciale</a></li>
1262
- <li><code>count distinct</code> : <a href="#formulas_special_functions">fonction spéciale</a></li>
1263
- <li><code>customer</code> : <a href="#formulas_variables_customer">variables</a></li>
1264
- <li><code>customer_group</code> : <a href="#formulas_variables_customer_group">variables</a></li>
1265
- <li><code>customer_groups</code> : <a href="#property_customer_groups">propriété</a></li>
1266
- <li><code>customvar</code> : <a href="#formulas_variables_customvar">variables</a></li>
1267
- </ul>
1268
-
1269
- <h3>D</h3>
1270
- <ul>
1271
- <li><code>data</code> : <a href="#definitions_element">type d'élément</a>, <a href="#examples_data">exemples</a></li>
1272
- <li><code>date</code> : <a href="#formulas_variables_date">variables</a></li>
1273
- <li>désactivation : voir <code>enabled</code></li>
1274
- <li><code>description</code> : <a href="#property_description">propriété</a></li>
1275
- <li>destination : voir <code>shipto</code></li>
1276
- <li>DOM/TOM : <a href="#examples_excluding_domtom_postcode">exclusion des codes postaux</a></li>
1277
- </ul>
1278
-
1279
- <h3>E</h3>
1280
- <ul>
1281
- <li>élément : <a href="#definitions_element">définition</a></li>
1282
- <li><code>enabled</code> : <a href="#property_enabled">propriété</a></li>
1283
- <li>expression régulière : voir la propriété <code>shipto</code></li>
1284
- </ul>
1285
-
1286
- <h3>F</h3>
1287
- <ul>
1288
- <li><code>fees</code> : <a href="#property_fees">propriété</a></li>
1289
- <li><a href="#formulas_functions">Fonctions</a></li>
1290
- <li><code>foreach</code> : <a href="#formulas_foreach">boucle</a>, <a href="#examples_using_foreach">exemples</a></li>
1291
- <li><a href="#formulas">Formules</a></li>
1292
- <li>frais de port : voir <code>fees</code></li>
1293
- </ul>
1294
-
1295
- <h3>G</h3>
1296
- <ul>
1297
- <li>gratuit : voir "port offert"</li>
1298
- <li>groupes client : voir <code>customer_groups</code></li>
1299
- </ul>
1300
-
1301
- <h3>I</h3>
1302
- <ul>
1303
- <li>identifiant unique : <a href="#definitions_unique_id">définition</a></li>
1304
- <li><code>item</code> : <a href="#formulas_variables_item">variables</a></li>
1305
- <li><code>item.option.*</code> : <a href="#formulas_variables_item">variables</a></li>
1306
- </ul>
1307
- </div>
1308
- <div class="col-lg-6">
1309
- <h3>L</h3>
1310
- <ul>
1311
- <li><code>label</code> : <a href="#property_label">propriété</a></li>
1312
- </ul>
1313
-
1314
- <h3>M</h3>
1315
- <ul>
1316
- <li><code>max</code> :
1317
- <ul>
1318
- <li><a href="#formulas_functions">fonction</a></li>
1319
- <li><a href="#formulas_special_functions">fonction spéciale</a>, <a href="#examples_special_max">exemples</a></li>
1320
- </ul>
1321
- </li>
1322
- <li><code>meta</code> : <a href="#definitions_element">type d'élément</a>, <a href="#examples_meta">exemples</a></li>
1323
- <li><code>method</code> : <a href="#definitions_element">type d'élément</a></li>
1324
- <li><code>min</code> :
1325
- <ul>
1326
- <li><a href="#formulas_functions">fonction</a></li>
1327
- <li><a href="#formulas_special_functions">fonction spéciale</a>, <a href="#examples_special_min">exemples</a></li>
1328
- </ul>
1329
- </li>
1330
- </ul>
1331
-
1332
- <h3>O</h3>
1333
- <ul>
1334
- <li>offert : voir "port offert"</li>
1335
- <li>option produit : voir <code>item.option.*</code></li>
1336
- <li><code>origin</code> :
1337
- <ul>
1338
- <li><a href="#property_origin">propriété</a></li>
1339
- <li><a href="#formulas_variables_origin">variables</a></li>
1340
- </ul>
1341
- </li>
1342
- </ul>
1343
-
1344
- <h3>P</h3>
1345
- <ul>
1346
- <li>panier : voir <code>cart</code></li>
1347
- <li>port offert : <a href="#examples_simple">exemples</a></li>
1348
- <li><code>product</code> : <a href="#formulas_variables_product">variables</a></li>
1349
- <li><code>product.attribute.*</code> : <a href="#formulas_variables_product">variables</a></li>
1350
- <li><code>product.categories</code> : <a href="#formulas_variables_product">variables</a>, <a href="#examples_product_categories">exemples</a></li>
1351
- <li>propriété : <a href="#definitions_property">définition</a></li>
1352
- </ul>
1353
-
1354
- <h3>Q</h3>
1355
- <ul>
1356
- <li><code>quote</code> : <a href="#formulas_variables_quote">variables</a></li>
1357
- </ul>
1358
-
1359
- <h3>R</h3>
1360
- <ul>
1361
- <li><code>request</code> : <a href="#formulas_variables_request">variables</a></li>
1362
- </ul>
1363
-
1364
- <h3>S</h3>
1365
- <ul>
1366
- <li><code>shipto</code> :
1367
- <ul>
1368
- <li><a href="#property_shipto">propriété</a>, <a href="#examples_using_address_filters">exemples</a></li>
1369
- <li><a href="#formulas_variables_shipto">variables</a></li>
1370
- </ul>
1371
- </li>
1372
- <li><code>store</code> : <a href="#formulas_variables_store">variables</a></li>
1373
- <li><code>sum</code> : <a href="#formulas_special_functions">fonction spéciale</a></li>
1374
- <li><code>switch</code> : <a href="#formulas_special_functions">fonction spéciale</a>, <a href="#examples_special_switch">exemples</a></li>
1375
- </ul>
1376
-
1377
- <h3>T</h3>
1378
- <ul>
1379
- <li><code>table</code> : <a href="#formulas_special_functions">fonction spéciale</a>, <a href="#examples_special_table">exemples</a></li>
1380
- <li>table de correspondance&nbsp;: voir <code>switch</code></li>
1381
- <li>titre&nbsp;: voir <code>label</code></li>
1382
- <li><code>tracking_url</code>&nbsp;: <a href="#property_tracking_url">propriété</a>, <a href="#more_tracking_url">plus d'informations</a></li>
1383
- <li><code>type</code>&nbsp;: <a href="#property_type">propriété</a></li>
1384
- </ul>
1385
-
1386
- <h3>U</h3>
1387
- <ul>
1388
- <li>URL de suivi&nbsp;: voir <code>tracking_url</code></li>
1389
- </ul>
1390
-
1391
- <h3>V</h3>
1392
- <ul>
1393
- <li>Variables : <a href="#formulas_variables">disponibles</a>, <a href="#formulas_deprecated_variables">dépréciées</a></li>
1394
- <li>Variables personnalisées de Magento : voir <code>customvar</code></li>
1395
- </ul>
1396
- </div>
1397
- </div>
1398
- </div>
1399
- </div>
1400
- <!-- doc content end -->
1401
- </div>
1402
- </div>
1403
  </div>
1404
  <script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
1405
  <script src="http://netdna.bootstrapcdn.com/bootstrap/3.0.0-rc1/js/bootstrap.min.js"></script>
1406
  <script>
1407
  <!-- doc scripts start -->
1408
  function jsonEncode(data, beautify, html, level, current_indent) {
1409
- if (typeof beautify == 'undefined') beautify = false;
1410
- if (typeof html == 'undefined') html = false;
1411
- if (typeof level == 'undefined') level = 0;
1412
- if (typeof current_indent == 'undefined') current_indent = '';
1413
-
1414
- var indent = html ? '&nbsp;&nbsp;&nbsp;' : "\t";
1415
- var line_break = html ? '<br/>' : "\n";
1416
- var new_indent = current_indent + indent;
1417
- switch (typeof(data)) {
1418
- case 'undefined':
1419
- return (html ? '<span class=json-reserved>' : '') + 'null' + (html ? '</span>' : '');
1420
- case 'boolean':
1421
- return (html ? '<span class=json-reserved>' : '') + (data ? 'true' : 'false') + (html ? '</span>' : '');
1422
- case 'number':
1423
- return (html ? '<span class=json-numeric>' : '') + data + (html ? '</span>' : '');
1424
- case 'string':
1425
- var output = JSON.stringify(data);
1426
- return html ? '<span class=json-string>' + output + '</span>' : output;
1427
- case 'object':
1428
- var output_index_count = 0;
1429
- var output = [];
1430
- for (var key in data) {
1431
- var value = data[key];
1432
- if (output_index_count!==null && output_index_count++!==key) {
1433
- output_index_count = null;
1434
- }
1435
- }
1436
- var is_associative = output_index_count===null;
1437
- for (var key in data) {
1438
- var value = data[key];
1439
- if (is_associative) {
1440
- var classes = [];
1441
- if (key=='about') classes.push('json-about');
1442
- if (key=='conditions' || key=='fees') classes.push('json-formula');
1443
- var property_classes = ['json-property'];
1444
- if (level==0) property_classes.push('json-id');
1445
- output.push(
1446
- (html && classes.length ? '<span class="' + classes.join(' ') + '">' : '')
1447
- + (html ? '<span' + (property_classes.length ? ' class="' + property_classes.join(' ') + '"' : '') + '>' : '')
1448
- + jsonEncode('' + key)
1449
- + (html ? '</span>' : '') + ':'
1450
- + (beautify ? ' ' : '')
1451
- + jsonEncode(value, beautify, html, level+1, new_indent)
1452
- + (html && classes.length ? '</span>' : '')
1453
- );
1454
- } else {
1455
- output.push(jsonEncode(value, beautify, html, level+1, current_indent));
1456
- }
1457
- }
1458
- if (is_associative) {
1459
- var classes = [];
1460
- if (data.type == 'meta') classes.push('json-meta');
1461
- output = (html && classes.length ? '<span class="' + classes.join(' ') + '">' : '')
1462
- + '{'
1463
- + (beautify ? line_break + new_indent : '')
1464
- + output.join(',' + (beautify ? line_break + new_indent : ''))
1465
- + (beautify ? line_break + current_indent : '')
1466
- + '}'
1467
- + (html && classes.length ? '</span>' : '');
1468
- return output;
1469
- } else {
1470
- return '[' + output.join(',' + (beautify ? ' ' : '')) + ']';
1471
- }
1472
- default:
1473
- return ''; // Not supported
1474
- }
1475
  }
1476
 
1477
  $(function(){
1478
- var navHeight = $('.navbar').outerHeight(true) + 10;
1479
-
1480
- $('a[href^="#"]').click(function (e) {
1481
- $('.highlight').removeClass('highlight');
1482
- var anchor = $(this).attr('href').replace('#', '');
1483
- window.location.hash = '#' + anchor;
1484
- var jelem = $('#' + anchor);
1485
- jelem.addClass('highlight');
1486
- $('body,html').scrollTop(Math.round(jelem.offset().top - navHeight + 10));
1487
- e.preventDefault()
1488
- });
1489
-
1490
- $('a[href^="#"]').each(function (e) {
1491
- var anchor = $(this).attr('href').replace('#', '');
1492
- if (anchor == '') return;
1493
- var jelem = $('#' + anchor);
1494
- if (!jelem.length) {
1495
- $(this).css('border', 'solid 1px red').css('padding', 3);
1496
- }
1497
- });
1498
-
1499
- var index = 0;
1500
- $('div.json').each(function(){
1501
- var text = $(this).text();
1502
- while (text.match(/"__auto__"/)) {
1503
- text = text.replace(/"__auto__"/, '"id_' + ('000' + index).slice(-3) + '"');
1504
- index++;
1505
- }
1506
- var obj = $.parseJSON(text);
1507
- var beautified = jsonEncode(obj, true, true);
1508
- $(this).html('<pre>' + beautified + '</pre>');
1509
- $(this).addClass('code');
1510
- });
1511
- $('body').scrollspy({
1512
- target: '.sidebar',
1513
- offset: navHeight
1514
- });
1515
 
1516
  });
1517
  <!-- doc scripts end -->
2
  <html>
3
  <head lang="fr">
4
  <meta charset="utf-8"/>
5
+ <title>Documentation de l'extension Owebia-Shipping 2.5.22</title>
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
  <link href="http://netdna.bootstrapcdn.com/bootstrap/3.0.0-rc1/css/bootstrap.min.css" rel="stylesheet">
8
  <style>
39
  .sidebar .nav .nav {display: none; /* Hide by default, but at >768px, show it */margin-bottom: 8px;}
40
  .sidebar .nav .nav > li > a {padding-top:3px;padding-bottom:3px;padding-left:30px;font-size:90%;}
41
  @media screen and (min-width: 768px) {
42
+ .sidebar{display:block}
43
+ .sidebar .nav > .active > ul {display:block}
44
+ .bs-navbar-top-example .navbar-fixed-top,
45
+ .bs-navbar-bottom-example .navbar-fixed-bottom {position:absolute}
46
  }
47
  @media screen and (min-width: 992px) {
48
+ .sidebar.affix,
49
+ .sidebar.affix-bottom {width:213px}
50
+ .sidebar.affix {position:fixed;top:80px}
51
+ .sidebar.affix-bottom {position:absolute}
52
+ .sidebar.affix-bottom .sidenav,
53
+ .sidebar.affix .sidenav {margin-top:0;margin-bottom:0}
54
  }
55
  @media screen and (min-width: 1200px) {
56
+ .sidebar.affix-bottom,
57
+ .sidebar.affix {width:270px}
58
  }
59
  </style>
60
  </head>
61
  <body>
62
  <div class="navbar navbar-inverse navbar-fixed-top">
63
+ <div class="container">
64
+ <a href="http://www.owebia.com" class="navbar-brand">Owebia</a>
65
+ <ul class="nav navbar-nav">
66
+ </ul>
67
+ </div>
68
  </div>
69
  <div class="container">
70
+ <div class="row">
71
+ <div class="col-lg-3">
72
+ <div class="affix sidebar">
73
+ <!-- doc sidebar start -->
74
+ <ul class="nav sidenav">
75
+ <li><a href="#introduction">Introduction</a></li>
76
+ <li><a href="#examples">Exemples</a>
77
+ <ul class="nav">
78
+ <li><a href="#examples_simple">Exemple simple : port offert</a></li>
79
+ <li><a href="#examples_using_address_filters">Frais relatifs à la destination</a></li>
80
+ <li><a href="#examples_using_customer_groups">Frais relatifs au groupe client</a></li>
81
+ <li><a href="#examples_using_formulas">Utiliser les formules</a></li>
82
+ <li><a href="#examples_using_special_functions">Utiliser les fonctions spéciales</a></li>
83
+ <li><a href="#examples_using_foreach">Utiliser les boucles <code>{foreach …}</code></a></li>
84
+ <li><a href="#examples_using_array_functions">Manipuler les tableaux</a></li>
85
+ <li><a href="#examples_more">Autres exemples</a></li>
86
+ </ul>
87
+ </li>
88
+ <li><a href="#definitions">Définitions</a>
89
+ <ul class="nav">
90
+ <li><a href="#definitions_element">Les éléments</a></li>
91
+ <li><a href="#definitions_property">Les propriétés</a></li>
92
+ <li><a href="#definitions_unique_id">L'identifiant unique</a></li>
93
+ </ul>
94
+ </li>
95
+ <li><a href="#formulas">Les formules</a>
96
+ <ul class="nav">
97
+ <li><a href="#formulas_variables">Les variables</a></li>
98
+ <li><a href="#formulas_functions">Les fonctions</a></li>
99
+ <li><a href="#formulas_special_functions">Les fonctions spéciales</a></li>
100
+ <li><a href="#formulas_foreach">Les boucles <code>foreach</code></a></li>
101
+ <li><a href="#formulas_deprecated_variables">Les variables dépréciées</a></li>
102
+ </ul>
103
+ </li>
104
+ <li><a href="#more">Divers</a>
105
+ <ul class="nav">
106
+ <li><a href="#more_tracking_url">L'URL de suivi</a></li>
107
+ </ul>
108
+ </li>
109
+ <li><a href="#changelog">Changelog</a></li>
110
+ <li><a href="#index">Index</a></li>
111
+ </ul>
112
+ <!-- doc sidebar end -->
113
+ </div>
114
+ </div>
115
+ <div class="col-lg-9">
116
+ <!-- doc content start -->
117
+ <h1>Documentation de l'extension Owebia-Shipping 2.5.20 pour Magento</h1>
118
+ <div id="introduction">
119
+ <h2>Introduction</h2>
120
+
121
+ <p>Owebia-Shipping est une extension pour la solution de e-commerce <a href="http://www.magentocommerce.com/" target="_blank">Magento</a>.</p>
122
+ <p>Grace à sa syntaxe au format <a href="http://fr.wikipedia.org/wiki/JavaScript_Object_Notation" target=_blank>JSON</a>, cette extension permet une grande souplesse dans le paramétrage des frais de livraison.</p>
123
+
124
+ <p>Cette documentation explique comment créer une configuration pour l'un des modes de livraison proposé par l'extension.</p>
125
+
126
+ <p class="alert alert-info">Nouvelle documentation, plus simple et plus claire.<br/>
127
+ <strong>Utilisez l'<a href="#index">index</a></strong> pour vous retrouver plus facilement dans la documentation.</p>
128
+ </div>
129
+
130
+ <div id="examples">
131
+ <h2>Exemples</h2>
132
+
133
+ <div id="examples_simple">
134
+ <h3>Exemple simple : port offert</h3>
135
+ <div class="json">{
136
+ "__auto__":{"label":"Livraison gratuite","fees": 0}
137
+ }</div>
138
+ </div>
139
+
140
+ <div id="examples_using_address_filters">
141
+ <h3>Frais relatifs à la destination</h3>
142
+ <div class="json">{
143
+ "__auto__":{"label":"France, Allemagne, Suisse, Espagne, Italie","shipto":"FR,DE,CH,ES,IT","fees":10},
144
+ "__auto__":{"label":"France sauf la Corse","shipto":"FR-(2A,2B)","fees":10},
145
+ "__auto__":{"label":"Corse","shipto":"FR(2A,2B)","fees":10},
146
+ "__auto__":{"label":"Monde entier sauf l'Allemagne et la Corse","shipto":"* - ( DE, FR(2A,2B) )","fees":10}
147
+ }</div>
148
+
149
+ <h4>Utiliser le caractère jocker <code>*</code> ou les expressions régulières</h4>
150
+ <div class="json">{
151
+ "__auto__":{"label":"Caractère jocker autorisant les codes postaux commençant par 25","shipto":"FR(25*)","fees":10},
152
+ "__auto__":{"label":"Expression régulière acceptant les codes postaux commençant par 'PO', 'po', 'Po' ou 'pO'","shipto":"GB(/^PO.*$/i)","fees":10}
153
+ }</div>
154
+
155
+ <div id="examples_excluding_domtom_postcode">
156
+ <h4>Bloquer la livraison vers la France mais avec un code postal DOM/TOM</h4>
157
+ <p>Avec l'expression régulière suivante, vous bloquez les codes postaux commançant par 97 ou 98 (avec ou sans zéros et espaces intercalés).</p>
158
+ <div class="json">{
159
+ "__auto__":{"label":"Expression régulière refusant les codes postaux commençant par 97 et 98","shipto":"FR-(/^[0\\s]*9\\s*[78].*/)","fees":10}
160
+ }</div>
161
+ </div>
162
+
163
+ <div id="examples_using_address_filters_shortcuts">
164
+ <h4>Utilisation des raccourcis <code>address_filter</code></h4>
165
+ <div class="json">{
166
+ "__auto__":{"label":"Europe sauf la France","shipto":"({address_filter.EU-27}) - (FR)","fees":10}
167
+ }</div>
168
+ </div>
169
+ </div>
170
+
171
+ <div id="examples_using_customer_groups">
172
+ <h3>Frais relatifs au groupe client</h3>
173
+ <p>On peut utiliser le nom ou l'ID des groupes client.</p>
174
+ <div class="json">{
175
+ "__auto__":{"label":"Groupes NOT LOGGED IN et General","customer_groups":"NOT LOGGED IN,General","fees":10},
176
+ "__auto__":{"label":"Groupes NOT LOGGED IN et General par leur ID","customer_groups":"0,1","fees":10},
177
+ "__auto__":{"label":"Groupe Retailer","customer_groups":"Retailer","fees":10}
178
+ }</div>
179
+ </div>
180
+
181
+ <div id="examples_using_formulas">
182
+ <h3>Utiliser les formules</h3>
183
+ <p>Les formules peuvent être utilisées dans les propriétés <code>conditions</code> et <code>fees</code>.</p>
184
+ <div class="json">{
185
+ "__auto__":{"label":"Livraison","fees":"0.1 * {cart.price-tax+discount} + 10.00"}
186
+ }</div>
187
+
188
+ <h4>Copier la propriété d'un autre élément</h4>
189
+ <div class="json">{
190
+ "standard":{"label":"Livraison standard","conditions":"{cart.price-tax+discount} < 1000.00","fees":10},
191
+ "express":{"label":"Livraison express","conditions":"( {standard.conditions} ) && ( {cart.weight} < 10 )","fees":12}
192
+ }</div>
193
+
194
+ <h4>Utiliser la fonction <code>min()</code></h4>
195
+ <div class="json">{
196
+ "__auto__":{"label":"Livraison","fees":"min({cart.weight}, {cart.price+tax+discount}, {cart.qty})"}
197
+ }</div>
198
+
199
+ <h4>Utiliser la fonction <code>range()</code></h4>
200
+ <div class="json">{
201
+ "__auto__":{"label":"Livraison","conditions":"range({cart.weight}, 1.0, 3.0)","fees":10}
202
+ }</div>
203
+
204
+ <h4>Utiliser la fonction <code>substr()</code></h4>
205
+ <p>Une variable de type chaîne de caractères doit être entourée par des guillemets simples sauf si on utilise l'auto-échappement avec les caractères <code>{{</code> et <code>}}</code>.</p>
206
+ <div class="json">{
207
+ "__auto__":{"label":"Sans utiliser l'auto-échappement","conditions":"substr('{cart.coupon_code}', 0, 5)=='free_'","fees":10},
208
+ "__auto__":{"label":"En utilisant l'auto-échappement","conditions":"substr({{cart.coupon_code}}, 0, 5)=='free_'","fees":10}
209
+ }</div>
210
+
211
+ </div>
212
+
213
+ <div id="examples_using_special_functions">
214
+ <h3>Utiliser les fonctions spéciales</h3>
215
+
216
+ <div id="examples_special_table">
217
+ <h4>Utilisation de la fonction spéciale <code>{table … in …}</code></h4>
218
+ <div class="json">{
219
+ "__auto__":{"label":"Livraison","fees":"{table {cart.weight} in 0.5:5.30, 1.0:6.50, 2.0:7.40, 3.0:8.30, 5.0:10.10}"}
220
+ }</div>
221
+ <p>
222
+ Dans une <code>table</code>, on peut inclure ou exclure une valeur limite avec les caractères <code>[</code> et <code>]</code> :
223
+ </p>
224
+ <div class="json">{
225
+ "__auto__":{"label":"Limite supérieure incluse","fees":"{table {cart.weight} in 1.0]:5.00}"},
226
+ "__auto__":{"label":"Limite supérieure exclue","fees":"{table {cart.weight} in 1.0[:5.00}"}
227
+ }</div>
228
+
229
+ <p>
230
+ Dans une <code>table</code>, on doit spécifier la valeur de référence. Pour cela, on peut utiliser une des <a href="#formulas_variables">variables</a> disponibles.<br/>
231
+ On peut aussi utiliser une formule afin de définir une autre variable de référence.
232
+ </p>
233
+
234
+ <div class="json">{
235
+ "__auto__":{"label":"Table avec poids du panier","fees":"{table {cart.weight} in 0.5:5.30, 1.0:6.50}"},
236
+ "__auto__":{"label":"Table avec quantité d'articles","fees":"{table {cart.qty} in 10:5.30, 20:6.50}"},
237
+ "__auto__":{"label":"Table avec prix TTC","fees":"{table {cart.price+tax+discount} in 15.00:5.30, 30.00:6.50, *:10.00}"},
238
+ "__auto__":{"label":"Table avec prix HT","fees":"{table {cart.price-tax+discount} in 15.00:5.30, 30.00:6.50, *:10.00}"},
239
+ "__auto__":{"label":"Table avec valeur personnalisée","fees":"{table ceil({cart.weight}/10) in 1:5.30, 2:6.50}"}
240
+ }</div>
241
+ </div>
242
+
243
+ <div id="examples_special_switch">
244
+ <h4>Utilisation de la fonction spéciale <code>{switch … in …}</code> (table de correspondance)</h4>
245
+ <p>
246
+ Dans un <code>switch</code>, on doit spécifier la valeur de référence. Pour cela, on peut utiliser une des <a href="#formulas_variables">variables</a> disponibles.<br/>
247
+ On peut aussi utiliser une formule afin de définir une autre variable de référence.
248
+ </p>
249
+ <div class="json">{
250
+ "__auto__":{"label":"Switch avec code promo","fees":"{switch {{cart.coupon_code}} in 'coupon1':5.30, 'coupon2':6.50, null:10.00, *:7.50}"},
251
+ "__auto__":{"label":"Switch avec pays de livraison","fees":"{switch {{shipto.country_id}} in 'FR':5.30, 'BE':6.50, 'DE':10.00, *:7.50}"}
252
+ }</div>
253
+ </div>
254
+
255
+ <div id="examples_special_count">
256
+ <h4>Utiliser la fonction spéciale <code>{count …}</code></h4>
257
+ <div class="json">{
258
+ "__auto__":{"label":"Si au moins un produit possède l'attribut 'color' égal à 'Bleu'","conditions":"{count items where product.attribute.color=='Bleu'} > 0","fees":10},
259
+ "__auto__":{"label":"Si tous les produits possèdent l'option 'size' supérieure ou égal à '1'","conditions":"{count items where item.option.size>='1'} == {cart.qty}","fees":10}
260
+ }</div>
261
+
262
+ <p>
263
+ Si la propriété est de type <strong>Oui/Non</strong>, vous devez utiliser les valeurs <code>true</code>/<code>false</code> ou <code>1</code>/<code>0</code> sans les guillemets.
264
+ </p>
265
+ <div class="json">{
266
+ "__auto__":{"label":"Exemple propriété de type Oui/Non : 1","conditions":"{count items where product.attribute.colissimo_allowed==1}","fees":10},
267
+ "__auto__":{"label":"Exemple propriété de type Oui/Non : true","conditions":"{count items where product.attribute.colissimo_allowed==true}","fees":10}
268
+ }</div>
269
+ </div>
270
+
271
+ <div id="examples_special_count_distinct">
272
+ <h4>Utiliser la fonction spéciale <code>{count distinct …}</code></h4>
273
+ <div class="json">{
274
+ "__auto__":{"label":"Nombre de SKU différents","conditions":"{count distinct product.attribute.sku}","fees":10}
275
+ }</div>
276
+ </div>
277
+
278
+ <div id="examples_special_sum">
279
+ <h4>Utiliser la fonction spéciale <code>{sum …}</code></h4>
280
+ <div class="json">{
281
+ "__auto__":{"label":"Somme de toutes les options 'size' est supérieure à 30","conditions":"{sum item.option.size} > 30","fees":10}
282
+ }</div>
283
+ </div>
284
+
285
+ <div id="examples_special_min">
286
+ <h4>Utiliser la fonction spéciale <code>{min …}</code></h4>
287
+ <div class="json">{
288
+ "__auto__":{"label":"Prix HT sans remise minimum des articles dans le panier est supérieur à 10","conditions":"{min item.price-tax-discount} > 10","fees":10}
289
+ }</div>
290
+ </div>
291
+
292
+ <div id="examples_special_max">
293
+ <h4>Utiliser la fonction spéciale <code>{max …}</code></h4>
294
+ <div class="json">{
295
+ "__auto__":{"label":"Valeur maximum de l'option 'size' des articles dans le panier est inférieure à 50","conditions":"{max item.option.size} < 50","fees":10}
296
+ }</div>
297
+ </div>
298
+ </div>
299
+
300
+ <div id="examples_using_foreach">
301
+ <h3>Utiliser les boucles <code>{foreach …}</code></h3>
302
+ <div class="json">{
303
+ "__auto__":{"label":"Regroupement des produits par origine puis traitement des groupes séparémment","fees":"{foreach product.attribute.code_origin}{table {selection.weight} in 0.0:0.00, 1.0:11.00, 3.0:12.00, 5.0:13.00}{/foreach}"},
304
+ "__auto__":{"label":"Calcul des frais de port par produit","fees":"{foreach product.attribute.sku}{product.attribute.shipping}*{item.qty}{/foreach}"}
305
+ }</div>
306
+ </div>
307
+
308
+ <div id="examples_using_array_functions">
309
+ <h3>Manipuler les tableaux</h3>
310
+
311
+ <h4>Utilisation de la fonction <code>in_array()</code></h4>
312
+ <div class="json">{
313
+ "__auto__":{"label":"Livraison","conditions":"in_array({cart.qty}, array(10, 20, 30))","fees":10}
314
+ }</div>
315
+
316
+ <h4>Utilisation de la fonction <code>in_array()</code> avec des chaînes de caractères *</h4>
317
+ <div class="json">{
318
+ "__auto__":{"label":"Livraison","conditions":"in_array({{cart.coupon_code}}, array('free1', 'free2'))","fees":10}
319
+ }</div>
320
+
321
+ <h4>Utilisation de la fonction <code>array_match_any()</code></h4>
322
+ <div class="json">{
323
+ "__auto__":{"label":"Livraison","about":"5 x poids des produits qui se trouvent dans la catégorie 2 ou 3","fees":"{sum product.weight where array_match_any(product.categories.id, array(2, 3))} * 5.0"}
324
+ }</div>
325
+
326
+ <h4>Utilisation de la fonction <code>array_match_all()</code></h4>
327
+ <div class="json">{
328
+ "__auto__":{"label":"Livraison","about":"5 x poids des produits qui se trouvent à la fois dans la catégorie 2 et dans la catégorie 3","fees":"{sum product.weight where array_match_all(product.categories.id, array(2, 3))} * 5.0"}
329
+ }</div>
330
+ </div>
331
+
332
+ <div id="examples_more">
333
+ <h3>Autres exemples</h3>
334
+
335
+ <div id="examples_product_categories">
336
+ <h4>Utiliser la catégorie des produits</h4>
337
+ <p class="alert alert-danger">Attention, il est à noter que dans Magento, <strong>un produit peut être dans plusieurs catégories</strong>. Faites donc particulièrement attention à la façon dont vous utilisez cette propriété.</p>
338
+ <div class="json">{
339
+ "__auto__":{"label":"Boucle foreach dont l'itération se fait sur la catégorie","fees":"{foreach product.categories}{selection.weight}{/foreach}"},
340
+ "__auto__":{"label":"Utilisation de la catégorie à l'intérieur d'une boucle foreach","fees":"{foreach product.sku}({{product.category}}=='Test' ? 2.00 : 1.00)*{item.qty}{/foreach}"},
341
+ "__auto__":{"label":"Utilisation de l'id de la catégorie à l'intérieur d'une boucle foreach","fees":"{foreach product.sku}({product.category.id}==12 ? 2.00 : 1.00)*{item.qty}{/foreach}"},
342
+ "__auto__":{"about":"La fonction in_array() est utilisée car product.categories retourne un tableau","label":"Somme des attributs weight des produits de la catégorie 'Test'","fees":"{sum product.weight where in_array('Test', product.categories)}"},
343
+ "__auto__":{"about":"La fonction in_array() est utilisée car product.categories.id retourne un tableau","label":"Somme des attributs weight des produits de la catégorie dont l'id est 12","fees":"{sum product.weight where in_array(12, product.categories.id)}"},
344
+ "__auto__":{"about":"La fonction array_match_any() est utilisée car product.categories.id retourne un tableau","label":"Somme des attributs weight des produits des catégories dont les id sont 11 et 12","fees":"{sum product.weight where array_match_any(product.categories.id, array(11, 12))}"},
345
+ "__auto__":{"label":"Somme des poids des produits dont la première catégorie est 'Test'","fees":"{sum product.weight where product.category=='Test'}"},
346
+ "__auto__":{"label":"Somme des poids des produits dont l'id de la première catégorie est 12","fees":"{sum product.weight where product.category.id==12}"}
347
+ }</div>
348
+ </div>
349
+
350
+ <div id="examples_data">
351
+ <h4>Ajout et utilisation d'un élément <code>data</code></h4>
352
+ <p>Un élément de type <code>data</code> permet de spécifier des données utilisables dans les méthodes de livraison.</p>
353
+ <div class="json">{
354
+ "mydata":{"type":"data","var1":"12"},
355
+ "__auto__":{"label":"Livraison","shipto":"FR","fees": "{mydata.var1}"},
356
+ "__auto__":{"label":"Livraison","shipto":"DE","fees": "{mydata.var1}*1.5"}
357
+ }</div>
358
+ </div>
359
+
360
+ <div id="examples_meta">
361
+ <h4>Ajout d'un élément <code>meta</code></h4>
362
+ <p>Un élément de type <code>meta</code> permet d'ajouter des données informatives (auteur, date…).</p>
363
+ <div class="json">{
364
+ "about":{"type":"meta","author":"Owebia","date":"15/07/2013","about":"Tarifs 2013"}
365
+ }</div>
366
+ </div>
367
+ </div>
368
+ </div>
369
+
370
+ <div id="definitions">
371
+ <h2>Définitions</h2>
372
+ <p>
373
+ La configuration d'un mode de livraison est un objet JSON contenant plusieurs <strong><a href="#definitions_property">propriétés</a></strong>.<br/>
374
+ Comme imposé par JSON, chaque propriété a un nom unique, qui servira d'<a href="#definitions_unique_id">identifiant unique</a>.<br/>
375
+ Chaque propriété constitue un <strong><a href="#definitions_element">élément</a></strong> de configuration (qui est également un objet JSON).<br/>
376
+ </p>
377
+ <div id="definitions_element">
378
+ <h3>Les éléments</h3>
379
+
380
+ <p>
381
+ Il existe trois différents types d'<strong>élément</strong> de configuration :
382
+ </p>
383
+ <ul>
384
+ <li><code>method</code> : méthode de livraison (par défaut si non spécifié)</li>
385
+ <li><code>data</code> : données pouvant être utilisées dans une ou plusieurs méthodes de livraison (<a href="#examples_data">exemples</a>)</li>
386
+ <li><code>meta</code> : données informatives (<a href="#examples_meta">exemples</a>)</li>
387
+ </ul>
388
+ </div>
389
+
390
+ <div id="definitions_property">
391
+ <h3>Les propriétés</h3>
392
+
393
+ <p>
394
+ Chaque élément possède plusieurs <strong>propriétés</strong> :
395
+ </p>
396
+ <ul>
397
+ <li id="property_about"><code>about</code> : commentaire sur l'élément</li>
398
+ <li id="property_type"><code>type</code> : type de l'élément (<code>method</code>, <code>meta</code> ou <code>data</code>)</li>
399
+ </ul>
400
+
401
+ <p>
402
+ Propriétés spécifiques à un élément de type <code>method</code> :
403
+ </p>
404
+ <ul>
405
+ <li id="property_label"><code>label</code> : nom de la méthode de livraison</li>
406
+ <li id="property_description"><code>description</code> : description (visible seulement si le template l'affiche)</li>
407
+ <li id="property_enabled"><code>enabled</code> : méthode de livraison activée ou non</li>
408
+ <li id="property_fees"><code>fees</code> : frais de port</li>
409
+ <li id="property_conditions"><code>conditions</code> : conditions d'activation</li>
410
+ <li id="property_shipto"><code>shipto</code> : pays (régions, codes postaux) autorisés à la livraison</li>
411
+ <li id="property_billto"><code>billto</code> : pays (régions, codes postaux) autorisés à la facturation</li>
412
+ <li id="property_origin"><code>origin</code> : pays (régions, codes postaux) autorisés en origine</li>
413
+ <li id="property_customer_groups"><code>customer_groups</code> : groupes de client autorisés</li>
414
+ <li id="property_tracking_url"><code>tracking_url</code> : URL de suivi (<a href="#more_tracking_url">plus d'informations</a>)</li>
415
+ </ul>
416
+
417
+ <p><a href="#examples">Voir les exemples</a></p>
418
+
419
+ <h4>Utiliser les propriétés de type adresse (<code>shipto</code>, <code>billto</code> et <code>origin</code>)</h4>
420
+ <p>
421
+ Les codes pays utilisés sont ceux de Magento (à priori ils sont les mêmes que les <a href="http://fr.wikipedia.org/wiki/ISO_3166-1" target=_blank>codes ISO 3166-1 alpha-2</a>).<br/>
422
+ Il est possible de spécifier les codes régions (uniquement avec <code>shipto</code>) ou les codes postaux que l'on veut filtrer ou exclure.
423
+ </p>
424
+ <p class=new>
425
+ Vous pouvez utiliser le caractère <strong>jocker</strong> <code>*</code> ou les <strong>expressions régulières</strong> pour les codes postaux.<br/>
426
+ Une expression régulière doit commencer et se terminer par le caractère <code>/</code>. Si vous souhaitez utiliser les caractères <code>(</code>, <code>)</code> ou <code>.</code>, vous devez les échapper avec le caractère <code>\</code> (ex: <code><span class=string>"FR(/^25\([0-9]{3}\)$/)"</span></code>).<br/>
427
+ Vous pouvez utiliser l'option d'insensibilité à la casse (ex: <code><span class=string>"GB(/^PO.*$/i)"</span></code>).
428
+ </p>
429
+
430
+ <p><a href="#examples_using_address_filters">Voir les exemples</a></p>
431
+
432
+ <div id="address_filter" class="alert alert-info">
433
+ <p><strong>Astuce</strong><br/>Pour raccourcir la saisie des pays, vous pouvez utiliser les variables suivantes :</p>
434
+ <ul>
435
+ <li><code>{address_filter.AF}</code> : pays d'Afrique</li>
436
+ <li><code>{address_filter.AS}</code> : pays d'Asie</li>
437
+ <li><code>{address_filter.EU}</code> : pays d'Europe</li>
438
+ <li><code>{address_filter.NA}</code> : pays d'Amérique du Nord</li>
439
+ <li><code>{address_filter.SA}</code> : pays d'Amérique du Sud</li>
440
+ <li><code>{address_filter.OC}</code> : pays d'Océanie</li>
441
+ <li><code>{address_filter.AN}</code> : pays d'Antartique</li>
442
+ <li><code>{address_filter.EU-27}</code> : pays de l'Union Européenne</li>
443
+ <li><code>{address_filter.DOM}</code> : codes pays des département d'Outre-Mer Français</li>
444
+ <li><code>{address_filter.COM}</code> : codes pays des Collectivités d'Outre-Mer Françaises</li>
445
+ </ul>
446
+ <p><a href="#examples_using_address_filters_shortcuts">Voir les exemples</a></p>
447
+ </div>
448
+ </div>
449
+
450
+ <div id="definitions_unique_id">
451
+ <h3>L'identifiant unique</h3>
452
+
453
+ <p>Chaque élément de configuration possède un <strong>identifiant unique</strong>. Cet identifiant permet ensuite de faire référence à l'élément.</p>
454
+ <p>Exemple :</p>
455
+ <div class="json">{
456
+ "europe":{"label":"Livraison Europe","fees":10},
457
+ "us":{"label":"Livraison US","fees":"{europe.fees}+20"}
458
+ }</div>
459
+
460
+ <p class="alert alert-danger"><strong><u>Attention</u> :</strong> pour éviter les conflicts, n'utiliser que les caractères <code>a-z</code>, <code>A-Z</code>, <code>0-9</code>, <code>-</code> et <code>_</code> pour former l'identifiant unique.<br/>Vous devez également éviter les identifiants qui correspondent déjà à des noms de variable (<code>cart</code>, <code>product</code>, <code>item</code>…).</p>
461
+ </div>
462
+ </div>
463
+
464
+ <div id="formulas">
465
+ <h2>Les formules</h2>
466
+ <p>
467
+ Les propriétés <code>fees</code> et <code>conditions</code> sont spécifiées sous la forme de formules.<br/>
468
+ </p>
469
+ <p>
470
+ Une formule utilise des <a href="#formulas_variables">variables</a>, des <a href="#formulas_functions">fonctions</a>, des <a href="#formulas_special_functions">fonctions spéciales</a> et des opérateurs mathématiques.
471
+ </p>
472
+ <p>
473
+ Opérateurs mathématiques disponibles :
474
+ </p>
475
+ <ul>
476
+ <li>opérateurs : <code>*</code>, <code>/</code>, <code>+</code> et <code>-</code></li>
477
+ <li>modulo : <code>%</code></li>
478
+ <li>parenthèses : <code>(</code> et <code>)</code></li>
479
+ <li>les opérateurs booléens <code>&amp;&amp;</code>, <code>and</code>, <code>||</code>, <code>or</code>, <code>==</code>, <code>&lt;</code>, <code>&gt;</code>, <code>&lt;=</code>, <code>&gt;=</code></li>
480
+ <li>les opérateurs binaires <code>&amp;</code> et <code>|</code></li>
481
+ <li>le groupe d'opérateur <code>C ? X : Y</code> (ex: <code><span class=string>"{cart.price_exluding_tax}&gt;100 ? 15*{cart.weight} : 20*{cart.weight}"</span></code>)</li>
482
+ </ul>
483
+ <p>
484
+ Vous avez la possibilité de mettre des espaces et des retours à la ligne dans les formules (pour aérer).
485
+ </p>
486
+ <p>
487
+ Possibilité d'utiliser les fonctionnalités avancées suivantes : casting en entier <code>(int)</code> ou en nombre flottant <code>(float)</code>,
488
+ comparaison avec la valeur <code>null</code> ou les valeurs booléennes <code>true</code> et <code>false</code>.
489
+ </p>
490
+
491
+ <div id="formulas_variables">
492
+ <h3>Les variables</h3>
493
+
494
+ <p class="alert alert-info">
495
+ 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 <code>{{ }}</code>.
496
+ </p>
497
+
498
+ <p>
499
+ Les variables suivantes peuvent être utilisées dans les <a href="#formulas">formules</a>.
500
+ </p>
501
+ <ul>
502
+ <li id="formulas_variables_cart">Le panier :
503
+ <ul>
504
+ <li><code>{cart.weight}</code> : poids des marchandises</li>
505
+ <li><code>{cart.qty}</code> : la quantité d'articles</li>
506
+ <li><code>{cart.price-tax+discount}</code> : prix HT avec remise</li>
507
+ <li><code>{cart.price+tax+discount}</code> : prix TTC avec remise</li>
508
+ <li><code>{cart.price-tax-discount}</code> : prix HT sans remise</li>
509
+ <li><code>{cart.price+tax-discount}</code> : prix TTC sans remise</li>
510
+ <li><code>{cart.coupon_code}</code> : coupon de réduction</li>
511
+ <li><code>{cart.free_shipping}</code> : frais de port offert (par une règle dans Magento) [true/false]</li>
512
+ <li><code>{cart.weight_unit}</code> : l'unité de poids</li>
513
+ <li><code>{cart.weight_for_charge}</code> : poids des marchandises dont la livraison n'est pas offerte (par les règles de prix panier de Magento)</li>
514
+ </ul>
515
+ </li>
516
+ <li id="formulas_variables_quote">Le bon de commande :
517
+ <ul>
518
+ <li><code>{quote.subtotal}</code>: sous-total HT</li>
519
+ <li><code>{quote.subtotal_with_discount}</code>: sous-total HT avec remise</li>
520
+ <li><code>{quote.grand_total}</code>: total TTC avec remise</li>
521
+ <li><code>{quote.base_subtotal}</code>: sous-total HT dans la devise de base</li>
522
+ <li><code>{quote.base_subtotal_with_discount}</code>: sous-total HT avec remise dans la devise de base</li>
523
+ <li><code>{quote.base_grand_total}</code>: total TTC avec remise dans la devise de base</li>
524
+ </ul>
525
+ </li>
526
+ <li id="formulas_variables_customer_group">Le group client :
527
+ <ul>
528
+ <li><code>{customer_group.id}</code> : id du groupe client</li>
529
+ <li><code>{customer_group.code}</code> : nom du groupe client</li>
530
+ <li><code>{customer_group.*}</code> : propriété du groupe client (ex: <code>{customer_group.tax_class_id}</code>)</li>
531
+ </ul>
532
+ </li>
533
+ <li id="formulas_variables_customer">Le client :
534
+ <ul>
535
+ <li><code>{customer.id}</code> : id du client</li>
536
+ <li><code>{customer.attribute.*}</code> : attribut du client (ex: lastname, firstname, group_id…)</li>
537
+ <li><code>{customer.attribute.*.value}</code> : dans le cas des attributs de type liste de sélection, <code>{customer.attribute.*}</code> retourne l'id, pour obtenir la valeur il faut utiliser <code>{customer.attribute.*.value}</code></li>
538
+ <li><code>{customer.*}</code> : identique à <code>{customer.attribute.*}</code>, sauf si la variable est déjà définie (ex: <code>{customer.id}</code> est déjà définie)</li>
539
+ </ul>
540
+ </li>
541
+ <li id="formulas_variables_customvar">Les variables personnalisées ou `Custom Variables` (depuis la version 1.4.0.1 de Magento) :
542
+ <ul>
543
+ <li><code>{customvar.*}</code> : variable personnalisée de Magento (ex: <code>{customvar.my_var}</code>)</li>
544
+ </ul>
545
+ </li>
546
+ <li id="formulas_variables_shipto">L'adresse de livraison :
547
+ <ul>
548
+ <li><code>{shipto.country_name}</code> : le nom du pays</li>
549
+ <li><code>{shipto.country_id}</code> : le code du pays</li>
550
+ <li><code>{shipto.region_id}</code> : l'id de la région</li>
551
+ <li><code>{shipto.region_code}</code> : le code de la région</li>
552
+ <li><code>{shipto.street}</code> : la rue</li>
553
+ <li><code>{shipto.city}</code> : la ville</li>
554
+ <li><code>{shipto.postcode}</code> : le code postal</li>
555
+ </ul>
556
+ </li>
557
+ <li id="formulas_variables_billto">L'adresse de facturation :
558
+ <ul>
559
+ <li><code>{billto.country_name}</code> : le nom du pays</li>
560
+ <li><code>{billto.country_id}</code> : le code du pays</li>
561
+ <li><code>{billto.postcode}</code> : le code postal</li>
562
+ <li><code>{billto.*}</code> : propriété de l'adresse de facturation (ex: <code>{billto.city}</code>)</li>
563
+ </ul>
564
+ </li>
565
+ <li id="formulas_variables_origin">L'adresse d'envoi :
566
+ <ul>
567
+ <li><code>{origin.country_name}</code> : le nom du pays</li>
568
+ <li><code>{origin.country_id}</code> : le code du pays</li>
569
+ <li><code>{origin.region_id}</code> : l'id de la région</li>
570
+ <li><code>{origin.city}</code> : la ville</li>
571
+ <li><code>{origin.postcode}</code> : le code postal</li>
572
+ </ul>
573
+ </li>
574
+ <li id="formulas_variables_store">Le magasin :
575
+ <ul>
576
+ <li><code>{store.id}</code> <code>{store.code}</code> <code>{store.name}</code> <code>{store.address}</code> <code>{store.phone}</code> : id, code, nom, adresse et téléphone du magasin</li>
577
+ </ul>
578
+ </li>
579
+ <li id="formulas_variables_date">La date courante :
580
+ <ul>
581
+ <li><code>{date.timestamp}</code> : timestamp UNIX de la date actuelle</li>
582
+ <li><code>{date.year}</code> <code>{date.month}</code> <code>{date.day}</code> <code>{date.hour}</code> <code>{date.minute}</code> <code>{date.second}</code> : année, mois, jour, heure, minute et seconde de la date actuelle</li>
583
+ <li><code>{date.weekday}</code> : jour de la semaine de la date actuelle de 0 (dimanche) à 6 (samedi)</li>
584
+ </ul>
585
+ </li>
586
+ <li id="formulas_variables_request">L'objet <code>request</code> :
587
+ <ul>
588
+ <li><code>{request.*}</code> : propriété de l'objet request (Mage_Shipping_Model_Rate_Request) passé en paramètre par Magento (ex: <code>{request.package_qty}</code>). Utiliser l'option "Déboguage" pour obtenir plus de détail sur les propriétés disponibles.</li>
589
+ </ul>
590
+ </li>
591
+ </ul>
592
+
593
+ <div id="formulas_variables_for_special_functions">
594
+ <h4>Variables utilisables dans les fonctions spéciales</h4>
595
+
596
+ <p>Les variables suivantes peuvent être utilisées dans les <a href="#formulas_special_functions">fonctions spéciales</a>.</p>
597
+
598
+ <p class="alert alert-danger">Contrairement à ailleurs, les variables suivantes ne doivent pas être entourées par les caractères <code>{</code> et <code>}</code>.</p>
599
+
600
+ <p>
601
+ Un <code>item</code> est une déclinaison d'un <code>product</code> auquel on a ajouté d'éventuelles options. Chaque <code>item</code> a une quantité.
602
+ </p>
603
+ <ul>
604
+ <li id="formulas_variables_item">L'article (ou <code>item</code>) :
605
+ <ul>
606
+ <li><code>item.qty</code> : quantité dans le panier</li>
607
+ <li><code>item.price-tax+discount</code> : le prix HT avec remise</li>
608
+ <li><code>item.price-tax-discount</code> : le prix HT sans remise</li>
609
+ <li><code>item.price+tax+discount</code> : le prix TTC avec remise</li>
610
+ <li><code>item.price+tax-discount</code> : le prix TTC sans remise</li>
611
+ <li><code>item.option.*</code> : option (la liste des options disponibles dépendra des produits)</li>
612
+ </ul>
613
+ </li>
614
+ <li id="formulas_variables_product">Le produit (ou <code>product</code>) :
615
+ <ul>
616
+ <li><code>product.attribute.*</code> : attribut<br/>Attributs intéressants :
617
+ <ul>
618
+ <li><code>sku</code> : la référence</li>
619
+ <li><code>name</code> : le nom</li>
620
+ <li><code>weight</code> : le poids</li>
621
+ <li><code>price</code> : le prix (tel qu'il a été saisi sur la fiche du produit)</li>
622
+ <li><code>special_price</code> : le prix promotionnel (tel qu'il a été saisi sur la fiche du produit)</li>
623
+ <li>…</li>
624
+ </ul>
625
+ </li>
626
+ <li><code>product.attribute.*.value</code> : valeur de l'attribut<br/>Dans le cas des attributs de type liste de sélection, <code>product.attribute.*</code> retourne l'id. Pour obtenir la valeur, il faut utiliser <code>product.attribute.*.value</code></li>
627
+ <li><code>product.*</code> : identique à <code>product.attribute.*</code> sauf si la variable est définie (ex: <code>product.category</code>)</li>
628
+ <li>Première catégorie du produit :
629
+ <ul>
630
+ <li><code>product.category</code> : nom de la catégorie</li>
631
+ <li><code>product.category.id</code> : id de la catégorie</li>
632
+ <li><code>product.category.*</code> : attribut de la catégorie (ex: <code>product.category.is_active</code>)<br/>Attributs intéressants :
633
+ <ul>
634
+ <li><code>is_active</code> : catégorie activée ou non</li>
635
+ <li><code>name</code> : nom</li>
636
+ <li>…</li>
637
+ </ul>
638
+ </li>
639
+ </ul>
640
+ </li>
641
+ <li>Toutes les catégories du produit (retourne un tableau, <a href="#examples_product_categories">exemples</a>) :
642
+ <ul>
643
+ <li><code>product.categories</code> : tableau du nom des catégories</li>
644
+ <li><code>product.categories.id</code> : tableau de l'id des catégories</li>
645
+ </ul>
646
+ </li>
647
+ <li>Le jeu d'attributs du produit :
648
+ <ul>
649
+ <li><code>product.attribute_set</code> : nom du jeu d'attributs</li>
650
+ <li><code>product.attribute_set.id</code> : id du jeu d'attributs</li>
651
+ <li><code>product.attribute_set.*</code> : attribut du jeu d'attributs (ex: <code>product.attribute_set.attribute_set_name</code>)</li>
652
+ </ul>
653
+ </li>
654
+ <li><code>product.stock.*</code> : attribut du stock du produit<br/>Attributs intéressants :
655
+ <ul>
656
+ <li><code>is_in_stock</code> : disponibilité du produit</li>
657
+ <li><code>qty</code> : stock du produit</li>
658
+ <li>…</li>
659
+ </ul>
660
+ </li>
661
+ </ul>
662
+ </li>
663
+ </ul>
664
+ </div>
665
+
666
+ <div id="formulas_variables_for_foreach">
667
+ <h4>Variables utilisables dans les boucles <code>foreach</code></h4>
668
+
669
+ <p>Les variables suivantes peuvent être utilisées dans les <a href="#formulas_foreach">boucles <code>foreach</code></a>.</p>
670
+
671
+ <ul>
672
+ <li><code>{selection.weight}</code> : poids de la sélection</li>
673
+ <li><code>{selection.qty}</code> : nombre d'articles dans la sélection</li>
674
+ </ul>
675
+ <p>
676
+ Lorsque la sélection se fait sur le sku, chaque sélection est composée d'un seul article.
677
+ On peut donc utiliser les <a href="#formulas_variables_for_special_functions">variables article et produit</a>.
678
+ </p>
679
+ <ul>
680
+ <li><code>{item.*}</code> : propriété de l'article</li>
681
+ <li><code>{product.*}</code> : propriété du produit</li>
682
+ </ul>
683
+ <p class="alert alert-info">
684
+ Les variables article et produit sont identiques aux <a href="#formulas_variables_for_special_functions">variables utilisables dans les fonctions spéciales</a> à la seule différence qu'elles doivent être entourées par les caractères <code>{</code> et <code>}</code>.
685
+ </p>
686
+ </div>
687
+ </div>
688
+
689
+ <div id="formulas_functions">
690
+ <h3>Les fonctions</h3>
691
+
692
+ <h4>Les fonctions numériques</h4>
693
+ <ul>
694
+ <li><code>abs(x)</code> : valeur absolue</li>
695
+ <li><code>ceil(x)</code> : arrondi supérieur</li>
696
+ <li><code>exp(x)</code> : exponentiel</li>
697
+ <li><code>floor(x)</code> : arrondi inférieur</li>
698
+ <li><code>log(x)</code> : logarithme népérien</li>
699
+ <li><code>log(x, base)</code> : logarithme</li>
700
+ <li><code>max(x, y, …)</code> : maximum, valeurs nulles ignorées</li>
701
+ <li><code>min(x, y, …)</code> : minimum, valeurs nulles ignorées</li>
702
+ <li><code>pi()</code> : nombre PI</li>
703
+ <li><code>pow(x, puissance)</code> : puissance </li>
704
+ <li><code>rand(min, max)</code> : entier aléatoire</li>
705
+ <li><code>round(x)</code> : arrondi</li>
706
+ <li><code>sqrt(x)</code> : racine carrée</li>
707
+ </ul>
708
+
709
+ <h4>Les fonctions pour manipuler des chaînes de caractères</h4>
710
+ <ul>
711
+ <li><code>substr(string, start, length)</code> : retourne un segment de chaîne de caractères.</li>
712
+ </ul>
713
+
714
+ <h4>Les fonctions pour manipuler des tableaux</h4>
715
+ <ul>
716
+ <li><code>in_array(value, array(value1, value2, …))</code> : retourne vrai si la valeur se trouve dans le tableau.</li>
717
+ <li><code>array_match_any(array(value1, value2, …), array(value1, value2, …))</code> : retourne vrai si au moins une valeur est présente dans les deux tableaux.</li>
718
+ <li><code>array_match_all(array(value1, value2, …), array(value1, value2, …))</code> : retourne vrai si le contenu des tableaux est identique.</li>
719
+ </ul>
720
+
721
+ <h4>Fonctions diverses</h4>
722
+ <ul>
723
+ <li><code>range(value, min, max, include_min, include_max)</code> : retourne vrai si <code>value</code> est comprise entre <code>min</code> et <code>max</code>. Par défaut, <code>include_min</code> et <code>include_max</code> sont égales à <code>true</code>.</li>
724
+ </ul>
725
+ </div>
726
+
727
+ <div id="formulas_special_functions">
728
+ <h3>Les fonctions spéciales</h3>
729
+
730
+ <ul>
731
+ <li><code>{table … in …}</code> : définit des valeurs en fonction de seuils (<a href="#examples_special_table">exemples</a>)</li>
732
+ <li><code>{switch … in …}</code> : définit une table de correspondance (<a href="#examples_special_switch">exemples</a>)</li>
733
+ </ul>
734
+ <p>
735
+ Le premier paramètre <code>…</code> des fonctions <code>table</code> et <code>switch</code> est la valeur de référence, il peut s'agir soit d'une variable, soit d'une formule.
736
+ </p>
737
+ <ul>
738
+ <li><code>{count items[ where …]}</code> : compte les articles remplissant les conditions (<a href="#examples_special_count">exemples</a>)</li>
739
+ <li><code>{count distinct …[ where …]}</code> : compte les différentes valeurs d'une propriété pour les articles remplissant les conditions (<a href="#examples_special_count_distinct">exemples</a>)</li>
740
+ <li><code>{sum …[ where …]}</code> : calcule la somme des valeurs d'une propriété pour les articles remplissant les conditions (<a href="#examples_special_sum">exemples</a>)</li>
741
+ <li><code>{min …[ where …]}</code> : retourne la valeur minimum d'une propriété pour les articles remplissant les conditions (<a href="#examples_special_min">exemples</a>)</li>
742
+ <li><code>{max …[ where …]}</code> : retourne la valeur maximum d'une propriété pour les articles remplissant les conditions (<a href="#examples_special_max">exemples</a>)</li>
743
+ </ul>
744
+ <p>
745
+ Le premier paramètre <code>…</code> des fonctions <code>count distinct</code>, <code>sum</code>, <code>min</code> et <code>max</code> doit être une propriété (ex: <code>product.attribute.weight</code>).
746
+ </p>
747
+ <p>La condition <code>where</code> est facultative. Si elle est spécifiée, elle le sera sous la forme d'une formule.</p>
748
+ </div>
749
+
750
+ <div id="formulas_foreach">
751
+ <h3>Utilisation des boucles <code>foreach</code></h3>
752
+
753
+ <p>
754
+ Les boucles <code>foreach</code> permettent d'effectuer un calcul sur des groupes de produits plutôt que de tenir compte de tous les produits du panier.<br/>
755
+ Le résultat global d'une boucle <code>foreach</code> est la somme des résultats de chaque passage dans la boucle.
756
+ </p>
757
+ <p>
758
+ A l'intérieur d'une boucle <code>foreach</code>, il est possible d'utiliser de <a href="#formulas_variables_for_foreach">nouvelles variables</a>.
759
+ </p>
760
+ <p>
761
+ <a href="#examples_using_foreach">Exemples</a>
762
+ </p>
763
+ </div>
764
+
765
+ <div id="formulas_deprecated_variables">
766
+ <h3>Les variables dépréciées</h3>
767
+
768
+ <p>Les variables suivantes doivent être remplacées par leur équivalente.</p>
769
+
770
+ <ul>
771
+ <li><a href="#formulas_variables"><code><span class=strike>{cart.coupon}</span> {cart.coupon_code}</code></a></li>
772
+ <li><a href="#formulas_variables"><code><span class=strike>{cart.quantity}</span> {cart.qty}</code></a></li>
773
+ <li><a href="#formulas_variables"><code><span class=strike>{cart.price_excluding_tax}</span> {cart.price-tax+discount}</code></a></li>
774
+ <li><a href="#formulas_variables"><code><span class=strike>{cart.price_including_tax}</span> {cart.price+tax+discount}</code></a></li>
775
+ <li><a href="#formulas_variables"><code><span class=strike>{cart.weight.for-charge}</span> {cart.weight_for_charge}</code></a></li>
776
+ <li><a href="#formulas_variables"><code><span class=strike>{cart.weight.unit}</span> {cart.weight_unit}</code></a></li>
777
+ <li><a href="#formulas_variables"><code><span class=strike>{customer.group.code}</span> {customer_group.code}</code></a></li>
778
+ <li><a href="#formulas_variables"><code><span class=strike>{customer.group.id}</span> {customer_group.id}</code></a></li>
779
+ <li><a href="#formulas_variables"><code><span class=strike>{{customVar code=*}}</span> {customvar.*}</code></a></li>
780
+ <li><a href="#formulas_variables"><code><span class=strike>{destination.country.code}</span> {shipto.country_id}</code></a></li>
781
+ <li><a href="#formulas_variables"><code><span class=strike>{destination.country.name}</span> {shipto.country_name}</code></a></li>
782
+ <li><a href="#formulas_variables"><code><span class=strike>{destination.postcode}</span> {shipto.postcode}</code></a></li>
783
+ <li><a href="#formulas_variables"><code><span class=strike>{destination.region.code}</span> {shipto.region_code}</code></a></li>
784
+ <li><a href="#formulas_variables"><code><span class=strike>{free_shipping}</span> {cart.free_shipping}</code></a></li>
785
+ <li><a href="#formulas_variables"><code><span class=strike>{origin.country.code}</span> {origin.country_id}</code></a></li>
786
+ <li><a href="#formulas_variables"><code><span class=strike>{origin.country.name}</span> {origin.country_name}</code></a></li>
787
+ <li><a href="#formulas_variables"><code><span class=strike>{origin.region.code}</span> {origin.region_id}</code></a></li>
788
+ <li><a href="#formulas_variables_for_foreach"><code><span class=strike>{selection.quantity}</span> {selection.qty}</code></a></li>
789
+ </ul>
790
+ <ul>
791
+ <li><a href="#formulas_variables_for_special_functions"><code><span class=strike>product.quantity</span> item.qty</code></a></li>
792
+ <li><a href="#formulas_variables_for_special_functions"><code><span class=strike>product.price-tax+discount</span> item.price-tax+discount</code></a></li>
793
+ <li><a href="#formulas_variables_for_special_functions"><code><span class=strike>product.price-tax-discount</span> item.price-tax-discount</code></a></li>
794
+ <li><a href="#formulas_variables_for_special_functions"><code><span class=strike>product.price+tax+discount</span> item.price+tax+discount</code></a></li>
795
+ <li><a href="#formulas_variables_for_special_functions"><code><span class=strike>product.price+tax-discount</span> item.price+tax-discount</code></a></li>
796
+ <li><a href="#formulas_variables_for_special_functions"><code><span class=strike>product.option.*</span> item.option.*</code></a></li>
797
+ <li><a href="#formulas_variables_for_special_functions"><code><span class=strike>product.option.*</span> item.option.*</code></a></li>
798
+ </ul>
799
+ </div>
800
+ </div>
801
+
802
+ <div id="more">
803
+ <h2>Divers</h2>
804
+
805
+ <div id="more_tracking_url">
806
+ <h3>L'URL de suivi <code>tracking_url</code></h3>
807
+
808
+ <p class="alert alert-danger">
809
+ L'utilisation de la propriété <code>tracking_url</code> est réservée aux utilisateurs expérimentés. Si vous ne comprenez pas les indications ci-dessous, il est préférable que vous évitiez d'utiliser cette fonctionnalité.
810
+ </p>
811
+ <p>
812
+ La propriété <code>tracking_url</code> permet de surcharger le champ "URL de suivi" d'un mode de livraison Owebia-Shipping et ainsi de spécifier une URL de suivi <strong>par méthode de livraison</strong> plutôt qu'une pour tout le mode de livraison.
813
+ </p>
814
+ <p>
815
+ Pour insérer automatiquement le numéro de colis dans l'URL de suivi, vous devez utiliser <code>{tracking_number}</code>.
816
+ </p>
817
+
818
+ <div class="json">{
819
+ "__auto__":{"label":"Exemple avec URL de suivi pour le transporteur Colissimo","fees":10,"tracking_url":"http://www.coliposte.net/particulier/suivi_particulier.jsp?colispart={tracking_number}"}
820
+ }</div>
821
+
822
+ <p>
823
+ Magento ne gère pas les liens de tracking mais un statut de tracking. L'extension Owebia-Shipping fournit un lien HTML à la place du statut, lien qui permet d'aller sur le site du transporteur et de suivre l'avancement de la livraison du colis.
824
+ </p>
825
+ <p>
826
+ Lorsque l'URL de suivi est construite par l'extension, la seule information disponible est le numéro de colis et on n'a nul part accès à la méthode de livraison sélectionnée. Afin de pouvoir retrouver l'url de suivi dans la configuration, il faut spécifier la méthode de livraison dans le numéro de tracking, par exemple : <code>colissimo:8Lxxxxxxxxxxx</code> où <code>colissimo</code> est le code de la méthode de livraison sélectionnée.<br/>
827
+ Si aucun code n'est spécifié (si vous saisissez uniquement le numéro de tracking), l'url utilisée sera celle globale au mode de livraison.
828
+ </p>
829
+ <p class="alert alert-danger">
830
+ Pour répondre à une question récurrente, Magento affiche le statut de livraison depuis le back office ou le front office. Si vous souhaitez insérer l'URL de suivi dans les mails d'expédition, <strong>vous devrez développer vous même</strong> la récupération de l'URL de suivi et son insertion dans le mail, en effet, l'extension Owebia-Shipping se contente de fournir des modes de livraison paramétrables sans apporter de grande modification au coeur de Magento afin de réduire les problèmes d'incompatibilité et de mise à jour.
831
+ </p>
832
+ <p class="alert alert-danger">
833
+ Si vous obtenez un popup vide lorsque vous cliquez sur le lien de suivi, votre problème est très certainement lié au fait que vous n'avez pas spécifié le code de la méthode de livraison dans le numéro de suivi (voir indications plus haut) et que votre champ global "URL de suivi" est vide.
834
+ </p>
835
+ <p class="alert alert-danger">Il n'est actuellement pas prévu de modifier les fonctionnalitées de l'extension liées à l'URL de suivi.</p>
836
+ </div>
837
+ </div>
838
+
839
+ <div id="changelog">
840
+ <h2>Changelog</h2>
841
+
842
+ <pre class=changelog>
843
+ [2.5.22 - July 18, 2016]
844
+ Add composer.json and modman files
845
+
846
+ [2.5.21 - May 9, 2016]
847
+ Fix replacement of special functions, thanks to Sébastien L.
848
+
849
+ [2.5.20 - 25 avril 2016]
850
+ Fix code indentation
851
+ Fix version number
852
+ Add readme file in package
853
+
854
+ [2.5.19 - 09 novembre 2015]
855
+ Note: the extension is not affected by the patch SUPEE-6788 since it uses the new admin url routing syntax for 3 years (version 2.4.8.0)
856
+ Fix bug: deactivation of auto-escaping by default since it can cause some bugs (ex: impossible to use {address_filter.EU-27} in shipto)
857
+ Fix bug: fix auto-escaping of properties like {{shipto.country_name}}
858
+ Fix bug: variable replacements in labels (variables {cart.price-tax-discount}, {cart.price-tax+discount}, {cart.price+tax-discount} and {cart.price+tax+discount})
859
+ Fix bug: use items and not quote to retrieve values {cart.price-tax-discount}, {cart.price-tax+discount}, {cart.price+tax-discount} and {cart.price+tax+discount} (quote totals are not available at this time, calculating them causes duplications of addresses and a false grand_total value)
860
+ Fix bug: retrieve customer in backoffice order
861
+ Fix unicode accented chars in json_encode for PHP &lt; 5.4
862
+ Fix bug: usage of regular expressions inside {count ...}, {sum ...}, {min ...} and {max ...}
863
+ Allow usage of php functions date and strtotime (ex: "label": "'Your package will be delivered between ' . date('d/m', strtotime('+5 days')) . ' and ' . date('d/m Y', strtotime('+7 days'))",
864
+
865
  [2.5.18 - 24 juillet 2014]
866
  Pas de modification, nouvelle version pour Magento Connect
867
 
952
  Modification de la syntaxe de la configuration pour la rendre 100% compatible JSON
953
  Refonte complète de l'éditeur
954
  Suppression de la compatibilité avec les propriétés dépréciées suivantes :
955
+ 'fees_table', 'fees_formula', 'fixed_fees', 'reference_value', 'prices_range', 'weights_range', 'product_properties',
956
+ 'free_shipping__fees_table', 'free_shipping__fees_formula', 'free_shipping__fixed_fees', 'free_shipping__label',
957
  Suppression de la compatibilité avec la désactivation d'une méthode de livraison à l'aide du caractère #
958
  Suppression de la compatibilité avec les mots réservés en majuscule : TABLE, SUM, COUNT, DISTINCT et IN
959
  Ajout des fonctions array_match_any et array_match_all
978
  Correction d'un bug dans l'utilisation de la fonction {table ... in ...} : lorsque la variable de référence est indéfinie, le résultat était invalide (valeur précédente de la variable $replacement)
979
  Correction d'un problème avec les produits packagés (bundle product) : les produits 'bundle' et les produits 'simple' étaient tous deux récupérés ce qui faussait les résultats
980
  Support des sets d'attributs
981
+ product.attribute_set dans les conditions de boucle foreach
982
+ {product.attribute_set} et {product.attribute_set.id} comme variables dans les boucles foreach
983
+ product.attribute_set, product.attribute_set.id dans les conditions des opérations sum, count, min et max
984
  Optimisation du chargement de certaines valeurs (catégories, attribute set, ...)
985
  Correction d'un problème avec les castings successifs (string), (float) qui posent problème lorsque la locale utilise la virgule comme séparateur de décimales
986
 
1007
  Ajout des alias &quot;a&quot; et &quot;attr&quot; pour &quot;attribute&quot;, &quot;o&quot; et &quot;opt&quot; pour &quot;option&quot;, &quot;p&quot; pour &quot;product&quot;, &quot;c&quot; pour &quot;cart&quot;, &quot;s&quot; pour &quot;selection&quot;
1008
  Correction de la récupération des variables personnalisées : getValue('text') au lieu de getValue('plain')
1009
  Support des catégories
1010
+ product.categories dans les conditions de boucle foreach
1011
+ {product.category} et {product.category.id} comme variables dans les boucles foreach
1012
+ product.category, product.category.id, product.categories, product.categories.id dans les conditions des opérations sum, count, min et max
1013
  Amélioration du debug
1014
 
1015
  [2.4.1 - 24 août 2011]
1016
  Modification légère du code php pour éviter un plantage avec certaines versions d'eAccelerator (cache php)
1017
+ $row = null;
1018
+ $this-&gt;addMessage('info',$row,null,'Ignored lines %s','&lt;div class=&quot;code&quot;&gt;'.trim($config_string).'&lt;/div&gt;');
1019
+ au lieu de ;
1020
+ $this-&gt;addMessage('info',$row=null,null,'Ignored lines %s','&lt;div class=&quot;code&quot;&gt;'.trim($config_string).'&lt;/div&gt;');
1021
+ (cf http://www.magentocommerce.com/boards/viewthread/233202/)
1022
  Ajout des variables de debug &quot;info.server.os&quot; et &quot;info.server.software&quot;
1023
  Ajout de la possibilité de récupérer la valeur minimum ou maximum de la quantité (ex: &quot;{max product.quantity}&quot;)
1024
 
1245
  [2.0 - 3 avril 2009]
1246
  Création de la version 2.0 du module Owebia Shipping qui n'est plus compatible avec les anciennes versions
1247
 
1248
+ </pre>
1249
+ </div>
1250
+
1251
+ <div id="index">
1252
+ <h2>Index</h2>
1253
+ <div class="panel">
1254
+ <div class="row">
1255
+ <div class="col-lg-6">
1256
+ <h3>A</h3>
1257
+ <ul>
1258
+ <li><code>about</code> : <a href="#property_about">propriété</a></li>
1259
+ <li>activation : voir <code>enabled</code></li>
1260
+ <li>adresse d'envoi : voir <code>origin</code></li>
1261
+ <li>adresse de facturation : voir <code>billto</code></li>
1262
+ <li>adresse de livraison : voir <code>shipto</code></li>
1263
+ <li><code>address_filter</code> : <a href="#address_filter">raccourci</a>, <a href="#examples_using_address_filters_shortcuts">exemples</a></li>
1264
+ <li>attribut produit : voir <code>product.attribute.*</code></li>
1265
+ </ul>
1266
+
1267
+ <h3>B</h3>
1268
+ <ul>
1269
+ <li><code>billto</code> :
1270
+ <ul>
1271
+ <li><a href="#property_billto">propriété</a></li>
1272
+ <li><a href="#formulas_variables_billto">variables</a></li>
1273
+ </ul>
1274
+ </li>
1275
+ <li>bon de commande : voir <code>quote</code></li>
1276
+ </ul>
1277
+
1278
+ <h3>C</h3>
1279
+ <ul>
1280
+ <li><code>cart</code> : <a href="#formulas_variables_cart">variables</a></li>
1281
+ <li>commentaire : voir <code>about</code></li>
1282
+ <li><code>conditions</code> : <a href="#property_conditions">propriété</a></li>
1283
+ <li><code>count</code> : <a href="#formulas_special_functions">fonction spéciale</a></li>
1284
+ <li><code>count distinct</code> : <a href="#formulas_special_functions">fonction spéciale</a></li>
1285
+ <li><code>customer</code> : <a href="#formulas_variables_customer">variables</a></li>
1286
+ <li><code>customer_group</code> : <a href="#formulas_variables_customer_group">variables</a></li>
1287
+ <li><code>customer_groups</code> : <a href="#property_customer_groups">propriété</a></li>
1288
+ <li><code>customvar</code> : <a href="#formulas_variables_customvar">variables</a></li>
1289
+ </ul>
1290
+
1291
+ <h3>D</h3>
1292
+ <ul>
1293
+ <li><code>data</code> : <a href="#definitions_element">type d'élément</a>, <a href="#examples_data">exemples</a></li>
1294
+ <li><code>date</code> : <a href="#formulas_variables_date">variables</a></li>
1295
+ <li>désactivation : voir <code>enabled</code></li>
1296
+ <li><code>description</code> : <a href="#property_description">propriété</a></li>
1297
+ <li>destination : voir <code>shipto</code></li>
1298
+ <li>DOM/TOM : <a href="#examples_excluding_domtom_postcode">exclusion des codes postaux</a></li>
1299
+ </ul>
1300
+
1301
+ <h3>E</h3>
1302
+ <ul>
1303
+ <li>élément : <a href="#definitions_element">définition</a></li>
1304
+ <li><code>enabled</code> : <a href="#property_enabled">propriété</a></li>
1305
+ <li>expression régulière : voir la propriété <code>shipto</code></li>
1306
+ </ul>
1307
+
1308
+ <h3>F</h3>
1309
+ <ul>
1310
+ <li><code>fees</code> : <a href="#property_fees">propriété</a></li>
1311
+ <li><a href="#formulas_functions">Fonctions</a></li>
1312
+ <li><code>foreach</code> : <a href="#formulas_foreach">boucle</a>, <a href="#examples_using_foreach">exemples</a></li>
1313
+ <li><a href="#formulas">Formules</a></li>
1314
+ <li>frais de port : voir <code>fees</code></li>
1315
+ </ul>
1316
+
1317
+ <h3>G</h3>
1318
+ <ul>
1319
+ <li>gratuit : voir "port offert"</li>
1320
+ <li>groupes client : voir <code>customer_groups</code></li>
1321
+ </ul>
1322
+
1323
+ <h3>I</h3>
1324
+ <ul>
1325
+ <li>identifiant unique : <a href="#definitions_unique_id">définition</a></li>
1326
+ <li><code>item</code> : <a href="#formulas_variables_item">variables</a></li>
1327
+ <li><code>item.option.*</code> : <a href="#formulas_variables_item">variables</a></li>
1328
+ </ul>
1329
+ </div>
1330
+ <div class="col-lg-6">
1331
+ <h3>L</h3>
1332
+ <ul>
1333
+ <li><code>label</code> : <a href="#property_label">propriété</a></li>
1334
+ </ul>
1335
+
1336
+ <h3>M</h3>
1337
+ <ul>
1338
+ <li><code>max</code> :
1339
+ <ul>
1340
+ <li><a href="#formulas_functions">fonction</a></li>
1341
+ <li><a href="#formulas_special_functions">fonction spéciale</a>, <a href="#examples_special_max">exemples</a></li>
1342
+ </ul>
1343
+ </li>
1344
+ <li><code>meta</code> : <a href="#definitions_element">type d'élément</a>, <a href="#examples_meta">exemples</a></li>
1345
+ <li><code>method</code> : <a href="#definitions_element">type d'élément</a></li>
1346
+ <li><code>min</code> :
1347
+ <ul>
1348
+ <li><a href="#formulas_functions">fonction</a></li>
1349
+ <li><a href="#formulas_special_functions">fonction spéciale</a>, <a href="#examples_special_min">exemples</a></li>
1350
+ </ul>
1351
+ </li>
1352
+ </ul>
1353
+
1354
+ <h3>O</h3>
1355
+ <ul>
1356
+ <li>offert : voir "port offert"</li>
1357
+ <li>option produit : voir <code>item.option.*</code></li>
1358
+ <li><code>origin</code> :
1359
+ <ul>
1360
+ <li><a href="#property_origin">propriété</a></li>
1361
+ <li><a href="#formulas_variables_origin">variables</a></li>
1362
+ </ul>
1363
+ </li>
1364
+ </ul>
1365
+
1366
+ <h3>P</h3>
1367
+ <ul>
1368
+ <li>panier : voir <code>cart</code></li>
1369
+ <li>port offert : <a href="#examples_simple">exemples</a></li>
1370
+ <li><code>product</code> : <a href="#formulas_variables_product">variables</a></li>
1371
+ <li><code>product.attribute.*</code> : <a href="#formulas_variables_product">variables</a></li>
1372
+ <li><code>product.categories</code> : <a href="#formulas_variables_product">variables</a>, <a href="#examples_product_categories">exemples</a></li>
1373
+ <li>propriété : <a href="#definitions_property">définition</a></li>
1374
+ </ul>
1375
+
1376
+ <h3>Q</h3>
1377
+ <ul>
1378
+ <li><code>quote</code> : <a href="#formulas_variables_quote">variables</a></li>
1379
+ </ul>
1380
+
1381
+ <h3>R</h3>
1382
+ <ul>
1383
+ <li><code>request</code> : <a href="#formulas_variables_request">variables</a></li>
1384
+ </ul>
1385
+
1386
+ <h3>S</h3>
1387
+ <ul>
1388
+ <li><code>shipto</code> :
1389
+ <ul>
1390
+ <li><a href="#property_shipto">propriété</a>, <a href="#examples_using_address_filters">exemples</a></li>
1391
+ <li><a href="#formulas_variables_shipto">variables</a></li>
1392
+ </ul>
1393
+ </li>
1394
+ <li><code>store</code> : <a href="#formulas_variables_store">variables</a></li>
1395
+ <li><code>sum</code> : <a href="#formulas_special_functions">fonction spéciale</a></li>
1396
+ <li><code>switch</code> : <a href="#formulas_special_functions">fonction spéciale</a>, <a href="#examples_special_switch">exemples</a></li>
1397
+ </ul>
1398
+
1399
+ <h3>T</h3>
1400
+ <ul>
1401
+ <li><code>table</code> : <a href="#formulas_special_functions">fonction spéciale</a>, <a href="#examples_special_table">exemples</a></li>
1402
+ <li>table de correspondance&nbsp;: voir <code>switch</code></li>
1403
+ <li>titre&nbsp;: voir <code>label</code></li>
1404
+ <li><code>tracking_url</code>&nbsp;: <a href="#property_tracking_url">propriété</a>, <a href="#more_tracking_url">plus d'informations</a></li>
1405
+ <li><code>type</code>&nbsp;: <a href="#property_type">propriété</a></li>
1406
+ </ul>
1407
+
1408
+ <h3>U</h3>
1409
+ <ul>
1410
+ <li>URL de suivi&nbsp;: voir <code>tracking_url</code></li>
1411
+ </ul>
1412
+
1413
+ <h3>V</h3>
1414
+ <ul>
1415
+ <li>Variables : <a href="#formulas_variables">disponibles</a>, <a href="#formulas_deprecated_variables">dépréciées</a></li>
1416
+ <li>Variables personnalisées de Magento : voir <code>customvar</code></li>
1417
+ </ul>
1418
+ </div>
1419
+ </div>
1420
+ </div>
1421
+ </div>
1422
+ <!-- doc content end -->
1423
+ </div>
1424
+ </div>
1425
  </div>
1426
  <script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
1427
  <script src="http://netdna.bootstrapcdn.com/bootstrap/3.0.0-rc1/js/bootstrap.min.js"></script>
1428
  <script>
1429
  <!-- doc scripts start -->
1430
  function jsonEncode(data, beautify, html, level, current_indent) {
1431
+ if (typeof beautify == 'undefined') beautify = false;
1432
+ if (typeof html == 'undefined') html = false;
1433
+ if (typeof level == 'undefined') level = 0;
1434
+ if (typeof current_indent == 'undefined') current_indent = '';
1435
+
1436
+ var indent = html ? '&nbsp;&nbsp;&nbsp;' : "\t";
1437
+ var line_break = html ? '<br/>' : "\n";
1438
+ var new_indent = current_indent + indent;
1439
+ switch (typeof(data)) {
1440
+ case 'undefined':
1441
+ return (html ? '<span class=json-reserved>' : '') + 'null' + (html ? '</span>' : '');
1442
+ case 'boolean':
1443
+ return (html ? '<span class=json-reserved>' : '') + (data ? 'true' : 'false') + (html ? '</span>' : '');
1444
+ case 'number':
1445
+ return (html ? '<span class=json-numeric>' : '') + data + (html ? '</span>' : '');
1446
+ case 'string':
1447
+ var output = JSON.stringify(data);
1448
+ return html ? '<span class=json-string>' + output + '</span>' : output;
1449
+ case 'object':
1450
+ var output_index_count = 0;
1451
+ var output = [];
1452
+ for (var key in data) {
1453
+ var value = data[key];
1454
+ if (output_index_count!==null && output_index_count++!==key) {
1455
+ output_index_count = null;
1456
+ }
1457
+ }
1458
+ var is_associative = output_index_count===null;
1459
+ for (var key in data) {
1460
+ var value = data[key];
1461
+ if (is_associative) {
1462
+ var classes = [];
1463
+ if (key=='about') classes.push('json-about');
1464
+ if (key=='conditions' || key=='fees') classes.push('json-formula');
1465
+ var property_classes = ['json-property'];
1466
+ if (level==0) property_classes.push('json-id');
1467
+ output.push(
1468
+ (html && classes.length ? '<span class="' + classes.join(' ') + '">' : '')
1469
+ + (html ? '<span' + (property_classes.length ? ' class="' + property_classes.join(' ') + '"' : '') + '>' : '')
1470
+ + jsonEncode('' + key)
1471
+ + (html ? '</span>' : '') + ':'
1472
+ + (beautify ? ' ' : '')
1473
+ + jsonEncode(value, beautify, html, level+1, new_indent)
1474
+ + (html && classes.length ? '</span>' : '')
1475
+ );
1476
+ } else {
1477
+ output.push(jsonEncode(value, beautify, html, level+1, current_indent));
1478
+ }
1479
+ }
1480
+ if (is_associative) {
1481
+ var classes = [];
1482
+ if (data.type == 'meta') classes.push('json-meta');
1483
+ output = (html && classes.length ? '<span class="' + classes.join(' ') + '">' : '')
1484
+ + '{'
1485
+ + (beautify ? line_break + new_indent : '')
1486
+ + output.join(',' + (beautify ? line_break + new_indent : ''))
1487
+ + (beautify ? line_break + current_indent : '')
1488
+ + '}'
1489
+ + (html && classes.length ? '</span>' : '');
1490
+ return output;
1491
+ } else {
1492
+ return '[' + output.join(',' + (beautify ? ' ' : '')) + ']';
1493
+ }
1494
+ default:
1495
+ return ''; // Not supported
1496
+ }
1497
  }
1498
 
1499
  $(function(){
1500
+ var navHeight = $('.navbar').outerHeight(true) + 10;
1501
+
1502
+ $('a[href^="#"]').click(function (e) {
1503
+ $('.highlight').removeClass('highlight');
1504
+ var anchor = $(this).attr('href').replace('#', '');
1505
+ window.location.hash = '#' + anchor;
1506
+ var jelem = $('#' + anchor);
1507
+ jelem.addClass('highlight');
1508
+ $('body,html').scrollTop(Math.round(jelem.offset().top - navHeight + 10));
1509
+ e.preventDefault()
1510
+ });
1511
+
1512
+ $('a[href^="#"]').each(function (e) {
1513
+ var anchor = $(this).attr('href').replace('#', '');
1514
+ if (anchor == '') return;
1515
+ var jelem = $('#' + anchor);
1516
+ if (!jelem.length) {
1517
+ $(this).css('border', 'solid 1px red').css('padding', 3);
1518
+ }
1519
+ });
1520
+
1521
+ var index = 0;
1522
+ $('div.json').each(function(){
1523
+ var text = $(this).text();
1524
+ while (text.match(/"__auto__"/)) {
1525
+ text = text.replace(/"__auto__"/, '"id_' + ('000' + index).slice(-3) + '"');
1526
+ index++;
1527
+ }
1528
+ var obj = $.parseJSON(text);
1529
+ var beautified = jsonEncode(obj, true, true);
1530
+ $(this).html('<pre>' + beautified + '</pre>');
1531
+ $(this).addClass('code');
1532
+ });
1533
+ $('body').scrollspy({
1534
+ target: '.sidebar',
1535
+ offset: navHeight
1536
+ });
1537
 
1538
  });
1539
  <!-- doc scripts end -->
app/code/community/Owebia/Shipping2/etc/adminhtml.xml CHANGED
@@ -21,33 +21,33 @@
21
  -->
22
  <!-- Magento 1.4.0 and upper -->
23
  <config>
24
- <acl>
25
- <resources>
26
- <admin>
27
- <children>
28
- <system>
29
- <children>
30
- <config>
31
- <children>
32
- <owebia_shipping2>
33
- <title>Owebia Shipping 2 Section</title>
34
- <sort_order>100</sort_order>
35
- </owebia_shipping2>
36
- </children>
37
- </config>
38
- </children>
39
- </system>
40
- </children>
41
- </admin>
42
- </resources>
43
- </acl>
44
- <translate>
45
- <modules>
46
- <Mage_Shipping>
47
- <files>
48
- <owebia_shipping2>Owebia_Shipping2.csv</owebia_shipping2>
49
- </files>
50
- </Mage_Shipping>
51
- </modules>
52
- </translate>
53
  </config>
21
  -->
22
  <!-- Magento 1.4.0 and upper -->
23
  <config>
24
+ <acl>
25
+ <resources>
26
+ <admin>
27
+ <children>
28
+ <system>
29
+ <children>
30
+ <config>
31
+ <children>
32
+ <owebia_shipping2>
33
+ <title>Owebia Shipping 2 Section</title>
34
+ <sort_order>100</sort_order>
35
+ </owebia_shipping2>
36
+ </children>
37
+ </config>
38
+ </children>
39
+ </system>
40
+ </children>
41
+ </admin>
42
+ </resources>
43
+ </acl>
44
+ <translate>
45
+ <modules>
46
+ <Mage_Shipping>
47
+ <files>
48
+ <owebia_shipping2>Owebia_Shipping2.csv</owebia_shipping2>
49
+ </files>
50
+ </Mage_Shipping>
51
+ </modules>
52
+ </translate>
53
  </config>
app/code/community/Owebia/Shipping2/etc/config.xml CHANGED
@@ -1,7 +1,7 @@
1
  <?xml version="1.0"?>
2
  <!--
3
  /**
4
- * Copyright (c) 2008-14 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,
@@ -20,195 +20,180 @@
20
  **/
21
  -->
22
  <config>
23
- <modules>
24
- <Owebia_Shipping2>
25
- <version>2.5.18</version>
26
- <depends>
27
- <Mage_Shipping />
28
- </depends>
29
- </Owebia_Shipping2>
30
- </modules>
31
 
32
- <global>
33
- <models>
34
- <owebia_shipping2>
35
- <class>Owebia_Shipping2_Model</class>
36
- </owebia_shipping2>
37
- </models>
38
- <blocks>
39
- <owebia_shipping2>
40
- <class>Owebia_Shipping2_Block</class>
41
- </owebia_shipping2>
42
- </blocks>
43
- <helpers>
44
- <owebia_shipping2>
45
- <class>Owebia_Shipping2_Helper</class>
46
- </owebia_shipping2>
47
- </helpers>
48
- <resources>
49
- <owebia_shipping2_setup>
50
- <setup>
51
- <module>Owebia_Shipping2</module>
52
- <class>Owebia_Shipping2_Model_Mysql4_Setup</class>
53
- </setup>
54
- </owebia_shipping2_setup>
55
- <sales>
56
- <shipping>
57
- <carriers>
58
- <owebiashipping1>
59
- <class>Owebia_Shipping2_Model_Carrier_OwebiaShipping1</class>
60
- </owebiashipping1>
61
- <owebiashipping3>
62
- <class>Owebia_Shipping2_Model_Carrier_OwebiaShipping3</class>
63
- </owebiashipping3>
64
- <owebiashipping2>
65
- <class>Owebia_Shipping2_Model_Carrier_OwebiaShipping2</class>
66
- </owebiashipping2>
67
- <owebiashipping4>
68
- <class>Owebia_Shipping2_Model_Carrier_OwebiaShipping4</class>
69
- </owebiashipping4>
70
- </carriers>
71
- </shipping>
72
- </sales>
73
- </resources>
74
- </global>
75
 
76
- <admin>
77
- <routers>
78
- <adminhtml>
79
- <args>
80
- <modules>
81
- <owebia_shipping2 before="Mage_Adminhtml">Owebia_Shipping2_Adminhtml</owebia_shipping2>
82
- </modules>
83
- </args>
84
- </adminhtml>
85
- </routers>
86
- </admin>
87
- <adminhtml>
88
- <!-- Magento lower than 1.4.0 -->
89
- <acl>
90
- <resources>
91
- <admin>
92
- <children>
93
- <system>
94
- <children>
95
- <config>
96
- <children>
97
- <owebia>
98
- <title>Owebia Section</title>
99
- <sort_order>100</sort_order>
100
- </owebia>
101
- </children>
102
- </config>
103
- </children>
104
- </system>
105
- </children>
106
- </admin>
107
- </resources>
108
- </acl>
109
- <translate>
110
- <modules>
111
- <Mage_Shipping>
112
- <files>
113
- <owebia_shipping2>Owebia_Shipping2.csv</owebia_shipping2>
114
- </files>
115
- </Mage_Shipping>
116
- </modules>
117
- </translate>
118
- </adminhtml>
119
 
120
- <frontend>
121
- <translate>
122
- <modules>
123
- <Mage_Shipping>
124
- <files>
125
- <owebia_shipping2>Owebia_Shipping2.csv</owebia_shipping2>
126
- </files>
127
- </Mage_Shipping>
128
- </modules>
129
- </translate>
130
- <routers>
131
- <checkout>
132
- <args>
133
- <modules>
134
- <owebia_shipping2 before="Mage_Checkout">Owebia_Shipping2_Checkout</owebia_shipping2>
135
- </modules>
136
- </args>
137
- </checkout>
138
- </routers>
139
- </frontend>
140
 
141
- <default>
142
- <owebia_shipping2>
143
- <general>
144
- <weight_unit>kg</weight_unit>
145
- </general>
146
- <bundle_product>
147
- <process_children>0</process_children>
148
- <load_item_options_on_parent>1</load_item_options_on_parent>
149
- <load_item_data_on_parent>1</load_item_data_on_parent>
150
- <load_product_data_on_parent>1</load_product_data_on_parent>
151
- </bundle_product>
152
- <configurable_product>
153
- <load_item_options_on_parent>1</load_item_options_on_parent>
154
- <load_item_data_on_parent>1</load_item_data_on_parent>
155
- <load_product_data_on_parent>0</load_product_data_on_parent>
156
- </configurable_product>
157
- </owebia_shipping2>
158
- <carriers>
159
- <owebiashipping1>
160
- <active>0</active>
161
- <title>Owebia Shipping - Mode de livraison 1</title>
162
- <model>Owebia_Shipping2_Model_Carrier_OwebiaShipping1</model>
163
- <tracking_view_url></tracking_view_url>
164
- <config>{
165
  "demo": {
166
  "label": "Frais de port fixes",
167
  "fees": 10
168
  }
169
  }</config>
170
- <debug>0</debug>
171
- <auto_escaping>0</auto_escaping>
172
- <auto_correction>1</auto_correction>
173
- <stop_to_first_match>0</stop_to_first_match>
174
- <sort_order>1</sort_order>
175
- </owebiashipping1>
176
- <owebiashipping3>
177
- <active>0</active>
178
- <title>Owebia Shipping - Mode de livraison 3</title>
179
- <model>Owebia_Shipping2_Model_Carrier_OwebiaShipping3</model>
180
- <tracking_view_url></tracking_view_url>
181
- <config></config>
182
- <debug>0</debug>
183
- <auto_escaping>0</auto_escaping>
184
- <auto_correction>1</auto_correction>
185
- <stop_to_first_match>0</stop_to_first_match>
186
- <sort_order>3</sort_order>
187
- </owebiashipping3>
188
- <owebiashipping2>
189
- <active>0</active>
190
- <title>Owebia Shipping - Mode de livraison 2</title>
191
- <model>Owebia_Shipping2_Model_Carrier_OwebiaShipping2</model>
192
- <tracking_view_url></tracking_view_url>
193
- <config></config>
194
- <debug>0</debug>
195
- <auto_escaping>0</auto_escaping>
196
- <auto_correction>1</auto_correction>
197
- <stop_to_first_match>0</stop_to_first_match>
198
- <sort_order>2</sort_order>
199
- </owebiashipping2>
200
- <owebiashipping4>
201
- <active>0</active>
202
- <title>Owebia Shipping - Mode de livraison 4</title>
203
- <model>Owebia_Shipping2_Model_Carrier_OwebiaShipping4</model>
204
- <tracking_view_url></tracking_view_url>
205
- <config></config>
206
- <debug>0</debug>
207
- <auto_escaping>0</auto_escaping>
208
- <auto_correction>1</auto_correction>
209
- <stop_to_first_match>0</stop_to_first_match>
210
- <sort_order>4</sort_order>
211
- </owebiashipping4>
212
- </carriers>
213
- </default>
214
  </config>
1
  <?xml version="1.0"?>
2
  <!--
3
  /**
4
+ * Copyright (c) 2008-16 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,
20
  **/
21
  -->
22
  <config>
23
+ <modules>
24
+ <Owebia_Shipping2>
25
+ <version>2.5.22</version>
26
+ <depends>
27
+ <Mage_Shipping />
28
+ </depends>
29
+ </Owebia_Shipping2>
30
+ </modules>
31
 
32
+ <global>
33
+ <models>
34
+ <owebia_shipping2>
35
+ <class>Owebia_Shipping2_Model</class>
36
+ </owebia_shipping2>
37
+ </models>
38
+ <blocks>
39
+ <owebia_shipping2>
40
+ <class>Owebia_Shipping2_Block</class>
41
+ </owebia_shipping2>
42
+ </blocks>
43
+ <helpers>
44
+ <owebia_shipping2>
45
+ <class>Owebia_Shipping2_Helper</class>
46
+ </owebia_shipping2>
47
+ </helpers>
48
+ <resources>
49
+ <owebia_shipping2_setup>
50
+ <setup>
51
+ <module>Owebia_Shipping2</module>
52
+ <class>Owebia_Shipping2_Model_Mysql4_Setup</class>
53
+ </setup>
54
+ </owebia_shipping2_setup>
55
+ <sales>
56
+ <shipping>
57
+ <carriers>
58
+ <owebiashipping1>
59
+ <class>Owebia_Shipping2_Model_Carrier_OwebiaShipping1</class>
60
+ </owebiashipping1>
61
+ <owebiashipping2>
62
+ <class>Owebia_Shipping2_Model_Carrier_OwebiaShipping2</class>
63
+ </owebiashipping2>
64
+ <owebiashipping3>
65
+ <class>Owebia_Shipping2_Model_Carrier_OwebiaShipping3</class>
66
+ </owebiashipping3>
67
+ </carriers>
68
+ </shipping>
69
+ </sales>
70
+ </resources>
71
+ </global>
 
 
 
72
 
73
+ <admin>
74
+ <routers>
75
+ <adminhtml>
76
+ <args>
77
+ <modules>
78
+ <owebia_shipping2 before="Mage_Adminhtml">Owebia_Shipping2_Adminhtml</owebia_shipping2>
79
+ </modules>
80
+ </args>
81
+ </adminhtml>
82
+ </routers>
83
+ </admin>
84
+ <adminhtml>
85
+ <!-- Magento lower than 1.4.0 -->
86
+ <acl>
87
+ <resources>
88
+ <admin>
89
+ <children>
90
+ <system>
91
+ <children>
92
+ <config>
93
+ <children>
94
+ <owebia>
95
+ <title>Owebia Section</title>
96
+ <sort_order>100</sort_order>
97
+ </owebia>
98
+ </children>
99
+ </config>
100
+ </children>
101
+ </system>
102
+ </children>
103
+ </admin>
104
+ </resources>
105
+ </acl>
106
+ <translate>
107
+ <modules>
108
+ <Mage_Shipping>
109
+ <files>
110
+ <owebia_shipping2>Owebia_Shipping2.csv</owebia_shipping2>
111
+ </files>
112
+ </Mage_Shipping>
113
+ </modules>
114
+ </translate>
115
+ </adminhtml>
116
 
117
+ <frontend>
118
+ <translate>
119
+ <modules>
120
+ <Mage_Shipping>
121
+ <files>
122
+ <owebia_shipping2>Owebia_Shipping2.csv</owebia_shipping2>
123
+ </files>
124
+ </Mage_Shipping>
125
+ </modules>
126
+ </translate>
127
+ <routers>
128
+ <checkout>
129
+ <args>
130
+ <modules>
131
+ <owebia_shipping2 before="Mage_Checkout">Owebia_Shipping2_Checkout</owebia_shipping2>
132
+ </modules>
133
+ </args>
134
+ </checkout>
135
+ </routers>
136
+ </frontend>
137
 
138
+ <default>
139
+ <owebia_shipping2>
140
+ <general>
141
+ <weight_unit>kg</weight_unit>
142
+ </general>
143
+ <bundle_product>
144
+ <process_children>0</process_children>
145
+ <load_item_options_on_parent>1</load_item_options_on_parent>
146
+ <load_item_data_on_parent>1</load_item_data_on_parent>
147
+ <load_product_data_on_parent>1</load_product_data_on_parent>
148
+ </bundle_product>
149
+ <configurable_product>
150
+ <load_item_options_on_parent>1</load_item_options_on_parent>
151
+ <load_item_data_on_parent>1</load_item_data_on_parent>
152
+ <load_product_data_on_parent>0</load_product_data_on_parent>
153
+ </configurable_product>
154
+ </owebia_shipping2>
155
+ <carriers>
156
+ <owebiashipping1>
157
+ <active>0</active>
158
+ <title>Owebia Shipping - Mode de livraison 1</title>
159
+ <model>Owebia_Shipping2_Model_Carrier_OwebiaShipping1</model>
160
+ <tracking_view_url></tracking_view_url>
161
+ <config>{
162
  "demo": {
163
  "label": "Frais de port fixes",
164
  "fees": 10
165
  }
166
  }</config>
167
+ <debug>0</debug>
168
+ <auto_escaping>0</auto_escaping>
169
+ <auto_correction>1</auto_correction>
170
+ <stop_to_first_match>0</stop_to_first_match>
171
+ <sort_order>1</sort_order>
172
+ </owebiashipping1>
173
+ <owebiashipping2>
174
+ <active>0</active>
175
+ <title>Owebia Shipping - Mode de livraison 2</title>
176
+ <model>Owebia_Shipping2_Model_Carrier_OwebiaShipping2</model>
177
+ <tracking_view_url></tracking_view_url>
178
+ <config></config>
179
+ <debug>0</debug>
180
+ <auto_escaping>0</auto_escaping>
181
+ <auto_correction>1</auto_correction>
182
+ <stop_to_first_match>0</stop_to_first_match>
183
+ <sort_order>2</sort_order>
184
+ </owebiashipping2>
185
+ <owebiashipping3>
186
+ <active>0</active>
187
+ <title>Owebia Shipping - Mode de livraison 3</title>
188
+ <model>Owebia_Shipping2_Model_Carrier_OwebiaShipping3</model>
189
+ <tracking_view_url></tracking_view_url>
190
+ <config></config>
191
+ <debug>0</debug>
192
+ <auto_escaping>0</auto_escaping>
193
+ <auto_correction>1</auto_correction>
194
+ <stop_to_first_match>0</stop_to_first_match>
195
+ <sort_order>3</sort_order>
196
+ </owebiashipping3>
197
+ </carriers>
198
+ </default>
 
 
 
 
 
 
 
 
 
 
 
 
199
  </config>
app/code/community/Owebia/Shipping2/etc/system.xml CHANGED
@@ -20,574 +20,465 @@
20
  **/
21
  -->
22
  <config>
23
- <tabs>
24
- <owebia>
25
- <label>Owebia</label>
26
- <sort_order>300</sort_order>
27
- </owebia>
28
- </tabs>
29
- <sections>
30
- <carriers>
31
- <show_in_store>1</show_in_store>
32
- <groups>
33
- <owebiashipping1 translate="label" module="shipping">
34
- <label>Owebia Shipping - Mode de livraison 1</label>
35
- <frontend_type>text</frontend_type>
36
- <sort_order>-19</sort_order>
37
- <show_in_default>1</show_in_default>
38
- <show_in_website>1</show_in_website>
39
- <show_in_store>1</show_in_store>
40
- <fields>
41
- <informations translate="label">
42
- <label>Informations</label>
43
- <frontend_model>owebia_shipping2/adminhtml_system_config_form_field_informations</frontend_model>
44
- <sort_order>0</sort_order>
45
- <show_in_default>1</show_in_default>
46
- <show_in_website>1</show_in_website>
47
- <show_in_store>1</show_in_store>
48
- </informations>
49
- <active translate="label">
50
- <label>Enabled</label>
51
- <frontend_type>select</frontend_type>
52
- <source_model>adminhtml/system_config_source_yesno</source_model>
53
- <sort_order>1</sort_order>
54
- <show_in_default>1</show_in_default>
55
- <show_in_website>1</show_in_website>
56
- <show_in_store>1</show_in_store>
57
- </active>
58
- <title translate="label">
59
- <label>Title</label>
60
- <frontend_type>text</frontend_type>
61
- <sort_order>2</sort_order>
62
- <show_in_default>1</show_in_default>
63
- <show_in_website>1</show_in_website>
64
- <show_in_store>1</show_in_store>
65
- </title>
66
- <config translate="label">
67
- <label>Configuration</label>
68
- <frontend_model>owebia_shipping2/adminhtml_system_config_form_field_config</frontend_model>
69
- <frontend_type>textarea</frontend_type>
70
- <sort_order>3</sort_order>
71
- <show_in_default>1</show_in_default>
72
- <show_in_website>1</show_in_website>
73
- <show_in_store>1</show_in_store>
74
- </config>
75
- <tracking_view_url translate="label">
76
- <label>Tracking URL</label>
77
- <frontend_type>text</frontend_type>
78
- <sort_order>4</sort_order>
79
- <show_in_default>1</show_in_default>
80
- <show_in_website>1</show_in_website>
81
- <show_in_store>1</show_in_store>
82
- </tracking_view_url>
83
- <debug translate="label">
84
- <label>Debug</label>
85
- <frontend_type>select</frontend_type>
86
- <source_model>adminhtml/system_config_source_yesno</source_model>
87
- <comment>{debug_help}</comment>
88
- <sort_order>5</sort_order>
89
- <show_in_default>1</show_in_default>
90
- <show_in_website>1</show_in_website>
91
- <show_in_store>1</show_in_store>
92
- </debug>
93
- <compression translate="label">
94
- <label>Compression</label>
95
- <frontend_type>select</frontend_type>
96
- <source_model>adminhtml/system_config_source_yesno</source_model>
97
- <comment>{compression_help}</comment>
98
- <sort_order>6</sort_order>
99
- <show_in_default>1</show_in_default>
100
- <show_in_website>1</show_in_website>
101
- <show_in_store>1</show_in_store>
102
- </compression>
103
- <auto_escaping translate="label">
104
- <label>Auto-escaping</label>
105
- <frontend_type>select</frontend_type>
106
- <source_model>adminhtml/system_config_source_yesno</source_model>
107
- <comment>{auto_escaping_help}</comment>
108
- <sort_order>7</sort_order>
109
- <show_in_default>1</show_in_default>
110
- <show_in_website>1</show_in_website>
111
- <show_in_store>1</show_in_store>
112
- </auto_escaping>
113
- <auto_correction translate="label">
114
- <label>Auto-correction</label>
115
- <frontend_type>select</frontend_type>
116
- <source_model>adminhtml/system_config_source_yesno</source_model>
117
- <comment>{auto_correction_help}</comment>
118
- <sort_order>8</sort_order>
119
- <show_in_default>1</show_in_default>
120
- <show_in_website>1</show_in_website>
121
- <show_in_store>1</show_in_store>
122
- </auto_correction>
123
- <stop_to_first_match translate="label">
124
- <label>Stop to first match</label>
125
- <frontend_type>select</frontend_type>
126
- <source_model>adminhtml/system_config_source_yesno</source_model>
127
- <sort_order>9</sort_order>
128
- <show_in_default>1</show_in_default>
129
- <show_in_website>1</show_in_website>
130
- <show_in_store>1</show_in_store>
131
- </stop_to_first_match>
132
- <sort_order translate="label">
133
- <label>Sort order</label>
134
- <frontend_type>text</frontend_type>
135
- <sort_order>100</sort_order>
136
- <show_in_default>1</show_in_default>
137
- <show_in_website>1</show_in_website>
138
- <show_in_store>1</show_in_store>
139
- </sort_order>
140
- </fields>
141
- </owebiashipping1>
142
- <owebiashipping3 translate="label" module="shipping">
143
- <label>Owebia Shipping - Mode de livraison 3</label>
144
- <frontend_type>text</frontend_type>
145
- <sort_order>-17</sort_order>
146
- <show_in_default>1</show_in_default>
147
- <show_in_website>1</show_in_website>
148
- <show_in_store>1</show_in_store>
149
- <fields>
150
- <informations translate="label">
151
- <label>Informations</label>
152
- <frontend_model>owebia_shipping2/adminhtml_system_config_form_field_informations</frontend_model>
153
- <sort_order>0</sort_order>
154
- <show_in_default>1</show_in_default>
155
- <show_in_website>1</show_in_website>
156
- <show_in_store>1</show_in_store>
157
- </informations>
158
- <active translate="label">
159
- <label>Enabled</label>
160
- <frontend_type>select</frontend_type>
161
- <source_model>adminhtml/system_config_source_yesno</source_model>
162
- <sort_order>1</sort_order>
163
- <show_in_default>1</show_in_default>
164
- <show_in_website>1</show_in_website>
165
- <show_in_store>1</show_in_store>
166
- </active>
167
- <title translate="label">
168
- <label>Title</label>
169
- <frontend_type>text</frontend_type>
170
- <sort_order>2</sort_order>
171
- <show_in_default>1</show_in_default>
172
- <show_in_website>1</show_in_website>
173
- <show_in_store>1</show_in_store>
174
- </title>
175
- <config translate="label">
176
- <label>Configuration</label>
177
- <frontend_model>owebia_shipping2/adminhtml_system_config_form_field_config</frontend_model>
178
- <frontend_type>textarea</frontend_type>
179
- <sort_order>3</sort_order>
180
- <show_in_default>1</show_in_default>
181
- <show_in_website>1</show_in_website>
182
- <show_in_store>1</show_in_store>
183
- </config>
184
- <tracking_view_url translate="label">
185
- <label>Tracking URL</label>
186
- <frontend_type>text</frontend_type>
187
- <sort_order>4</sort_order>
188
- <show_in_default>1</show_in_default>
189
- <show_in_website>1</show_in_website>
190
- <show_in_store>1</show_in_store>
191
- </tracking_view_url>
192
- <debug translate="label">
193
- <label>Debug</label>
194
- <frontend_type>select</frontend_type>
195
- <source_model>adminhtml/system_config_source_yesno</source_model>
196
- <comment>{debug_help}</comment>
197
- <sort_order>5</sort_order>
198
- <show_in_default>1</show_in_default>
199
- <show_in_website>1</show_in_website>
200
- <show_in_store>1</show_in_store>
201
- </debug>
202
- <compression translate="label">
203
- <label>Compression</label>
204
- <frontend_type>select</frontend_type>
205
- <source_model>adminhtml/system_config_source_yesno</source_model>
206
- <comment>{compression_help}</comment>
207
- <sort_order>6</sort_order>
208
- <show_in_default>1</show_in_default>
209
- <show_in_website>1</show_in_website>
210
- <show_in_store>1</show_in_store>
211
- </compression>
212
- <auto_escaping translate="label">
213
- <label>Auto-escaping</label>
214
- <frontend_type>select</frontend_type>
215
- <source_model>adminhtml/system_config_source_yesno</source_model>
216
- <comment>{auto_escaping_help}</comment>
217
- <sort_order>7</sort_order>
218
- <show_in_default>1</show_in_default>
219
- <show_in_website>1</show_in_website>
220
- <show_in_store>1</show_in_store>
221
- </auto_escaping>
222
- <auto_correction translate="label">
223
- <label>Auto-correction</label>
224
- <frontend_type>select</frontend_type>
225
- <source_model>adminhtml/system_config_source_yesno</source_model>
226
- <comment>{auto_correction_help}</comment>
227
- <sort_order>8</sort_order>
228
- <show_in_default>1</show_in_default>
229
- <show_in_website>1</show_in_website>
230
- <show_in_store>1</show_in_store>
231
- </auto_correction>
232
- <stop_to_first_match translate="label">
233
- <label>Stop to first match</label>
234
- <frontend_type>select</frontend_type>
235
- <source_model>adminhtml/system_config_source_yesno</source_model>
236
- <sort_order>9</sort_order>
237
- <show_in_default>1</show_in_default>
238
- <show_in_website>1</show_in_website>
239
- <show_in_store>1</show_in_store>
240
- </stop_to_first_match>
241
- <sort_order translate="label">
242
- <label>Sort order</label>
243
- <frontend_type>text</frontend_type>
244
- <sort_order>100</sort_order>
245
- <show_in_default>1</show_in_default>
246
- <show_in_website>1</show_in_website>
247
- <show_in_store>1</show_in_store>
248
- </sort_order>
249
- </fields>
250
- </owebiashipping3>
251
- <owebiashipping2 translate="label" module="shipping">
252
- <label>Owebia Shipping - Mode de livraison 2</label>
253
- <frontend_type>text</frontend_type>
254
- <sort_order>-18</sort_order>
255
- <show_in_default>1</show_in_default>
256
- <show_in_website>1</show_in_website>
257
- <show_in_store>1</show_in_store>
258
- <fields>
259
- <informations translate="label">
260
- <label>Informations</label>
261
- <frontend_model>owebia_shipping2/adminhtml_system_config_form_field_informations</frontend_model>
262
- <sort_order>0</sort_order>
263
- <show_in_default>1</show_in_default>
264
- <show_in_website>1</show_in_website>
265
- <show_in_store>1</show_in_store>
266
- </informations>
267
- <active translate="label">
268
- <label>Enabled</label>
269
- <frontend_type>select</frontend_type>
270
- <source_model>adminhtml/system_config_source_yesno</source_model>
271
- <sort_order>1</sort_order>
272
- <show_in_default>1</show_in_default>
273
- <show_in_website>1</show_in_website>
274
- <show_in_store>1</show_in_store>
275
- </active>
276
- <title translate="label">
277
- <label>Title</label>
278
- <frontend_type>text</frontend_type>
279
- <sort_order>2</sort_order>
280
- <show_in_default>1</show_in_default>
281
- <show_in_website>1</show_in_website>
282
- <show_in_store>1</show_in_store>
283
- </title>
284
- <config translate="label">
285
- <label>Configuration</label>
286
- <frontend_model>owebia_shipping2/adminhtml_system_config_form_field_config</frontend_model>
287
- <frontend_type>textarea</frontend_type>
288
- <sort_order>3</sort_order>
289
- <show_in_default>1</show_in_default>
290
- <show_in_website>1</show_in_website>
291
- <show_in_store>1</show_in_store>
292
- </config>
293
- <tracking_view_url translate="label">
294
- <label>Tracking URL</label>
295
- <frontend_type>text</frontend_type>
296
- <sort_order>4</sort_order>
297
- <show_in_default>1</show_in_default>
298
- <show_in_website>1</show_in_website>
299
- <show_in_store>1</show_in_store>
300
- </tracking_view_url>
301
- <debug translate="label">
302
- <label>Debug</label>
303
- <frontend_type>select</frontend_type>
304
- <source_model>adminhtml/system_config_source_yesno</source_model>
305
- <comment>{debug_help}</comment>
306
- <sort_order>5</sort_order>
307
- <show_in_default>1</show_in_default>
308
- <show_in_website>1</show_in_website>
309
- <show_in_store>1</show_in_store>
310
- </debug>
311
- <compression translate="label">
312
- <label>Compression</label>
313
- <frontend_type>select</frontend_type>
314
- <source_model>adminhtml/system_config_source_yesno</source_model>
315
- <comment>{compression_help}</comment>
316
- <sort_order>6</sort_order>
317
- <show_in_default>1</show_in_default>
318
- <show_in_website>1</show_in_website>
319
- <show_in_store>1</show_in_store>
320
- </compression>
321
- <auto_escaping translate="label">
322
- <label>Auto-escaping</label>
323
- <frontend_type>select</frontend_type>
324
- <source_model>adminhtml/system_config_source_yesno</source_model>
325
- <comment>{auto_escaping_help}</comment>
326
- <sort_order>7</sort_order>
327
- <show_in_default>1</show_in_default>
328
- <show_in_website>1</show_in_website>
329
- <show_in_store>1</show_in_store>
330
- </auto_escaping>
331
- <auto_correction translate="label">
332
- <label>Auto-correction</label>
333
- <frontend_type>select</frontend_type>
334
- <source_model>adminhtml/system_config_source_yesno</source_model>
335
- <comment>{auto_correction_help}</comment>
336
- <sort_order>8</sort_order>
337
- <show_in_default>1</show_in_default>
338
- <show_in_website>1</show_in_website>
339
- <show_in_store>1</show_in_store>
340
- </auto_correction>
341
- <stop_to_first_match translate="label">
342
- <label>Stop to first match</label>
343
- <frontend_type>select</frontend_type>
344
- <source_model>adminhtml/system_config_source_yesno</source_model>
345
- <sort_order>9</sort_order>
346
- <show_in_default>1</show_in_default>
347
- <show_in_website>1</show_in_website>
348
- <show_in_store>1</show_in_store>
349
- </stop_to_first_match>
350
- <sort_order translate="label">
351
- <label>Sort order</label>
352
- <frontend_type>text</frontend_type>
353
- <sort_order>100</sort_order>
354
- <show_in_default>1</show_in_default>
355
- <show_in_website>1</show_in_website>
356
- <show_in_store>1</show_in_store>
357
- </sort_order>
358
- </fields>
359
- </owebiashipping2>
360
- <owebiashipping4 translate="label" module="shipping">
361
- <label>Owebia Shipping - Mode de livraison 4</label>
362
- <frontend_type>text</frontend_type>
363
- <sort_order>-16</sort_order>
364
- <show_in_default>1</show_in_default>
365
- <show_in_website>1</show_in_website>
366
- <show_in_store>1</show_in_store>
367
- <fields>
368
- <informations translate="label">
369
- <label>Informations</label>
370
- <frontend_model>owebia_shipping2/adminhtml_system_config_form_field_informations</frontend_model>
371
- <sort_order>0</sort_order>
372
- <show_in_default>1</show_in_default>
373
- <show_in_website>1</show_in_website>
374
- <show_in_store>1</show_in_store>
375
- </informations>
376
- <active translate="label">
377
- <label>Enabled</label>
378
- <frontend_type>select</frontend_type>
379
- <source_model>adminhtml/system_config_source_yesno</source_model>
380
- <sort_order>1</sort_order>
381
- <show_in_default>1</show_in_default>
382
- <show_in_website>1</show_in_website>
383
- <show_in_store>1</show_in_store>
384
- </active>
385
- <title translate="label">
386
- <label>Title</label>
387
- <frontend_type>text</frontend_type>
388
- <sort_order>2</sort_order>
389
- <show_in_default>1</show_in_default>
390
- <show_in_website>1</show_in_website>
391
- <show_in_store>1</show_in_store>
392
- </title>
393
- <config translate="label">
394
- <label>Configuration</label>
395
- <frontend_model>owebia_shipping2/adminhtml_system_config_form_field_config</frontend_model>
396
- <frontend_type>textarea</frontend_type>
397
- <sort_order>3</sort_order>
398
- <show_in_default>1</show_in_default>
399
- <show_in_website>1</show_in_website>
400
- <show_in_store>1</show_in_store>
401
- </config>
402
- <tracking_view_url translate="label">
403
- <label>Tracking URL</label>
404
- <frontend_type>text</frontend_type>
405
- <sort_order>4</sort_order>
406
- <show_in_default>1</show_in_default>
407
- <show_in_website>1</show_in_website>
408
- <show_in_store>1</show_in_store>
409
- </tracking_view_url>
410
- <debug translate="label">
411
- <label>Debug</label>
412
- <frontend_type>select</frontend_type>
413
- <source_model>adminhtml/system_config_source_yesno</source_model>
414
- <comment>{debug_help}</comment>
415
- <sort_order>5</sort_order>
416
- <show_in_default>1</show_in_default>
417
- <show_in_website>1</show_in_website>
418
- <show_in_store>1</show_in_store>
419
- </debug>
420
- <compression translate="label">
421
- <label>Compression</label>
422
- <frontend_type>select</frontend_type>
423
- <source_model>adminhtml/system_config_source_yesno</source_model>
424
- <comment>{compression_help}</comment>
425
- <sort_order>6</sort_order>
426
- <show_in_default>1</show_in_default>
427
- <show_in_website>1</show_in_website>
428
- <show_in_store>1</show_in_store>
429
- </compression>
430
- <auto_escaping translate="label">
431
- <label>Auto-escaping</label>
432
- <frontend_type>select</frontend_type>
433
- <source_model>adminhtml/system_config_source_yesno</source_model>
434
- <comment>{auto_escaping_help}</comment>
435
- <sort_order>7</sort_order>
436
- <show_in_default>1</show_in_default>
437
- <show_in_website>1</show_in_website>
438
- <show_in_store>1</show_in_store>
439
- </auto_escaping>
440
- <auto_correction translate="label">
441
- <label>Auto-correction</label>
442
- <frontend_type>select</frontend_type>
443
- <source_model>adminhtml/system_config_source_yesno</source_model>
444
- <comment>{auto_correction_help}</comment>
445
- <sort_order>8</sort_order>
446
- <show_in_default>1</show_in_default>
447
- <show_in_website>1</show_in_website>
448
- <show_in_store>1</show_in_store>
449
- </auto_correction>
450
- <stop_to_first_match translate="label">
451
- <label>Stop to first match</label>
452
- <frontend_type>select</frontend_type>
453
- <source_model>adminhtml/system_config_source_yesno</source_model>
454
- <sort_order>9</sort_order>
455
- <show_in_default>1</show_in_default>
456
- <show_in_website>1</show_in_website>
457
- <show_in_store>1</show_in_store>
458
- </stop_to_first_match>
459
- <sort_order translate="label">
460
- <label>Sort order</label>
461
- <frontend_type>text</frontend_type>
462
- <sort_order>100</sort_order>
463
- <show_in_default>1</show_in_default>
464
- <show_in_website>1</show_in_website>
465
- <show_in_store>1</show_in_store>
466
- </sort_order>
467
- </fields>
468
- </owebiashipping4>
469
- </groups>
470
- </carriers>
471
- </sections>
472
- <sections>
473
- <owebia_shipping2 translate="label">
474
- <label>Owebia Shipping 2</label>
475
- <tab>owebia</tab>
476
- <frontend_type>text</frontend_type>
477
- <sort_order>100</sort_order>
478
- <show_in_default>1</show_in_default>
479
- <show_in_website>1</show_in_website>
480
- <show_in_store>1</show_in_store>
481
- <groups>
482
- <general translate="label">
483
- <label>General Configuration</label>
484
- <frontend_type>text</frontend_type>
485
- <sort_order>2</sort_order>
486
- <show_in_default>1</show_in_default>
487
- <show_in_website>1</show_in_website>
488
- <show_in_store>1</show_in_store>
489
- <fields>
490
- <weight_unit translate="label">
491
- <label>Weight unit</label>
492
- <frontend_type>text</frontend_type>
493
- <sort_order>1</sort_order>
494
- <show_in_default>1</show_in_default>
495
- <show_in_website>1</show_in_website>
496
- <show_in_store>1</show_in_store>
497
- </weight_unit>
498
- </fields>
499
- </general>
500
- <bundle_product translate="label">
501
- <label>Bundle Product Management</label>
502
- <frontend_type>text</frontend_type>
503
- <sort_order>10</sort_order>
504
- <show_in_default>1</show_in_default>
505
- <show_in_website>1</show_in_website>
506
- <show_in_store>1</show_in_store>
507
- <fields>
508
- <process_children translate="label">
509
- <label>Item processing</label>
510
- <comment>If "Self" is selected, options bellow are ignored</comment>
511
- <frontend_type>select</frontend_type>
512
- <source_model>owebia_shipping2/system_config_source_ProcessChildren</source_model>
513
- <sort_order>10</sort_order>
514
- <show_in_default>1</show_in_default>
515
- <show_in_website>1</show_in_website>
516
- <show_in_store>1</show_in_store>
517
- </process_children>
518
- <load_item_options_on_parent translate="label">
519
- <label>Item options on</label>
520
- <comment>item.option.*</comment>
521
- <frontend_type>select</frontend_type>
522
- <source_model>owebia_shipping2/system_config_source_LoadOnParent</source_model>
523
- <sort_order>20</sort_order>
524
- <show_in_default>1</show_in_default>
525
- <show_in_website>1</show_in_website>
526
- <show_in_store>1</show_in_store>
527
- </load_item_options_on_parent>
528
- <load_item_data_on_parent translate="label">
529
- <label>Item data on</label>
530
- <comment>item.*</comment>
531
- <frontend_type>select</frontend_type>
532
- <source_model>owebia_shipping2/system_config_source_LoadOnParent</source_model>
533
- <sort_order>21</sort_order>
534
- <show_in_default>1</show_in_default>
535
- <show_in_website>1</show_in_website>
536
- <show_in_store>1</show_in_store>
537
- </load_item_data_on_parent>
538
- <load_product_data_on_parent translate="label">
539
- <label>Product data on</label>
540
- <comment>product.*</comment>
541
- <frontend_type>select</frontend_type>
542
- <source_model>owebia_shipping2/system_config_source_LoadOnParent</source_model>
543
- <sort_order>22</sort_order>
544
- <show_in_default>1</show_in_default>
545
- <show_in_website>1</show_in_website>
546
- <show_in_store>1</show_in_store>
547
- </load_product_data_on_parent>
548
- </fields>
549
- </bundle_product>
550
- <configurable_product translate="label">
551
- <label>Configurable Product Management</label>
552
- <frontend_type>text</frontend_type>
553
- <sort_order>20</sort_order>
554
- <show_in_default>1</show_in_default>
555
- <show_in_website>1</show_in_website>
556
- <show_in_store>1</show_in_store>
557
- <fields>
558
- <load_item_options_on_parent translate="label">
559
- <label>Item options on</label>
560
- <comment>item.option.*</comment>
561
- <frontend_type>select</frontend_type>
562
- <source_model>owebia_shipping2/system_config_source_LoadOnParent</source_model>
563
- <sort_order>20</sort_order>
564
- <show_in_default>1</show_in_default>
565
- <show_in_website>1</show_in_website>
566
- <show_in_store>1</show_in_store>
567
- </load_item_options_on_parent>
568
- <load_item_data_on_parent translate="label">
569
- <label>Item data on</label>
570
- <comment>item.*</comment>
571
- <frontend_type>select</frontend_type>
572
- <source_model>owebia_shipping2/system_config_source_LoadOnParent</source_model>
573
- <sort_order>21</sort_order>
574
- <show_in_default>1</show_in_default>
575
- <show_in_website>1</show_in_website>
576
- <show_in_store>1</show_in_store>
577
- </load_item_data_on_parent>
578
- <load_product_data_on_parent translate="label">
579
- <label>Product data on</label>
580
- <comment>product.*</comment>
581
- <frontend_type>select</frontend_type>
582
- <source_model>owebia_shipping2/system_config_source_LoadOnParent</source_model>
583
- <sort_order>23</sort_order>
584
- <show_in_default>1</show_in_default>
585
- <show_in_website>1</show_in_website>
586
- <show_in_store>1</show_in_store>
587
- </load_product_data_on_parent>
588
- </fields>
589
- </configurable_product>
590
- </groups>
591
- </owebia_shipping2>
592
- </sections>
593
  </config>
20
  **/
21
  -->
22
  <config>
23
+ <tabs>
24
+ <owebia>
25
+ <label>Owebia</label>
26
+ <sort_order>300</sort_order>
27
+ </owebia>
28
+ </tabs>
29
+ <sections>
30
+ <carriers>
31
+ <show_in_store>1</show_in_store>
32
+ <groups>
33
+ <owebiashipping1 translate="label" module="shipping">
34
+ <label>Owebia Shipping - Mode de livraison 1</label>
35
+ <frontend_type>text</frontend_type>
36
+ <sort_order>-19</sort_order>
37
+ <show_in_default>1</show_in_default>
38
+ <show_in_website>1</show_in_website>
39
+ <show_in_store>1</show_in_store>
40
+ <fields>
41
+ <informations translate="label">
42
+ <label>Informations</label>
43
+ <frontend_model>owebia_shipping2/adminhtml_system_config_form_field_informations</frontend_model>
44
+ <sort_order>0</sort_order>
45
+ <show_in_default>1</show_in_default>
46
+ <show_in_website>1</show_in_website>
47
+ <show_in_store>1</show_in_store>
48
+ </informations>
49
+ <active translate="label">
50
+ <label>Enabled</label>
51
+ <frontend_type>select</frontend_type>
52
+ <source_model>adminhtml/system_config_source_yesno</source_model>
53
+ <sort_order>1</sort_order>
54
+ <show_in_default>1</show_in_default>
55
+ <show_in_website>1</show_in_website>
56
+ <show_in_store>1</show_in_store>
57
+ </active>
58
+ <title translate="label">
59
+ <label>Title</label>
60
+ <frontend_type>text</frontend_type>
61
+ <sort_order>2</sort_order>
62
+ <show_in_default>1</show_in_default>
63
+ <show_in_website>1</show_in_website>
64
+ <show_in_store>1</show_in_store>
65
+ </title>
66
+ <config translate="label">
67
+ <label>Configuration</label>
68
+ <frontend_model>owebia_shipping2/adminhtml_system_config_form_field_config</frontend_model>
69
+ <frontend_type>textarea</frontend_type>
70
+ <sort_order>3</sort_order>
71
+ <show_in_default>1</show_in_default>
72
+ <show_in_website>1</show_in_website>
73
+ <show_in_store>1</show_in_store>
74
+ </config>
75
+ <tracking_view_url translate="label">
76
+ <label>Tracking URL</label>
77
+ <frontend_type>text</frontend_type>
78
+ <sort_order>4</sort_order>
79
+ <show_in_default>1</show_in_default>
80
+ <show_in_website>1</show_in_website>
81
+ <show_in_store>1</show_in_store>
82
+ </tracking_view_url>
83
+ <debug translate="label">
84
+ <label>Debug</label>
85
+ <frontend_type>select</frontend_type>
86
+ <source_model>adminhtml/system_config_source_yesno</source_model>
87
+ <comment>{debug_help}</comment>
88
+ <sort_order>5</sort_order>
89
+ <show_in_default>1</show_in_default>
90
+ <show_in_website>1</show_in_website>
91
+ <show_in_store>1</show_in_store>
92
+ </debug>
93
+ <compression translate="label">
94
+ <label>Compression</label>
95
+ <frontend_type>select</frontend_type>
96
+ <source_model>adminhtml/system_config_source_yesno</source_model>
97
+ <comment>{compression_help}</comment>
98
+ <sort_order>6</sort_order>
99
+ <show_in_default>1</show_in_default>
100
+ <show_in_website>1</show_in_website>
101
+ <show_in_store>1</show_in_store>
102
+ </compression>
103
+ <auto_escaping translate="label">
104
+ <label>Auto-escaping</label>
105
+ <frontend_type>select</frontend_type>
106
+ <source_model>adminhtml/system_config_source_yesno</source_model>
107
+ <comment>{auto_escaping_help}</comment>
108
+ <sort_order>7</sort_order>
109
+ <show_in_default>1</show_in_default>
110
+ <show_in_website>1</show_in_website>
111
+ <show_in_store>1</show_in_store>
112
+ </auto_escaping>
113
+ <auto_correction translate="label">
114
+ <label>Auto-correction</label>
115
+ <frontend_type>select</frontend_type>
116
+ <source_model>adminhtml/system_config_source_yesno</source_model>
117
+ <comment>{auto_correction_help}</comment>
118
+ <sort_order>8</sort_order>
119
+ <show_in_default>1</show_in_default>
120
+ <show_in_website>1</show_in_website>
121
+ <show_in_store>1</show_in_store>
122
+ </auto_correction>
123
+ <stop_to_first_match translate="label">
124
+ <label>Stop to first match</label>
125
+ <frontend_type>select</frontend_type>
126
+ <source_model>adminhtml/system_config_source_yesno</source_model>
127
+ <sort_order>9</sort_order>
128
+ <show_in_default>1</show_in_default>
129
+ <show_in_website>1</show_in_website>
130
+ <show_in_store>1</show_in_store>
131
+ </stop_to_first_match>
132
+ <sort_order translate="label">
133
+ <label>Sort order</label>
134
+ <frontend_type>text</frontend_type>
135
+ <sort_order>100</sort_order>
136
+ <show_in_default>1</show_in_default>
137
+ <show_in_website>1</show_in_website>
138
+ <show_in_store>1</show_in_store>
139
+ </sort_order>
140
+ </fields>
141
+ </owebiashipping1>
142
+ <owebiashipping2 translate="label" module="shipping">
143
+ <label>Owebia Shipping - Mode de livraison 2</label>
144
+ <frontend_type>text</frontend_type>
145
+ <sort_order>-18</sort_order>
146
+ <show_in_default>1</show_in_default>
147
+ <show_in_website>1</show_in_website>
148
+ <show_in_store>1</show_in_store>
149
+ <fields>
150
+ <informations translate="label">
151
+ <label>Informations</label>
152
+ <frontend_model>owebia_shipping2/adminhtml_system_config_form_field_informations</frontend_model>
153
+ <sort_order>0</sort_order>
154
+ <show_in_default>1</show_in_default>
155
+ <show_in_website>1</show_in_website>
156
+ <show_in_store>1</show_in_store>
157
+ </informations>
158
+ <active translate="label">
159
+ <label>Enabled</label>
160
+ <frontend_type>select</frontend_type>
161
+ <source_model>adminhtml/system_config_source_yesno</source_model>
162
+ <sort_order>1</sort_order>
163
+ <show_in_default>1</show_in_default>
164
+ <show_in_website>1</show_in_website>
165
+ <show_in_store>1</show_in_store>
166
+ </active>
167
+ <title translate="label">
168
+ <label>Title</label>
169
+ <frontend_type>text</frontend_type>
170
+ <sort_order>2</sort_order>
171
+ <show_in_default>1</show_in_default>
172
+ <show_in_website>1</show_in_website>
173
+ <show_in_store>1</show_in_store>
174
+ </title>
175
+ <config translate="label">
176
+ <label>Configuration</label>
177
+ <frontend_model>owebia_shipping2/adminhtml_system_config_form_field_config</frontend_model>
178
+ <frontend_type>textarea</frontend_type>
179
+ <sort_order>3</sort_order>
180
+ <show_in_default>1</show_in_default>
181
+ <show_in_website>1</show_in_website>
182
+ <show_in_store>1</show_in_store>
183
+ </config>
184
+ <tracking_view_url translate="label">
185
+ <label>Tracking URL</label>
186
+ <frontend_type>text</frontend_type>
187
+ <sort_order>4</sort_order>
188
+ <show_in_default>1</show_in_default>
189
+ <show_in_website>1</show_in_website>
190
+ <show_in_store>1</show_in_store>
191
+ </tracking_view_url>
192
+ <debug translate="label">
193
+ <label>Debug</label>
194
+ <frontend_type>select</frontend_type>
195
+ <source_model>adminhtml/system_config_source_yesno</source_model>
196
+ <comment>{debug_help}</comment>
197
+ <sort_order>5</sort_order>
198
+ <show_in_default>1</show_in_default>
199
+ <show_in_website>1</show_in_website>
200
+ <show_in_store>1</show_in_store>
201
+ </debug>
202
+ <compression translate="label">
203
+ <label>Compression</label>
204
+ <frontend_type>select</frontend_type>
205
+ <source_model>adminhtml/system_config_source_yesno</source_model>
206
+ <comment>{compression_help}</comment>
207
+ <sort_order>6</sort_order>
208
+ <show_in_default>1</show_in_default>
209
+ <show_in_website>1</show_in_website>
210
+ <show_in_store>1</show_in_store>
211
+ </compression>
212
+ <auto_escaping translate="label">
213
+ <label>Auto-escaping</label>
214
+ <frontend_type>select</frontend_type>
215
+ <source_model>adminhtml/system_config_source_yesno</source_model>
216
+ <comment>{auto_escaping_help}</comment>
217
+ <sort_order>7</sort_order>
218
+ <show_in_default>1</show_in_default>
219
+ <show_in_website>1</show_in_website>
220
+ <show_in_store>1</show_in_store>
221
+ </auto_escaping>
222
+ <auto_correction translate="label">
223
+ <label>Auto-correction</label>
224
+ <frontend_type>select</frontend_type>
225
+ <source_model>adminhtml/system_config_source_yesno</source_model>
226
+ <comment>{auto_correction_help}</comment>
227
+ <sort_order>8</sort_order>
228
+ <show_in_default>1</show_in_default>
229
+ <show_in_website>1</show_in_website>
230
+ <show_in_store>1</show_in_store>
231
+ </auto_correction>
232
+ <stop_to_first_match translate="label">
233
+ <label>Stop to first match</label>
234
+ <frontend_type>select</frontend_type>
235
+ <source_model>adminhtml/system_config_source_yesno</source_model>
236
+ <sort_order>9</sort_order>
237
+ <show_in_default>1</show_in_default>
238
+ <show_in_website>1</show_in_website>
239
+ <show_in_store>1</show_in_store>
240
+ </stop_to_first_match>
241
+ <sort_order translate="label">
242
+ <label>Sort order</label>
243
+ <frontend_type>text</frontend_type>
244
+ <sort_order>100</sort_order>
245
+ <show_in_default>1</show_in_default>
246
+ <show_in_website>1</show_in_website>
247
+ <show_in_store>1</show_in_store>
248
+ </sort_order>
249
+ </fields>
250
+ </owebiashipping2>
251
+ <owebiashipping3 translate="label" module="shipping">
252
+ <label>Owebia Shipping - Mode de livraison 3</label>
253
+ <frontend_type>text</frontend_type>
254
+ <sort_order>-17</sort_order>
255
+ <show_in_default>1</show_in_default>
256
+ <show_in_website>1</show_in_website>
257
+ <show_in_store>1</show_in_store>
258
+ <fields>
259
+ <informations translate="label">
260
+ <label>Informations</label>
261
+ <frontend_model>owebia_shipping2/adminhtml_system_config_form_field_informations</frontend_model>
262
+ <sort_order>0</sort_order>
263
+ <show_in_default>1</show_in_default>
264
+ <show_in_website>1</show_in_website>
265
+ <show_in_store>1</show_in_store>
266
+ </informations>
267
+ <active translate="label">
268
+ <label>Enabled</label>
269
+ <frontend_type>select</frontend_type>
270
+ <source_model>adminhtml/system_config_source_yesno</source_model>
271
+ <sort_order>1</sort_order>
272
+ <show_in_default>1</show_in_default>
273
+ <show_in_website>1</show_in_website>
274
+ <show_in_store>1</show_in_store>
275
+ </active>
276
+ <title translate="label">
277
+ <label>Title</label>
278
+ <frontend_type>text</frontend_type>
279
+ <sort_order>2</sort_order>
280
+ <show_in_default>1</show_in_default>
281
+ <show_in_website>1</show_in_website>
282
+ <show_in_store>1</show_in_store>
283
+ </title>
284
+ <config translate="label">
285
+ <label>Configuration</label>
286
+ <frontend_model>owebia_shipping2/adminhtml_system_config_form_field_config</frontend_model>
287
+ <frontend_type>textarea</frontend_type>
288
+ <sort_order>3</sort_order>
289
+ <show_in_default>1</show_in_default>
290
+ <show_in_website>1</show_in_website>
291
+ <show_in_store>1</show_in_store>
292
+ </config>
293
+ <tracking_view_url translate="label">
294
+ <label>Tracking URL</label>
295
+ <frontend_type>text</frontend_type>
296
+ <sort_order>4</sort_order>
297
+ <show_in_default>1</show_in_default>
298
+ <show_in_website>1</show_in_website>
299
+ <show_in_store>1</show_in_store>
300
+ </tracking_view_url>
301
+ <debug translate="label">
302
+ <label>Debug</label>
303
+ <frontend_type>select</frontend_type>
304
+ <source_model>adminhtml/system_config_source_yesno</source_model>
305
+ <comment>{debug_help}</comment>
306
+ <sort_order>5</sort_order>
307
+ <show_in_default>1</show_in_default>
308
+ <show_in_website>1</show_in_website>
309
+ <show_in_store>1</show_in_store>
310
+ </debug>
311
+ <compression translate="label">
312
+ <label>Compression</label>
313
+ <frontend_type>select</frontend_type>
314
+ <source_model>adminhtml/system_config_source_yesno</source_model>
315
+ <comment>{compression_help}</comment>
316
+ <sort_order>6</sort_order>
317
+ <show_in_default>1</show_in_default>
318
+ <show_in_website>1</show_in_website>
319
+ <show_in_store>1</show_in_store>
320
+ </compression>
321
+ <auto_escaping translate="label">
322
+ <label>Auto-escaping</label>
323
+ <frontend_type>select</frontend_type>
324
+ <source_model>adminhtml/system_config_source_yesno</source_model>
325
+ <comment>{auto_escaping_help}</comment>
326
+ <sort_order>7</sort_order>
327
+ <show_in_default>1</show_in_default>
328
+ <show_in_website>1</show_in_website>
329
+ <show_in_store>1</show_in_store>
330
+ </auto_escaping>
331
+ <auto_correction translate="label">
332
+ <label>Auto-correction</label>
333
+ <frontend_type>select</frontend_type>
334
+ <source_model>adminhtml/system_config_source_yesno</source_model>
335
+ <comment>{auto_correction_help}</comment>
336
+ <sort_order>8</sort_order>
337
+ <show_in_default>1</show_in_default>
338
+ <show_in_website>1</show_in_website>
339
+ <show_in_store>1</show_in_store>
340
+ </auto_correction>
341
+ <stop_to_first_match translate="label">
342
+ <label>Stop to first match</label>
343
+ <frontend_type>select</frontend_type>
344
+ <source_model>adminhtml/system_config_source_yesno</source_model>
345
+ <sort_order>9</sort_order>
346
+ <show_in_default>1</show_in_default>
347
+ <show_in_website>1</show_in_website>
348
+ <show_in_store>1</show_in_store>
349
+ </stop_to_first_match>
350
+ <sort_order translate="label">
351
+ <label>Sort order</label>
352
+ <frontend_type>text</frontend_type>
353
+ <sort_order>100</sort_order>
354
+ <show_in_default>1</show_in_default>
355
+ <show_in_website>1</show_in_website>
356
+ <show_in_store>1</show_in_store>
357
+ </sort_order>
358
+ </fields>
359
+ </owebiashipping3>
360
+ </groups>
361
+ </carriers>
362
+ </sections>
363
+ <sections>
364
+ <owebia_shipping2 translate="label">
365
+ <label>Owebia Shipping 2</label>
366
+ <tab>owebia</tab>
367
+ <frontend_type>text</frontend_type>
368
+ <sort_order>100</sort_order>
369
+ <show_in_default>1</show_in_default>
370
+ <show_in_website>1</show_in_website>
371
+ <show_in_store>1</show_in_store>
372
+ <groups>
373
+ <general translate="label">
374
+ <label>General Configuration</label>
375
+ <frontend_type>text</frontend_type>
376
+ <sort_order>2</sort_order>
377
+ <show_in_default>1</show_in_default>
378
+ <show_in_website>1</show_in_website>
379
+ <show_in_store>1</show_in_store>
380
+ <fields>
381
+ <weight_unit translate="label">
382
+ <label>Weight unit</label>
383
+ <frontend_type>text</frontend_type>
384
+ <sort_order>1</sort_order>
385
+ <show_in_default>1</show_in_default>
386
+ <show_in_website>1</show_in_website>
387
+ <show_in_store>1</show_in_store>
388
+ </weight_unit>
389
+ </fields>
390
+ </general>
391
+ <bundle_product translate="label">
392
+ <label>Bundle Product Management</label>
393
+ <frontend_type>text</frontend_type>
394
+ <sort_order>10</sort_order>
395
+ <show_in_default>1</show_in_default>
396
+ <show_in_website>1</show_in_website>
397
+ <show_in_store>1</show_in_store>
398
+ <fields>
399
+ <process_children translate="label">
400
+ <label>Item processing</label>
401
+ <comment>If "Self" is selected, options bellow are ignored</comment>
402
+ <frontend_type>select</frontend_type>
403
+ <source_model>owebia_shipping2/system_config_source_ProcessChildren</source_model>
404
+ <sort_order>10</sort_order>
405
+ <show_in_default>1</show_in_default>
406
+ <show_in_website>1</show_in_website>
407
+ <show_in_store>1</show_in_store>
408
+ </process_children>
409
+ <load_item_options_on_parent translate="label">
410
+ <label>Item options on</label>
411
+ <comment>item.option.*</comment>
412
+ <frontend_type>select</frontend_type>
413
+ <source_model>owebia_shipping2/system_config_source_LoadOnParent</source_model>
414
+ <sort_order>20</sort_order>
415
+ <show_in_default>1</show_in_default>
416
+ <show_in_website>1</show_in_website>
417
+ <show_in_store>1</show_in_store>
418
+ </load_item_options_on_parent>
419
+ <load_item_data_on_parent translate="label">
420
+ <label>Item data on</label>
421
+ <comment>item.*</comment>
422
+ <frontend_type>select</frontend_type>
423
+ <source_model>owebia_shipping2/system_config_source_LoadOnParent</source_model>
424
+ <sort_order>21</sort_order>
425
+ <show_in_default>1</show_in_default>
426
+ <show_in_website>1</show_in_website>
427
+ <show_in_store>1</show_in_store>
428
+ </load_item_data_on_parent>
429
+ <load_product_data_on_parent translate="label">
430
+ <label>Product data on</label>
431
+ <comment>product.*</comment>
432
+ <frontend_type>select</frontend_type>
433
+ <source_model>owebia_shipping2/system_config_source_LoadOnParent</source_model>
434
+ <sort_order>22</sort_order>
435
+ <show_in_default>1</show_in_default>
436
+ <show_in_website>1</show_in_website>
437
+ <show_in_store>1</show_in_store>
438
+ </load_product_data_on_parent>
439
+ </fields>
440
+ </bundle_product>
441
+ <configurable_product translate="label">
442
+ <label>Configurable Product Management</label>
443
+ <frontend_type>text</frontend_type>
444
+ <sort_order>20</sort_order>
445
+ <show_in_default>1</show_in_default>
446
+ <show_in_website>1</show_in_website>
447
+ <show_in_store>1</show_in_store>
448
+ <fields>
449
+ <load_item_options_on_parent translate="label">
450
+ <label>Item options on</label>
451
+ <comment>item.option.*</comment>
452
+ <frontend_type>select</frontend_type>
453
+ <source_model>owebia_shipping2/system_config_source_LoadOnParent</source_model>
454
+ <sort_order>20</sort_order>
455
+ <show_in_default>1</show_in_default>
456
+ <show_in_website>1</show_in_website>
457
+ <show_in_store>1</show_in_store>
458
+ </load_item_options_on_parent>
459
+ <load_item_data_on_parent translate="label">
460
+ <label>Item data on</label>
461
+ <comment>item.*</comment>
462
+ <frontend_type>select</frontend_type>
463
+ <source_model>owebia_shipping2/system_config_source_LoadOnParent</source_model>
464
+ <sort_order>21</sort_order>
465
+ <show_in_default>1</show_in_default>
466
+ <show_in_website>1</show_in_website>
467
+ <show_in_store>1</show_in_store>
468
+ </load_item_data_on_parent>
469
+ <load_product_data_on_parent translate="label">
470
+ <label>Product data on</label>
471
+ <comment>product.*</comment>
472
+ <frontend_type>select</frontend_type>
473
+ <source_model>owebia_shipping2/system_config_source_LoadOnParent</source_model>
474
+ <sort_order>23</sort_order>
475
+ <show_in_default>1</show_in_default>
476
+ <show_in_website>1</show_in_website>
477
+ <show_in_store>1</show_in_store>
478
+ </load_product_data_on_parent>
479
+ </fields>
480
+ </configurable_product>
481
+ </groups>
482
+ </owebia_shipping2>
483
+ </sections>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
484
  </config>
app/code/community/Owebia/Shipping2/includes/OS2_AddressFilterParser.php CHANGED
@@ -13,136 +13,136 @@
13
  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
14
  * IN THE SOFTWARE.
15
  *
16
- * @website http://www.owebia.com/
17
- * @project Magento Owebia Shipping 2 module
18
- * @author Antoine Lemoine
19
- * @license http://www.opensource.org/licenses/MIT The MIT License (MIT)
20
  **/
21
 
22
  class OS2_AddressFilterParser
23
  {
24
- protected $input = null;
25
- protected $position = null;
26
- protected $buffer_start = null;
27
 
28
- protected $output = '';
29
- protected $level = null;
30
- protected $parent_level = null;
31
- protected $regexp = false;
32
- protected $litteral = false;
33
- protected $litteral_quote = null;
34
- protected $case_insensitive = false;
35
 
36
- public function parse($input) {
37
- $this->current = array();
38
 
39
- $this->input = $input;
40
- $this->length = strlen($this->input);
41
- // look at each character
42
- $join = ' && ';
43
- for ($this->position=0; $this->position < $this->length; $this->position++) {
44
- $char = $this->input[$this->position];
45
- switch ($char) {
46
- case ')':
47
- if ($this->regexp) break;
48
- if ($this->litteral) break;
49
- $this->push($this->buffer().')');
50
- $this->parent_level = null;
51
- break;
52
- case ' ':
53
- if ($this->regexp) break;
54
- if ($this->litteral) break;
55
- $this->push($this->buffer());
56
- break;
57
- case '-':
58
- if ($this->regexp) break;
59
- if ($this->litteral) break;
60
- $this->push($this->buffer());
61
- $join = ' && !';
62
- break;
63
- case ',':
64
- if ($this->regexp) break;
65
- if ($this->litteral) break;
66
- $this->push($this->buffer());
67
- $this->push(' || ');
68
- break;
69
- case '(':
70
- if ($this->regexp) break;
71
- if ($this->litteral) break;
72
- $this->push($this->buffer());
73
- $this->push($join, $only_if_not_empty = true);
74
- $this->push('(');
75
- $this->parent_level = $this->level;
76
- $join = ' && ';
77
- break;
78
- case "'":
79
- case '"':
80
- if (!$this->litteral || $this->litteral_quote == $char) {
81
- $this->litteral = !$this->litteral;
82
- $this->litteral_quote = $char;
83
- }
84
- if ($this->buffer_start === null) {
85
- $this->buffer_start = $this->position;
86
- }
87
- break;
88
- case '/':
89
- $this->regexp = !$this->regexp;
90
- default:
91
- if ($this->buffer_start === null) {
92
- $this->buffer_start = $this->position;
93
- }
94
- }
95
- }
96
- $this->push($this->buffer());
97
- return $this->output;
98
- }
99
 
100
- protected function escapeString($input)
101
- {
102
- return OwebiaShippingHelper::escapeString($input);
103
- }
104
 
105
- protected function buffer() {
106
- if ($this->buffer_start !== null) {
107
- // extract string from buffer start to current position
108
- $buffer = substr($this->input, $this->buffer_start, $this->position - $this->buffer_start);
109
- // clean buffer
110
- $this->buffer_start = null;
111
- // throw token into current scope
112
- //var_export($buffer);echo "\n";
113
- if ($buffer=='*') {
114
- $buffer = 1;
115
- } else if ($this->parent_level=='country') {
116
- if (preg_match('/^[A-Z]{2}$/', $buffer)) {
117
- $buffer = "{{c}}==={$this->escapeString($buffer)}";
118
- $this->level = 'country';
119
- } else if (substr($buffer, 0, 1)=='/' && (substr($buffer, strlen($buffer)-1, 1)=='/' || substr($buffer, strlen($buffer)-2, 2)=='/i')) {
120
- $case_insensitive = substr($buffer, strlen($buffer)-2, 2)=='/i';
121
- $buffer = "preg_match('".str_replace("'", "\\'", $buffer)."', (string)({{p}}))";
122
- } else if (strpos($buffer, '*')!==false) {
123
- $buffer = "preg_match('/^".str_replace(array("'", '*'), array("\\'", '(?:.*)'), $buffer)."$/', (string)({{p}}))";
124
- } else if (preg_match('/^"[^"]+"$/', $buffer)) {
125
- $buffer = trim($buffer, '"');
126
- $buffer = "({{p}}==={$this->escapeString($buffer)} || {{r}}==={$this->escapeString($buffer)})";
127
- } else if (preg_match('/^\'[^\']+\'$/', $buffer)) {
128
- $buffer = trim($buffer, "'");
129
- $buffer = "({{p}}==={$this->escapeString($buffer)} || {{r}}==={$this->escapeString($buffer)})";
130
- } else {
131
- $buffer = "({{p}}==={$this->escapeString($buffer)} || {{r}}==={$this->escapeString($buffer)})";
132
- }
133
- } else if (preg_match('/^[A-Z]{2}$/', $buffer)) {
134
- $buffer = "{{c}}==={$this->escapeString($buffer)}";
135
- $this->level = 'country';
136
- }
137
- return $buffer;
138
- }
139
- return null;
140
- }
141
 
142
- protected function push($text, $only_if_not_empty = false) {
143
- if (isset($text)) {
144
- if (!$only_if_not_empty || $this->output) $this->output .= $text;
145
- //echo "\"$this->output\"<br/>";
146
- }
147
- }
148
  }
13
  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
14
  * IN THE SOFTWARE.
15
  *
16
+ * @website http://www.owebia.com/
17
+ * @project Magento Owebia Shipping 2 module
18
+ * @author Antoine Lemoine
19
+ * @license http://www.opensource.org/licenses/MIT The MIT License (MIT)
20
  **/
21
 
22
  class OS2_AddressFilterParser
23
  {
24
+ protected $input = null;
25
+ protected $position = null;
26
+ protected $buffer_start = null;
27
 
28
+ protected $output = '';
29
+ protected $level = null;
30
+ protected $parent_level = null;
31
+ protected $regexp = false;
32
+ protected $litteral = false;
33
+ protected $litteral_quote = null;
34
+ protected $case_insensitive = false;
35
 
36
+ public function parse($input) {
37
+ $this->current = array();
38
 
39
+ $this->input = $input;
40
+ $this->length = strlen($this->input);
41
+ // look at each character
42
+ $join = ' && ';
43
+ for ($this->position=0; $this->position < $this->length; $this->position++) {
44
+ $char = $this->input[$this->position];
45
+ switch ($char) {
46
+ case ')':
47
+ if ($this->regexp) break;
48
+ if ($this->litteral) break;
49
+ $this->push($this->buffer().')');
50
+ $this->parent_level = null;
51
+ break;
52
+ case ' ':
53
+ if ($this->regexp) break;
54
+ if ($this->litteral) break;
55
+ $this->push($this->buffer());
56
+ break;
57
+ case '-':
58
+ if ($this->regexp) break;
59
+ if ($this->litteral) break;
60
+ $this->push($this->buffer());
61
+ $join = ' && !';
62
+ break;
63
+ case ',':
64
+ if ($this->regexp) break;
65
+ if ($this->litteral) break;
66
+ $this->push($this->buffer());
67
+ $this->push(' || ');
68
+ break;
69
+ case '(':
70
+ if ($this->regexp) break;
71
+ if ($this->litteral) break;
72
+ $this->push($this->buffer());
73
+ $this->push($join, $only_if_not_empty = true);
74
+ $this->push('(');
75
+ $this->parent_level = $this->level;
76
+ $join = ' && ';
77
+ break;
78
+ case "'":
79
+ case '"':
80
+ if (!$this->litteral || $this->litteral_quote == $char) {
81
+ $this->litteral = !$this->litteral;
82
+ $this->litteral_quote = $char;
83
+ }
84
+ if ($this->buffer_start === null) {
85
+ $this->buffer_start = $this->position;
86
+ }
87
+ break;
88
+ case '/':
89
+ $this->regexp = !$this->regexp;
90
+ default:
91
+ if ($this->buffer_start === null) {
92
+ $this->buffer_start = $this->position;
93
+ }
94
+ }
95
+ }
96
+ $this->push($this->buffer());
97
+ return $this->output;
98
+ }
99
 
100
+ protected function escapeString($input)
101
+ {
102
+ return OwebiaShippingHelper::escapeString($input);
103
+ }
104
 
105
+ protected function buffer() {
106
+ if ($this->buffer_start !== null) {
107
+ // extract string from buffer start to current position
108
+ $buffer = substr($this->input, $this->buffer_start, $this->position - $this->buffer_start);
109
+ // clean buffer
110
+ $this->buffer_start = null;
111
+ // throw token into current scope
112
+ //var_export($buffer);echo "\n";
113
+ if ($buffer=='*') {
114
+ $buffer = 1;
115
+ } else if ($this->parent_level=='country') {
116
+ if (preg_match('/^[A-Z]{2}$/', $buffer)) {
117
+ $buffer = "{{c}}==={$this->escapeString($buffer)}";
118
+ $this->level = 'country';
119
+ } else if (substr($buffer, 0, 1)=='/' && (substr($buffer, strlen($buffer)-1, 1)=='/' || substr($buffer, strlen($buffer)-2, 2)=='/i')) {
120
+ $case_insensitive = substr($buffer, strlen($buffer)-2, 2)=='/i';
121
+ $buffer = "preg_match('".str_replace("'", "\\'", $buffer)."', (string)({{p}}))";
122
+ } else if (strpos($buffer, '*')!==false) {
123
+ $buffer = "preg_match('/^".str_replace(array("'", '*'), array("\\'", '(?:.*)'), $buffer)."$/', (string)({{p}}))";
124
+ } else if (preg_match('/^"[^"]+"$/', $buffer)) {
125
+ $buffer = trim($buffer, '"');
126
+ $buffer = "({{p}}==={$this->escapeString($buffer)} || {{r}}==={$this->escapeString($buffer)})";
127
+ } else if (preg_match('/^\'[^\']+\'$/', $buffer)) {
128
+ $buffer = trim($buffer, "'");
129
+ $buffer = "({{p}}==={$this->escapeString($buffer)} || {{r}}==={$this->escapeString($buffer)})";
130
+ } else {
131
+ $buffer = "({{p}}==={$this->escapeString($buffer)} || {{r}}==={$this->escapeString($buffer)})";
132
+ }
133
+ } else if (preg_match('/^[A-Z]{2}$/', $buffer)) {
134
+ $buffer = "{{c}}==={$this->escapeString($buffer)}";
135
+ $this->level = 'country';
136
+ }
137
+ return $buffer;
138
+ }
139
+ return null;
140
+ }
141
 
142
+ protected function push($text, $only_if_not_empty = false) {
143
+ if (isset($text)) {
144
+ if (!$only_if_not_empty || $this->output) $this->output .= $text;
145
+ //echo "\"$this->output\"<br/>";
146
+ }
147
+ }
148
  }
app/code/community/Owebia/Shipping2/includes/OwebiaShippingHelper.php CHANGED
@@ -24,1448 +24,1444 @@
24
 
25
  class OwebiaShippingHelper
26
  {
27
- const FLOAT_REGEX = '[-]?\d+(?:[.]\d+)?';
28
- const COUPLE_REGEX = '(?:[0-9.]+|\*) *(?:\[|\])? *\: *[0-9.]+';
29
-
30
- public static $DEBUG_INDEX_COUNTER = 0;
31
- public static $UNCOMPRESSED_STRINGS = array(
32
- ' product.attribute.',
33
- ' item.option.',
34
- '{product.attribute.',
35
- '{item.option.',
36
- '{product.',
37
- '{cart.',
38
- '{selection.',
39
- );
40
- public static $COMPRESSED_STRINGS = array(
41
- ' p.a.',
42
- ' item.o.',
43
- '{p.a.',
44
- '{item.o.',
45
- '{p.',
46
- '{c.',
47
- '{s.',
48
- );
49
-
50
- public static function esc($input)
51
- {
52
- $input = htmlspecialchars($input, ENT_NOQUOTES, 'UTF-8');
53
- return preg_replace('/&lt;(\/?)span([^&]*)&gt;/', '<\1span\2>', $input);
54
- }
55
-
56
- public static function toString($value)
57
- {
58
- if (!isset($value)) return 'null';
59
- else if (is_bool($value)) return $value ? 'true' : 'false';
60
- else if (is_float($value)) return str_replace(',', '.', (string)$value); // To avoid locale problems
61
- else if (is_array($value)) return 'array(size:'.count($value).')';
62
- else if (is_object($value)) return get_class($value).'';
63
- else return $value;
64
- }
65
-
66
- public static function parseSize($size)
67
- {
68
- $size = trim($size);
69
- $last = strtolower($size[strlen($size)-1]);
70
- switch ($last) {
71
- case 'g': $size *= 1024;
72
- case 'm': $size *= 1024;
73
- case 'k': $size *= 1024;
74
- }
75
- return (float)$size;
76
- }
77
-
78
- public static function formatSize($size)
79
- {
80
- $unit = array('B', 'KB', 'MB', 'GB', 'TB', 'PB');
81
- return self::toString(@round($size/pow(1024, ($i=floor(log($size, 1024)))), 2)).' '.$unit[$i];
82
- }
83
-
84
- public static function getInfos()
85
- {
86
- $properties = array(
87
- 'server_os' => PHP_OS,
88
- 'server_software' => $_SERVER['SERVER_SOFTWARE'],
89
- 'php_version' => PHP_VERSION,
90
- 'memory_limit' => self::formatSize(self::parseSize(ini_get('memory_limit'))),
91
- 'memory_usage' => self::formatSize(memory_get_usage(true)),
92
- );
93
- return $properties;
94
- }
95
-
96
- public static function getDefaultProcessData()
97
- {
98
- return array(
99
- 'info' => new OS2_Data(self::getInfos()),
100
- 'cart' => new OS2_Data(),
101
- 'quote' => new OS2_Data(),
102
- 'selection' => new OS2_Data(),
103
- 'customer' => new OS2_Data(),
104
- 'customer_group' => new OS2_Data(),
105
- 'customvar' => new OS2_Data(),
106
- 'date' => new OS2_Data(),
107
- 'origin' => new OS2_Data(),
108
- 'shipto' => new OS2_Data(),
109
- 'billto' => new OS2_Data(),
110
- 'store' => new OS2_Data(),
111
- 'request' => new OS2_Data(),
112
- 'address_filter' => new OS2_Data(),
113
- );
114
- }
115
-
116
- public static function jsonEncode($data, $beautify = false, $html = false, $level = 0, $current_indent = '')
117
- {
118
- //$html = true;
119
- $indent = "\t";//$html ? '&nbsp;&nbsp;&nbsp;&nbsp;' : "\t";//
120
- $line_break = $html ? '<br/>' : "\n";
121
- $new_indent = $current_indent.$indent;
122
- switch ($type = gettype($data)) {
123
- case 'NULL':
124
- return ($html ? '<span class=json-reserved>' : '').'null'.($html ? '</span>' : '');
125
- case 'boolean':
126
- return ($html ? '<span class=json-reserved>' : '').($data ? 'true' : 'false').($html ? '</span>' : '');
127
- case 'integer':
128
- case 'double':
129
- case 'float':
130
- return ($html ? '<span class=json-numeric>' : '').$data.($html ? '</span>' : '');
131
- case 'string':
132
- return ($html ? '<span class=json-string>' : '').'"'.str_replace(array("\\", '"', "\n", "\r"), array("\\\\", '\"', "\\n", "\\r"), $html ? htmlspecialchars($data, ENT_COMPAT, 'UTF-8') : $data).'"'.($html ? '</span>' : '');
133
- case 'object':
134
- $data = (array)$data;
135
- case 'array':
136
- $output_index_count = 0;
137
- $output = array();
138
- foreach ($data as $key => $value) {
139
- if ($output_index_count!==null && $output_index_count++!==$key) {
140
- $output_index_count = null;
141
- }
142
- }
143
- $is_associative = $output_index_count===null;
144
- foreach ($data as $key => $value) {
145
- if ($is_associative) {
146
- $classes = array();
147
- if ($key=='about') $classes[] = 'json-about';
148
- if ($key=='conditions' || $key=='fees') $classes[] = 'json-formula';
149
- $property_classes = array('json-property');
150
- if ($level==0) $property_classes[] = 'json-id';
151
- $output[] = ($html && $classes ? '<span class="'.implode(' ', $classes).'">' : '')
152
- .($html ? '<span class="'.implode(' ', $property_classes).'">' : '')
153
- .self::jsonEncode((string)$key)
154
- .($html ? '</span>' : '').':'
155
- .($beautify ? ' ' : '')
156
- .self::jsonEncode($value, $beautify, $html, $level+1, $new_indent)
157
- .($html && $classes ? '</span>' : '');
158
- } else {
159
- $output[] = self::jsonEncode($value, $beautify, $html, $level+1, $current_indent);
160
- }
161
- }
162
- if ($is_associative) {
163
- $classes = array();
164
- if (isset($data['type']) && $data['type']=='meta') $classes[] = 'json-meta';
165
- $output = ($html && $classes ? '<span class="'.implode(' ', $classes).'">' : '')
166
- .'{'
167
- .($beautify ? "{$line_break}{$new_indent}" : '')
168
- .implode(','.($beautify ? "{$line_break}{$new_indent}" : ''), $output)
169
- .($beautify ? "{$line_break}{$current_indent}" : '')
170
- .'}'
171
- .($html && $classes ? '</span>' : '');
172
- //echo $output;
173
- return $output;
174
- } else {
175
- return '['.implode(','.($beautify ? ' ' : ''), $output).']';
176
- }
177
- default:
178
- return ''; // Not supported
179
- }
180
- }
181
-
182
- protected static function json_decode($input)
183
- {
184
- if (function_exists('json_decode')) { // PHP >= 5.2.0
185
- $output = json_decode($input);
186
- if (function_exists('json_last_error')) { // PHP >= 5.3.0
187
- $error = json_last_error();
188
- if ($error!=JSON_ERROR_NONE) throw new Exception($error);
189
- }
190
- return $output;
191
- } else {
192
- return Zend_Json::decode($input);
193
- }
194
- }
195
-
196
- protected static function json_encode($input)
197
- {
198
- if (function_exists('json_encode')) {
199
- return json_encode($input);
200
- } else {
201
- return Zend_Json::encode($input);
202
- }
203
- }
204
-
205
- public static function escapeString($input)
206
- {
207
- $escaped = self::json_encode($input);
208
- $escaped = preg_replace_callback('/\\\\u([0-9a-fA-F]{4})/', function ($match) {
209
- return mb_convert_encoding(pack('H*', $match[1]), 'UTF-8', 'UCS-2BE');
210
- }, $escaped);
211
- return $escaped;
212
- }
213
-
214
- protected $_input;
215
- protected $_config = array();
216
- protected $_messages = array();
217
- protected $_formula_cache = array();
218
- protected $_expression_cache = array();
219
- public $debug_code = null;
220
- public $debug_output = '';
221
- public $debug_header = null;
222
- protected $debug_prefix = '';
223
-
224
- public function __construct($input, $auto_correction)
225
- {
226
- $this->_input = $input;
227
- $this->_parseInput($auto_correction);
228
- }
229
-
230
- public function addDebugIndent()
231
- {
232
- $this->debug_prefix .= ' ';
233
- }
234
-
235
- public function removeDebugIndent()
236
- {
237
- $this->debug_prefix = substr($this->debug_prefix, 0, strlen($this->debug_prefix)-3);
238
- }
239
-
240
- public function debug($text)
241
- {
242
- $this->debug_output .= "<p>{$this->debug_prefix}{$text}</p>";
243
- }
244
-
245
- public function getDebug()
246
- {
247
- $index = $this->debug_code.'-'.self::$DEBUG_INDEX_COUNTER++;
248
- $output = "<style rel=stylesheet type=\"text/css\">"
249
- .".osh-debug{background:#000;color:#bbb;-webkit-opacity:0.9;-moz-opacity:0.9;opacity:0.9;text-align:left;white-space:pre-wrap;overflow:auto;}"
250
- .".osh-debug p{margin:2px 0;}"
251
- .".osh-formula{color:#f90;} .osh-key{color:#0099f7;} .osh-loop{color:#ff0;}"
252
- .".osh-error{color:#f00;} .osh-warning{color:#ff0;} .osh-info{color:#7bf700;}"
253
- .".osh-debug-content{padding:10px;font-family:monospace}"
254
- .".osh-replacement{color:#ff3000;}"
255
- ."</style>"
256
- ."<div id=osh-debug-{$index} class=osh-debug><div class=osh-debug-content><span class=osh-close style=\"float:right;cursor:pointer;\" onclick=\"document.getElementById('osh-debug-{$index}').style.display = 'none';\">[<span style=\"padding:0 5px;color:#f00;\">X</span>]</span>"
257
- ."<p>{$this->debug_header}</p>{$this->debug_output}</div></div>";
258
- return $output;
259
- }
260
-
261
- public function initDebug($code, $process)
262
- {
263
- $header = 'DEBUG OwebiaShippingHelper.php<br/>';
264
- foreach ($process as $index => $process_option) {
265
- if (in_array($index, array('data', 'options'))) {
266
- $header .= ' <span class=osh-key>'.self::esc(str_replace('.', '</span>.<span class=osh-key>', $index)).'</span> &gt;&gt;<br/>';
267
- foreach ($process_option as $object_name => $data) {
268
- if (is_object($data) || is_array($data)) {
269
- $header .= ' <span class=osh-key>'.self::esc(str_replace('.', '</span>.<span class=osh-key>', $object_name)).'</span> &gt;&gt;<br/>';
270
- $children = array();
271
- if (is_object($data)) $children = $data->__sleep();
272
- else if (is_array($data)) $children = array_keys($data);
273
- foreach ($children as $name) {
274
- $key = $name;
275
- if ($key=='*') {
276
- $header .= ' .<span class=osh-key>'.self::esc(str_replace('.', '</span>.<span class=osh-key>', $key)).'</span> = …<br/>';
277
- } else {
278
- if (is_object($data)) $value = $data->{$name};
279
- else if (is_array($data)) $children = $data[$name];
280
- $header .= ' .<span class=osh-key>'.self::esc(str_replace('.', '</span>.<span class=osh-key>', $key)).'</span> = <span class=osh-formula>'.self::esc(self::toString($value)).'</span> ('.gettype($value).')<br/>';
281
- }
282
- }
283
- } else {
284
- $header .= ' .<span class=osh-key>'.self::esc(str_replace('.', '</span>.<span class=osh-key>', $object_name)).'</span> = <span class=osh-formula>'.self::esc(self::toString($data)).'</span> ('.gettype($data).')<br/>';
285
- }
286
- }
287
- } else {
288
- $header .= ' <span class=osh-key>'.self::esc(str_replace('.', '</span>.<span class=osh-key>', $index)).'</span> = <span class=osh-formula>'.self::esc(self::toString($process_option)).'</span> ('.gettype($process_option).')<br/>';
289
- }
290
- }
291
- $this->debug_code = $code;
292
- $this->debug_header = $header;
293
- }
294
-
295
- public function getConfig()
296
- {
297
- return $this->_config;
298
- }
299
-
300
- public function getConfigRow($id)
301
- {
302
- return isset($this->_config[$id]) ? $this->_config[$id] : null;
303
- }
304
-
305
- public function setConfig($config)
306
- {
307
- return $this->_config = $config;
308
- }
309
-
310
- public function getMessages()
311
- {
312
- $messages = $this->_messages;
313
- $this->_messages = array();
314
- return $messages;
315
- }
316
-
317
- public function sortProperties($k1, $k2)
318
- {
319
- $i1 = isset($this->properties_sort[$k1]) ? $this->properties_sort[$k1] : 1000;
320
- $i2 = isset($this->properties_sort[$k2]) ? $this->properties_sort[$k2] : 1000;
321
- return $i1==$i2 ? strcmp($k1, $k2) : $i1-$i2;
322
- }
323
-
324
- public function formatConfig($compress, $keys_to_remove=array(), $html = false)
325
- {
326
- $object_array = array();
327
- $this->properties_sort = array_flip(array(
328
- 'type',
329
- 'about',
330
- 'enabled',
331
- 'label',
332
- 'description',
333
- 'shipto',
334
- 'billto',
335
- 'origin',
336
- 'conditions',
337
- 'fees',
338
- 'tracking_url',
339
- ));
340
- foreach ($this->_config as $code => $row) {
341
- $object = array();
342
- foreach ($row as $key => $property) {
343
- if (substr($key, 0, 1)!='*' && !in_array($key, $keys_to_remove)) {
344
- $object[$key] = $property['value'];
345
- }
346
- }
347
- uksort($object, array($this, 'sortProperties'));
348
- $object_array[$code] = $object;
349
- }
350
- $output = self::jsonEncode($object_array, $beautify = !$compress, $html);
351
- return $compress ? $this->compress($output) : $this->uncompress($output);
352
- }
353
-
354
- public function checkConfig()
355
- {
356
- $timestamp = time();
357
- $process = array(
358
- 'config' => $this->_config,
359
- 'data' => self::getDefaultProcessData(),
360
- 'result' => null,
361
- );
362
- foreach ($this->_config as $code => &$row) {
363
- $this->processRow($process, $row, $check_all_conditions=true);
364
- foreach ($row as $property_name => $property_value) {
365
- if (substr($property_name, 0, 1)!='*') {
366
- $this->debug(' check '.$property_name);
367
- $this->getRowProperty($row, $property_name);
368
- }
369
- }
370
- }
371
- }
372
-
373
- public function processRow($process, &$row, $is_checking=false)
374
- {
375
- if (!isset($row['*id'])) {
376
- $this->debug('skip row with unknown id');
377
- return new OS_Result(false);
378
- }
379
- $this->debug('process row <span class=osh-key>'.self::esc($row['*id']).'</span>');
380
-
381
- if (isset($row['about'])) { // Display on debug
382
- $about = $this->getRowProperty($row, 'about');
383
- }
384
-
385
- $type = $this->getRowProperty($row, 'type');
386
- if ($type=='data') {
387
- foreach ($row as $key => $data) {
388
- if (in_array($key, array('*id', 'code', 'type'))) continue;
389
- $value = isset($data['value']) ? $data['value'] : $data;
390
- $this->debug(' .<span class=osh-key>'.self::esc($key).'</span> = <span class=osh-formula>'.self::esc(self::toString($value)).'</span> ('.gettype($value).')');
391
- }
392
- return new OS_Result(false);
393
- }
394
- if (isset($type) && $type!='method') return new OS_Result(false);
395
-
396
- if (!isset($row['label']['value'])) $row['label']['value'] = '***';
397
-
398
- $enabled = $this->getRowProperty($row, 'enabled');
399
- if (isset($enabled)) {
400
- if (!$is_checking && !$enabled) {
401
- $this->addMessage('info', $row, 'enabled', 'Configuration disabled');
402
- return new OS_Result(false);
403
- }
404
- }
405
-
406
- $conditions = $this->getRowProperty($row, 'conditions');
407
- if (isset($conditions)) {
408
- $result = $this->processFormula($process, $row, 'conditions', $conditions, $is_checking);
409
- if (!$is_checking) {
410
- if (!$result->success) return $result;
411
- if (!$result->result) {
412
- $this->addMessage('info', $row, 'conditions', "The cart doesn't match conditions");
413
- return new OS_Result(false);
414
- }
415
- }
416
- }
417
-
418
- $address_properties = array(
419
- 'shipto' => "Shipping zone not allowed",
420
- 'billto' => "Billing zone not allowed",
421
- 'origin' => "Shipping origin not allowed",
422
- );
423
- foreach ($address_properties as $property_name => $failure_message) {
424
- $property_value = $this->getRowProperty($row, $property_name);
425
- if (isset($property_value)) {
426
- $match = $this->_addressMatch($process, $row, $property_name, $property_value, $process['data'][$property_name]);
427
- if (!$is_checking && !$match) {
428
- $this->addMessage('info', $row, $property_name, $failure_message);
429
- return new OS_Result(false);
430
- }
431
- }
432
- }
433
-
434
- $customer_groups = $this->getRowProperty($row, 'customer_groups');
435
- if (isset($customer_groups)) {
436
- $groups = explode(',', $customer_groups);
437
- $group_match = false;
438
- $customer_group = $process['data']['customer_group'];
439
- foreach ($groups as $group) {
440
- $group = trim($group);
441
- if ($group=='*' || $group==$customer_group->code || ctype_digit($group) && $group==$customer_group->id) {
442
- $this->debug(' group <span class=osh-replacement>'.self::esc($customer_group->code).'</span> (id:<span class=osh-replacement>'.self::esc($customer_group->id).'</span>) matches');
443
- $group_match = true;
444
- break;
445
- }
446
- }
447
- if (!$is_checking && !$group_match) {
448
- $this->addMessage('info', $row, 'customer_groups', "Customer group not allowed (%s)", $customer_group->code);
449
- return new OS_Result(false);
450
- }
451
- }
452
-
453
- $fees = $this->getRowProperty($row, 'fees');
454
- if (isset($fees)) {
455
- $result = $this->processFormula($process, $row, 'fees', $fees, $is_checking);
456
- if (!$result->success) return $result;
457
- $this->debug(' &raquo; <span class=osh-info>result</span> = <span class=osh-formula>'.self::esc(self::toString($result->result)).'</span>');
458
- return new OS_Result(true, (float)$result->result);
459
- }
460
- return new OS_Result(false);
461
- }
462
-
463
- public function getRowProperty(&$row, $key, $original_row=null, $original_key=null)
464
- {
465
- $property = null;
466
- $output = null;
467
- if (isset($original_row) && isset($original_key) && $original_row['*id']==$row['*id'] && $original_key==$key) {
468
- $this->addMessage('error', $row, $key, 'Infinite loop %s', "<span class=\"code\">{{$row['*id']}.{$key}}</span>");
469
- return array('error' => 'Infinite loop');
470
- }
471
- if (isset($row[$key]['value'])) {
472
- $property = $row[$key]['value'];
473
- $output = $property;
474
- $this->debug(' get <span class=osh-key>'.self::esc($row['*id']).'</span>.<span class=osh-key>'.self::esc($key).'</span> = <span class=osh-formula>'.self::esc(self::toString($property)).'</span>');
475
- preg_match_all('/{([a-z0-9_]+)\.([a-z0-9_]+)}/i', $output, $result_set, PREG_SET_ORDER);
476
- foreach ($result_set as $result) {
477
- list($original, $ref_code, $ref_key) = $result;
478
- if ($ref_code==$row['*id'] && $ref_key==$key) {
479
- $this->addMessage('error', $row, $key, 'Infinite loop %s', "<span class=\"code\">{$original}</span>");
480
- return null;
481
- }
482
- if (isset($this->_config[$ref_code][$ref_key]['value'])) {
483
- $replacement = $this->getRowProperty($this->_config[$ref_code], $ref_key,
484
- isset($original_row) ? $original_row : $row, isset($original_key) ? $original_key : $key);
485
- if (is_array($replacement) && isset($replacement['error'])) {
486
- return isset($original_row) ? $replacement : 'false';
487
- }
488
- $output = $this->replace('{'.$original.'}', $this->_autoEscapeStrings($replacement), $output);
489
- $output = $this->replace($original, $replacement, $output);
490
- } else {
491
- $replacement = $original;
492
- $output = $this->replace($original, $replacement, $output);
493
- }
494
- //$this->addMessage('error', $row, $key, $original.' => '.$replacement.' = '.$output);
495
- }
496
- } else {
497
- $this->debug(' get <span class=osh-key>'.self::esc($row['*id']).'</span>.<span class=osh-key>'.self::esc($key).'</span> = <span class=osh-formula>null</span>');
498
- }
499
- return $output;
500
- }
501
-
502
- public function evalInput($process, $row, $property_name, $input)
503
- {
504
- $result = $this->_prepareFormula($process, $row, $property_name, $input, $is_checking=false, $use_cache=true);
505
- return $result->success ? $result->result : $input;
506
- }
507
-
508
- public function compress($input)
509
- {
510
- $input = str_replace(
511
- self::$UNCOMPRESSED_STRINGS,
512
- self::$COMPRESSED_STRINGS,
513
- $input
514
- );
515
- if (function_exists('gzcompress') && function_exists('base64_encode')) {
516
- $input = 'gz64'.base64_encode(gzcompress($input));
517
- }
518
- return '$$'.$input;
519
- }
520
-
521
- public function uncompress($input)
522
- {
523
- if (substr($input, 0, 4)=='gz64' && function_exists('gzuncompress') && function_exists('base64_decode')) {
524
- $input = gzuncompress(base64_decode(substr($input, 4, strlen($input))));
525
- }
526
- return str_replace(
527
- self::$COMPRESSED_STRINGS,
528
- self::$UNCOMPRESSED_STRINGS,
529
- $input
530
- );
531
- }
532
-
533
- public function parseProperty($input)
534
- {
535
- if ($input==='false') return false;
536
- if ($input==='true') return true;
537
- if ($input==='null') return null;
538
- if (is_numeric($input)) return (double)$input;
539
- $value = str_replace('\"', '"', preg_replace('/^(?:"|\')(.*)(?:"|\')$/s', '$1', $input));
540
- return $value==='' ? null : $value;
541
- }
542
-
543
- protected function replace($from, $to, $input, $class_name=null, $message='replace')
544
- {
545
- if ($from===$to) return $input;
546
- if (mb_strpos($input, $from)===false) return $input;
547
- $to = self::toString($to);
548
- $to = preg_replace('/[\r\n\t]+/', ' ', $to);
549
- $this->debug(' '
550
- .($class_name ? '<span class="osh-'.$class_name.'">' : '')
551
- .$message.' <span class=osh-replacement>'.self::esc(self::toString($from)).'</span> by <span class=osh-replacement>'.self::esc($to).'</span>'
552
- .' =&gt; <span class=osh-formula>'.self::esc(str_replace($from, '<span class=osh-replacement>'.$to.'</span>', $input)).'</span>'
553
- .($class_name ? '</span>' : ''));
554
- return str_replace($from, $to, $input);
555
- }
556
-
557
- protected function _min()
558
- {
559
- $args = func_get_args();
560
- $min = null;
561
- foreach ($args as $arg) {
562
- if (isset($arg) && (!isset($min) || $min>$arg)) $min = $arg;
563
- }
564
- return $min;
565
- }
566
-
567
- protected function _max()
568
- {
569
- $args = func_get_args();
570
- $max = null;
571
- foreach ($args as $arg) {
572
- if (isset($arg) && (!isset($max) || $max<$arg)) $max = $arg;
573
- }
574
- return $max;
575
- }
576
-
577
- protected function _range($value=-1, $min_value=0, $max_value=1, $include_min_value=true, $include_max_value=true)
578
- {
579
- return ($value>$min_value || $include_min_value && $value==$min_value) && ($value<$max_value || $include_max_value && $value==$max_value);
580
- }
581
-
582
- protected function _array_match_any()
583
- {
584
- $args = func_get_args();
585
- $result = call_user_func_array('array_intersect', $args);
586
- return (bool)$result;
587
- }
588
-
589
- protected function _array_match_all()
590
- {
591
- $args = func_get_args();
592
- if (!isset($args[0])) return false;
593
- $result = call_user_func_array('array_intersect', $args);
594
- return count($result)==count($args[0]);
595
- }
596
-
597
- public function processFormula($process, &$row, $property_name, $formula_string, $is_checking, $use_cache=true)
598
- {
599
- $result = $this->_prepareFormula($process, $row, $property_name, $formula_string, $is_checking, $use_cache);
600
- if (!$result->success) return $result;
601
-
602
- $eval_result = $this->_evalFormula($result->result, $row, $property_name, $is_checking);
603
- if (!$is_checking && !isset($eval_result)) {
604
- $this->addMessage('error', $row, $property_name, 'Empty result');
605
- $result = new OS_Result(false);
606
- if ($use_cache) $this->_setCache($formula_string, $result);
607
- return $result;
608
- }
609
- $result = new OS_Result(true, $eval_result);
610
- if ($use_cache) $this->_setCache($formula_string, $result);
611
- return $result;
612
- }
613
-
614
- protected function _setCache($expression, $value)
615
- {
616
- if ($value instanceof OS_Result) {
617
- $this->_formula_cache[$expression] = $value;
618
- $this->debug(' cache <span class=osh-replacement>'.self::esc($expression).'</span> = <span class=osh-formula>'.self::esc(self::toString($value->result)).'</span> ('.gettype($value->result).')');
619
- } else {
620
- $this->_expression_cache[$expression] = $value; //self::toString($value); // In order to make isset work
621
- $this->debug(' cache <span class=osh-replacement>'.self::esc($expression).'</span> = <span class=osh-formula>'.self::esc(self::toString($value)).'</span> ('.gettype($value).')');
622
- }
623
- }
624
-
625
- protected function _getCachedExpression($original)
626
- {
627
- $replacement = $this->_expression_cache[$original];
628
- $this->debug(' get cached expression <span class=osh-replacement>'.self::esc($original).'</span> = <span class=osh-formula>'.self::esc(self::toString($replacement)).'</span> ('.gettype($replacement).')');
629
- return $replacement;
630
- }
631
-
632
- protected function _prepare_regexp($regexp)
633
- {
634
- if (!isset($this->constants)) {
635
- $reflector = new ReflectionClass(get_class($this));
636
- $this->constants = $reflector->getConstants();
637
- }
638
- foreach ($this->constants as $name => $value) {
639
- $regexp = str_replace('{'.$name.'}', $value, $regexp);
640
- }
641
- return $regexp;
642
- }
643
-
644
- protected function _preg_match($regexp, $input, &$result, $debug=false)
645
- {
646
- $regexp = $this->_prepare_regexp($regexp);
647
- if ($debug) $this->debug(' preg_match <span class=osh-replacement>'.self::esc($regexp).'</span>');
648
- return preg_match($regexp, $input, $result);
649
- }
650
-
651
- protected function _preg_match_all($regexp, $input, &$result, $debug=false)
652
- {
653
- $regexp = $this->_prepare_regexp($regexp);
654
- if ($debug) $this->debug(' preg_match_all <span class=osh-replacement>'.self::esc($regexp).'</span>');
655
- $return = preg_match_all($regexp, $input, $result, PREG_SET_ORDER);
656
- }
657
-
658
- protected function _loadValue($process, $object_name, $attribute)
659
- {
660
- switch ($object_name) {
661
- case 'item': return isset($process['data']['cart']->items[0]) ? $process['data']['cart']->items[0]->{$attribute} : null;
662
- case 'product': return isset($process['data']['cart']->items[0]) ? $process['data']['cart']->items[0]->getProduct()->{$attribute} : null;
663
- default: return isset($process['data'][$object_name]) ? $process['data'][$object_name]->{$attribute} : null;
664
- }
665
- }
666
-
667
- protected function _prepareFormula($process, $row, $property_name, $formula_string, $is_checking, $use_cache=true)
668
- {
669
- if ($use_cache && isset($this->_formula_cache[$formula_string])) {
670
- $result = $this->_formula_cache[$formula_string];
671
- $this->debug(' get cached formula <span class=osh-replacement>'.self::esc($formula_string).'</span> = <span class=osh-formula>'.self::esc(self::toString($result->result)).'</span>');
672
- return $result;
673
- }
674
-
675
- $formula = $formula_string;
676
- //$this->debug(' formula = <span class=osh-formula>'.self::esc($formula).'</span>');
677
-
678
- // foreach
679
- while ($this->_preg_match("#{foreach ((?:item|product|p)\.[a-z0-9_\+\-\.]+)}(.*){/foreach}#iU", $formula, $result)) { // ungreedy
680
- $original = $result[0];
681
- if ($use_cache && array_key_exists($original, $this->_expression_cache)) {
682
- $replacement = $this->_getCachedExpression($original);
683
- } else {
684
- $replacement = 0;
685
- $loop_var = $result[1];
686
- $selections = array();
687
- $this->debug(' foreach <span class=osh-key>'.self::esc($loop_var).'</span>');
688
- $this->addDebugIndent();
689
- $items = $process['data']['cart']->items;
690
- if ($items) {
691
- foreach ($items as $item) {
692
- $tmp_value = $this->_getItemProperty($item, $loop_var);
693
- $values = (array)$tmp_value;
694
- foreach ($values as $value_i) {
695
- $key = self::_autoEscapeStrings($value_i);
696
- $sel = isset($selections[$key]) ? $selections[$key] : null;
697
- $selections[$key]['items'][] = $item;
698
- }
699
- $this->debug(' items[<span class=osh-formula>'.self::esc((string)$item).'</span>].<span class=osh-key>'.self::esc($loop_var).'</span> = [<span class=osh-formula>'.self::esc(implode('</span>, <span class=osh-formula>', $values)).'</span>]');
700
- }
701
- }
702
- $this->removeDebugIndent();
703
- $this->debug(' <span class=osh-loop>start foreach</span>');
704
- $this->addDebugIndent();
705
- foreach ($selections as $key => $selection) {
706
- $this->debug(' <span class=osh-loop>&bull; value</span> = <span class=osh-formula>'.self::esc($key).'</span>');
707
- $this->addDebugIndent();
708
- $this->debug(' #### count '.count($process['data']['cart']->items));
709
- $process2 = $process;
710
- $process2['data']['cart'] = clone $process2['data']['cart']; // Important to not override previous items
711
- $process2['data']['cart']->items = $selection['items'];
712
- $selection['qty'] = 0;
713
- $selection['weight'] = 0;
714
- foreach ($selection['items'] as $item) {
715
- $selection['qty'] += $item->qty;
716
- $selection['weight'] += $item->weight;
717
- }
718
- if (isset($process2['data']['selection'])) {
719
- $process2['data']['selection']->set('qty', $selection['qty']);
720
- $process2['data']['selection']->set('weight', $selection['weight']);
721
- }
722
- $process_result = $this->processFormula($process2, $row, $property_name, $result[2], $is_checking, $tmp_use_cache=false);
723
- $replacement += $process_result->result;
724
- $this->debug(' &raquo; <span class=osh-info>foreach sum result</span> = <span class=osh-formula>'.self::esc(self::toString($replacement)).'</span>');
725
- $this->removeDebugIndent();
726
- }
727
- $this->removeDebugIndent();
728
- $this->debug(' <span class=osh-loop>end</span>');
729
- if ($use_cache) $this->_setCache($original, $replacement);
730
- }
731
- $formula = $this->replace($original, $replacement, $formula);
732
- }
733
-
734
- if (isset($process['data']['selection'])) {
735
- if ($process['data']['selection']->weight==null) $process['data']['selection']->set('weight', $process['data']['cart']->weight);
736
- if ($process['data']['selection']->qty==null) $process['data']['selection']->set('qty', $process['data']['cart']->qty);
737
- }
738
-
739
- // data
740
- $aliases = array(
741
- 'p' => 'product',
742
- 'c' => 'cart',
743
- 's' => 'selection',
744
- );
745
- $formula = $this->_replaceData($process, $formula, 'item|product|p|c|s', $aliases);
746
-
747
- // count, sum, min, max
748
- //while ($this->_preg_match("/{(count) products(?: where ([^}]+))?}/i", $formula, $result)
749
- // || $this->_preg_match("/{(sum|min|max|count distinct) {PRODUCT_REGEX}\.({ATTRIBUTE_REGEX}|{OPTION_REGEX}|stock)\.([a-z0-9_+-]+)(?: where ([^}]+))?}/i", $formula, $result)
750
- // || $this->_preg_match("/{(sum|min|max|count distinct) {PRODUCT_REGEX}\.(quantity)()(?: where ([^}]+))?}/i", $formula, $result)
751
- while ($this->_preg_match("/{(count)\s+items\s*(?:\s+where\s+((?:[^\"'}]|'[^']+'|\"[^\"]+\")+))?}/i", $formula, $result)
752
- || $this->_preg_match("/{(sum|min|max|count distinct) ((?:item|product|p)\.[a-z0-9_\+\-\.]+)(?: where ((?:[^\"'}]|'[^']+'|\"[^\"]+\")+))?}/i", $formula, $result)
753
- ) {
754
- $original = $result[0];
755
- if ($use_cache && array_key_exists($original, $this->_expression_cache)) {
756
- $replacement = $this->_getCachedExpression($original);
757
- } else {
758
- $replacement = $this->_processProduct($process['data']['cart']->items, $result, $row, $property_name, $is_checking);
759
- if ($use_cache) $this->_setCache($result[0], $replacement);
760
- }
761
- $formula = $this->replace($original, $replacement, $formula);
762
- }
763
-
764
- // switch
765
- while (preg_match("/{switch ([^}]+) in ([^}]+)}/i", $formula, $result)) {
766
- $original = $result[0];
767
- if ($use_cache && array_key_exists($original, $this->_expression_cache)) {
768
- $replacement = $this->_getCachedExpression($original);
769
- } else {
770
- $reference_value = $this->_evalFormula($result[1], $row, $property_name, $is_checking);
771
- $fees_table_string = $result[2];
772
-
773
- $couple_regex = '[^}:]+ *\: *[0-9.]+ *';
774
- if (!preg_match('#^ *'.$couple_regex.'(?:, *'.$couple_regex.')*$#', $fees_table_string)) {
775
- $this->addMessage('error', $row, $property_name, 'Error in switch %s', '<span class=osh-formula>'.self::esc($result[0]).'</span>');
776
- $result = new OS_Result(false);
777
- if ($use_cache) $this->_setCache($formula_string, $result);
778
- return $result;
779
- }
780
- $fees_table = explode(',', $fees_table_string);
781
-
782
- $replacement = null;
783
- foreach ($fees_table as $item) {
784
- $fee_data = explode(':', $item);
785
-
786
- $fee = trim($fee_data[1]);
787
- $value = trim($fee_data[0]);
788
- $value = $value=='*' ? '*' : $this->_evalFormula($fee_data[0], $row, $property_name, $is_checking);
789
-
790
- if ($value=='*' || $reference_value===$value) {
791
- $replacement = $fee;
792
- $this->debug(' compare <span class=osh-formula>'.self::esc($this->_autoEscapeStrings($reference_value)).'</span> == <span class=osh-formula>'.self::esc($this->_autoEscapeStrings($value)).'</span>');
793
- break;
794
- }
795
- $this->debug(' compare <span class=osh-formula>'.self::esc($this->_autoEscapeStrings($reference_value)).'</span> != <span class=osh-formula>'.self::esc($this->_autoEscapeStrings($value)).'</span>');
796
- }
797
- //$replacement = self::toString($replacement);
798
- if ($use_cache) $this->_setCache($original, $replacement);
799
- }
800
- $formula = $this->replace($original, $replacement, $formula);
801
- }
802
-
803
- // range table
804
- while (preg_match("/{table ([^}]+) in ([0-9\.:,\*\[\] ]+)}/i", $formula, $result)) {
805
- $original = $result[0];
806
- if ($use_cache && array_key_exists($original, $this->_expression_cache)) {
807
- $replacement = $this->_getCachedExpression($original);
808
- } else {
809
- $reference_value = $this->_evalFormula($result[1], $row, $property_name, $is_checking);
810
- $replacement = null;
811
- if (isset($reference_value)) {
812
- $fees_table_string = $result[2];
813
-
814
- if (!preg_match('#^'.self::COUPLE_REGEX.'(?:, *'.self::COUPLE_REGEX.')*$#', $fees_table_string)) {
815
- $this->addMessage('error', $row, $property_name, 'Error in table %s', '<span class=osh-formula>'.self::esc($result[0]).'</span>');
816
- $result = new OS_Result(false);
817
- if ($use_cache) $this->_setCache($formula_string, $result);
818
- return $result;
819
- }
820
- $fees_table = explode(',', $fees_table_string);
821
- foreach ($fees_table as $item) {
822
- $fee_data = explode(':', $item);
823
-
824
- $fee = trim($fee_data[1]);
825
- $max_value = trim($fee_data[0]);
826
-
827
- $last_char = $max_value{strlen($max_value)-1};
828
- if ($last_char=='[') $including_max_value = false;
829
- else if ($last_char==']') $including_max_value = true;
830
- else $including_max_value = true;
831
-
832
- $max_value = str_replace(array('[', ']'), '', $max_value);
833
-
834
- if ($max_value=='*' || $including_max_value && $reference_value<=$max_value || !$including_max_value && $reference_value<$max_value) {
835
- $replacement = $fee;
836
- break;
837
- }
838
- }
839
- }
840
- //$replacement = self::toString($replacement);
841
- if ($use_cache) $this->_setCache($original, $replacement);
842
- }
843
- $formula = $this->replace($original, $replacement, $formula);
844
- }
845
- $result = new OS_Result(true, $formula);
846
- return $result;
847
- }
848
-
849
- protected function _evalFormula($formula, &$row, $property_name=null, $is_checking=false)
850
- {
851
- if (is_bool($formula)) return $formula;
852
- if (!preg_match('/^(?:'
853
- .'\b(?:'
854
- .'E|e|int|float|string|boolean|object|array|true|false|null|and|or|in'
855
- .'|floor|ceil|round|rand|pow|pi|sqrt|log|exp|abs|substr|strtolower|preg_match|in_array'
856
- .'|max|min|range|array_match_any|array_match_all'
857
  .'|date|strtotime'
858
- .')\b'
859
- .'|\'[^\']*\'|\"[^\"]*\"|[0-9,\'\.\-\(\)\*\/\?\:\+\<\>\=\&\|%!]|\s)*$/', $formula)) {
860
- $errors = array(
861
- PREG_NO_ERROR => 'PREG_NO_ERROR',
862
- PREG_INTERNAL_ERROR => 'PREG_INTERNAL_ERROR',
863
- PREG_BACKTRACK_LIMIT_ERROR => 'PREG_BACKTRACK_LIMIT_ERROR',
864
- PREG_RECURSION_LIMIT_ERROR => 'PREG_RECURSION_LIMIT_ERROR',
865
- PREG_BAD_UTF8_ERROR => 'PREG_BAD_UTF8_ERROR',
866
- defined('PREG_BAD_UTF8_OFFSET_ERROR') ? PREG_BAD_UTF8_OFFSET_ERROR : 'PREG_BAD_UTF8_OFFSET_ERROR' => 'PREG_BAD_UTF8_OFFSET_ERROR',
867
- );
868
- $error = preg_last_error();
869
- if (isset($errors[$error])) $error = $errors[$error];
870
- if ($is_checking) $this->addMessage('error', $row, $property_name, $error.' ('.$formula.')');
871
- $this->debug(' eval <span class=osh-formula>'.self::esc($formula).'</span>');
872
- $this->debug(' doesn\'t match ('.self::esc($error).')');
873
- return null;
874
- }
875
- $formula = str_replace(
876
- array('min', 'max', 'range', 'array_match_any', 'array_match_all'),
877
- array('$this->_min', '$this->_max', '$this->_range', '$this->_array_match_any', '$this->_array_match_all'),
878
- $formula
879
- );
880
- $eval_result = null;
881
- //echo $formula.'<br/>';
882
- @eval('$eval_result = ('.$formula.');');
883
- $this->debug(' evaluate <span class=osh-formula>'.self::esc($formula).'</span> = <span class=osh-replacement>'.self::esc($this->_autoEscapeStrings($eval_result)).'</span>');
884
- return $eval_result;
885
- }
886
-
887
- protected function _parseInput($auto_correction)
888
- {
889
- $config_string = str_replace(
890
- array('&gt;', '&lt;', '“', '”', utf8_encode(chr(147)), utf8_encode(chr(148)), '&laquo;', '&raquo;', "\r\n", "\t"),
891
- array('>', '<', '"', '"', '"', '"', '"', '"', "\n", ' '),
892
- $this->_input
893
- );
894
-
895
- if (substr($config_string, 0, 2)=='$$') $config_string = $this->uncompress(substr($config_string, 2, strlen($config_string)));
896
-
897
- //echo ini_get('pcre.backtrack_limit');
898
- //exit;
899
-
900
- $this->debug('parse config (auto correction = '.self::esc(self::toString($auto_correction)).')');
901
- $config = null;
902
- $last_json_error = null;
903
- try {
904
- $config = self::json_decode($config_string);
905
- } catch (Exception $e) {
906
- $last_json_error = $e;
907
- }
908
- $auto_correction_warnings = array();
909
- $missing_enquote_of_property_name = array();
910
- if ($config) {
911
- foreach ($config as $code => $object) {
912
- if (!is_object($object)) {
913
- $config = null;
914
- break;
915
- }
916
- }
917
- }
918
- if ($auto_correction && !$config && $config_string!='[]') {
919
- if (preg_match_all('/((?:#+[^{\\n]*\\s+)+)\\s*{/s', $config_string, $result, PREG_SET_ORDER)) {
920
- $auto_correction_warnings[] = 'JSON: usage of incompatible comments';
921
- foreach ($result as $set) {
922
- $comment_lines = explode("\n", $set[1]);
923
- foreach ($comment_lines as $i => $line) {
924
- $comment_lines[$i] = preg_replace('/^#+\\s/', '', $line);
925
- }
926
- $comment = trim(implode("\n", $comment_lines));
927
- $config_string = str_replace($set[0], '{"about": "'.str_replace('"', '\\"', $comment).'",', $config_string);
928
- }
929
- }
930
- $property_regex = '\\s*(?<property_name>"?[a-z0-9_]+"?)\\s*:\\s*(?<property_value>"(?:(?:[^"]|\\\\")*[^\\\\])?"|'.self::FLOAT_REGEX.'|false|true|null)\\s*(?<property_separator>,)?\\s*(?:\\n)?';
931
- $object_regex = '(?:(?<object_name>"?[a-z0-9_]+"?)\\s*:\\s*)?{\\s*('.$property_regex.')+\\s*}\\s*(?<object_separator>,)?\\s*';
932
- preg_match_all('/('.$object_regex.')/is', $config_string, $object_set, PREG_SET_ORDER);
933
- //print_r($object_set);
934
- $json = array();
935
- $objects_count = count($object_set);
936
- $to_ignore_counter = -1;
937
- foreach ($object_set as $i => $object) {
938
- $pos = strpos($config_string, $object[0]);
939
- $to_ignore = trim(substr($config_string, 0, $pos));
940
- if ($to_ignore) {
941
- $to_ignore_counter++;
942
- if ($to_ignore_counter==0) {
943
- $bracket_pos = strpos($to_ignore, '{');
944
- if ($bracket_pos!==false) {
945
- $to_ignore = explode('{', $to_ignore, 2);
946
- }
947
- }
948
- $to_ignore = (array)$to_ignore;
949
- foreach ($to_ignore as $to_ignore_i) {
950
- $to_ignore_i = trim($to_ignore_i);
951
- if (!$to_ignore_i) continue;
952
- $auto_correction_warnings[] = 'JSON: ignored lines (<span class=osh-formula>'.self::toString($to_ignore_i).'</span>)';
953
- $n = 0;
954
- do {
955
- $key = 'meta'.$n;
956
- $n++;
957
- } while(isset($json[$key]));
958
- $json[$key] = array(
959
- 'type' => 'meta',
960
- 'ignored' => $to_ignore_i,
961
- );
962
- }
963
- $config_string = substr($config_string, $pos, strlen($config_string));
964
- }
965
- $config_string = str_replace($object[0], '', $config_string);
966
- $object_name = isset($object['object_name']) ? $object['object_name'] : null;
967
- $object_separator = isset($object['object_separator']) ? $object['object_separator'] : null;
968
- $is_last_object = ($i==$objects_count-1);
969
- if (!$is_last_object && $object_separator!=',') {
970
- $auto_correction_warnings[] = 'JSON: missing object separator (comma)';
971
- } else if ($is_last_object && $object_separator==',') {
972
- $auto_correction_warnings[] = 'JSON: no trailing object separator (comma) allowed';
973
- }
974
- $json_object = array();
975
- preg_match_all('/'.$property_regex.'/i', $object[0], $property_set, PREG_SET_ORDER);
976
- $properties_count = count($property_set);
977
- foreach ($property_set as $j => $property) {
978
- $name = $property['property_name'];
979
- if ($name{0}!='"' || $name{strlen($name)-1}!='"') {
980
- $auto_correction_warnings['missing_enquote_of_property_name'] = 'JSON: missing enquote of property name: %s';
981
- $missing_enquote_of_property_name[] = self::toString(trim($name, '"'));
982
- }
983
- $property_separator = isset($property['property_separator']) ? $property['property_separator'] : null;
984
- $is_last_property = ($j==$properties_count-1);
985
- if (!$is_last_property && $property_separator!=',') {
986
- $auto_correction_warnings[] = 'JSON: missing property separator (comma)';
987
- } else if ($is_last_property && $property_separator==',') {
988
- $auto_correction_warnings[] = 'JSON: no trailing property separator (comma) allowed';
989
- }
990
- $json_object[trim($name, '"')] = $this->parseProperty($property['property_value']);
991
- }
992
- if ($object_name) $json[trim($object_name, '"')] = $json_object;
993
- else if (isset($json_object['code'])) {
994
- $code = $json_object['code'];
995
- unset($json_object['code']);
996
- $json[$code] = $json_object;
997
- } else $json[] = $json_object;
998
- }
999
- $to_ignore = trim($config_string);
1000
- if ($to_ignore) {
1001
- $bracket_pos = strpos($to_ignore, '}');
1002
- if ($bracket_pos!==false) {
1003
- $to_ignore = explode('}', $to_ignore, 2);
1004
- }
1005
- $to_ignore = (array)$to_ignore;
1006
- foreach ($to_ignore as $to_ignore_i) {
1007
- $to_ignore_i = trim($to_ignore_i);
1008
- if (!$to_ignore_i) continue;
1009
- $auto_correction_warnings[] = 'JSON: ignored lines (<span class=osh-formula>'.self::toString($to_ignore_i).'</span>)';
1010
- $n = 0;
1011
- do {
1012
- $key = 'meta'.$n;
1013
- $n++;
1014
- } while(isset($json[$key]));
1015
- $json[$key] = array(
1016
- 'type' => 'meta',
1017
- 'ignored' => $to_ignore_i,
1018
- );
1019
- }
1020
- }
1021
- $config_string = $this->jsonEncode($json);//'['.$config_string2.']';
1022
- $config_string = str_replace(array("\n"), array("\\n"), $config_string);
1023
- //echo $config_string;
1024
-
1025
- $last_json_error = null;
1026
- try {
1027
- $config = self::json_decode($config_string);
1028
- } catch (Exception $e) {
1029
- $last_json_error = $e;
1030
- }
1031
- }
1032
- if ($last_json_error) {
1033
- $auto_correction_warnings[] = 'JSON: unable to parse config ('.$last_json_error->getMessage().')';
1034
- }
1035
-
1036
- $row = null;
1037
- $auto_correction_warnings = array_unique($auto_correction_warnings);
1038
- foreach ($auto_correction_warnings as $key => $warning) {
1039
- if ($key=='missing_enquote_of_property_name') {
1040
- $missing_enquote_of_property_name = array_unique($missing_enquote_of_property_name);
1041
- $warning = str_replace('%s', '<span class=osh-key>'.self::esc(implode('</span>, <span class=osh-key>', $missing_enquote_of_property_name)).'</span>', $warning);
1042
- }
1043
- $this->addMessage('warning', $row, null, $warning);
1044
- }
1045
- $config = (array)$config;
1046
-
1047
- $this->_config = array();
1048
- $available_keys = array('type', 'about', 'label', 'enabled', 'description', 'fees', 'conditions', 'shipto', 'billto', 'origin', 'customer_groups', 'tracking_url');
1049
- $reserved_keys = array('*id');
1050
- if ($auto_correction) {
1051
- $available_keys = array_merge($available_keys, array(
1052
- 'destination', 'code',
1053
- ));
1054
- }
1055
-
1056
- $deprecated_properties = array();
1057
- $unknown_properties = array();
1058
-
1059
- foreach ($config as $code => $object) {
1060
- $object = (array)$object;
1061
- if ($auto_correction) {
1062
- if (isset($object['destination'])) {
1063
- if (!in_array('destination', $deprecated_properties)) $deprecated_properties[] = 'destination';
1064
- $object['shipto'] = $object['destination'];
1065
- unset($object['destination']);
1066
- }
1067
- if (isset($object['code'])) {
1068
- if (!in_array('code', $deprecated_properties)) $deprecated_properties[] = 'code';
1069
- $code = $object['code'];
1070
- unset($object['code']);
1071
- }
1072
- }
1073
-
1074
- $row = array();
1075
- $i = 1;
1076
- foreach ($object as $property_name => $property_value) {
1077
- if (in_array($property_name, $reserved_keys)) {
1078
- continue;
1079
- }
1080
- if (in_array($property_name, $available_keys)
1081
- || substr($property_name, 0, 1)=='_'
1082
- || in_array($object['type'], array('data', 'meta'))) {
1083
- if (isset($property_value)) {
1084
- $row[$property_name] = array('value' => $property_value, 'original_value' => $property_value);
1085
- if ($auto_correction) $this->cleanProperty($row, $property_name);
1086
- }
1087
- } else {
1088
- if (!in_array($property_name, $unknown_properties)) $unknown_properties[] = $property_name;
1089
- }
1090
- $i++;
1091
- }
1092
- $this->addRow($code, $row);
1093
- }
1094
- $row = null;
1095
- 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>');
1096
- 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>');
1097
- }
1098
-
1099
- public function addRow($code, &$row)
1100
- {
1101
- if ($code) {
1102
- if (isset($this->_config[$code])) $this->addMessage('error', $row, 'code', 'The id must be unique, `%s` has been found twice', $code);
1103
- while (isset($this->_config[$code])) $code .= rand(0, 9);
1104
- }
1105
- $row['*id'] = $code;
1106
- $this->_config[$code] = $row;
1107
- }
1108
-
1109
- public function addMessage($type, &$row, $property)
1110
- {
1111
- $args = func_get_args();
1112
- array_shift($args);
1113
- array_shift($args);
1114
- array_shift($args);
1115
- $message = new OS_Message($type, $args);
1116
- if (isset($row)) {
1117
- if (isset($property)) {
1118
- $row[$property]['messages'][] = $message;
1119
- } else {
1120
- $row['*messages'][] = $message;
1121
- }
1122
- }
1123
- $this->_messages[] = $message;
1124
- $this->debug(' => <span class=osh-'.$message->type.'>'.self::esc((string)$message).'</span>');
1125
- }
1126
-
1127
- protected function _replaceVariable(&$process, $input, $original, $replacement)
1128
- {
1129
- if (mb_strpos($input, '{'.$original.'}')!==false) {
1130
- $input = $this->replace('{'.$original.'}', $this->_autoEscapeStrings($replacement), $input);
1131
- }
1132
- if (mb_strpos($input, $original)!==false) {
1133
- if (!isset($process['options']->auto_escaping) || $process['options']->auto_escaping) {
1134
- $input = $this->replace($original, $this->_autoEscapeStrings($replacement), $input);
1135
- } else {
1136
- $input = $this->replace($original, $replacement, $input);
1137
- }
1138
- }
1139
- return $input;
1140
- }
1141
-
1142
- protected function _replaceData(&$process, $input, $keys = '', $aliases = array())
1143
- {
1144
- $keys = ($keys ? $keys.'|' : '').implode('|', array_keys($process['data']));
1145
- $keys = preg_replace('/[^a-z_\|]/', '_', $keys);
1146
- // data
1147
- while ($this->_preg_match("#{({$keys})\.([a-z0-9_\+\-\.]+)}#i", $input, $result)) {
1148
- $original = $result[0];
1149
- $object_name = isset($aliases[$result[1]]) ? $aliases[$result[1]] : $result[1];
1150
- $replacement = $this->_loadValue($process, $object_name, $result[2]);
1151
- $input = $this->_replaceVariable($process, $input, $original, $replacement);
1152
- }
1153
- return $input;
1154
- }
1155
-
1156
- protected function _addressMatch(&$process, &$row, $property_name, $address_filter, $address)
1157
- {
1158
- //$address_filter = '(* - ( europe (FR-(25,26),DE(40,42) ))';
1159
- //echo '<pre>';
1160
- $address_filter = $this->_replaceData($process, $address_filter);
1161
- $parser = new OS2_AddressFilterParser();
1162
- $address_filter = $parser->parse($address_filter);
1163
-
1164
- $this->debug(' address filter = <span class=osh-formula>'.self::esc($address_filter).'</span>');
1165
- $data = array(
1166
- '{c}' => $address->country_id,
1167
- '{p}' => $address->postcode,
1168
- '{r}' => $address->region_code,
1169
- );
1170
- foreach ($data as $original => $replacement) {
1171
- $address_filter = $this->_replaceVariable($process, $address_filter, $original, $replacement);
1172
- }
1173
- return (bool)$this->_evalFormula($address_filter, $row, $property_name, $is_checking=false);
1174
- }
1175
-
1176
- protected function _getItemProperty($item, $property_name)
1177
- {
1178
- $elems = explode('.', $property_name, $limit=2);
1179
- switch ($elems[0]) {
1180
- case 'p':
1181
- case 'product': return $item->getProduct()->{$elems[1]};
1182
- case 'item': return $item->{$elems[1]};
1183
- }
1184
- return null;
1185
- }
1186
-
1187
- protected function _autoEscapeStrings($input)
1188
- {
1189
- if (is_array($input)) {
1190
- $items = array();
1191
- foreach ($input as $v) {
1192
- $items[] = isset($v) && (is_string($v) || empty($v)) ? self::escapeString($v) : self::toString($v);
1193
- }
1194
- return 'array('.join(',', $items).')';
1195
- } else {
1196
- return isset($input) && (is_string($input)/* || empty($input)*/) ? self::escapeString($input) : self::toString($input);
1197
- }
1198
- }
1199
-
1200
- protected function _processProduct($items, $regex_result, &$row, $property_name, $is_checking)
1201
- {
1202
- // count, sum, min, max, count distinct
1203
- $operation = strtolower($regex_result[1]);
1204
- $return_value = null;
1205
- $reference = 'items';
1206
- switch ($operation) {
1207
- case 'sum':
1208
- case 'min':
1209
- case 'max':
1210
- case 'count distinct':
1211
- $reference = $regex_result[2];
1212
- $conditions = isset($regex_result[3]) ? $regex_result[3] : null;
1213
- break;
1214
- case 'count':
1215
- $conditions = isset($regex_result[2]) ? $regex_result[2] : null;
1216
- break;
1217
- }
1218
- switch ($operation) {
1219
- case 'sum':
1220
- case 'count distinct':
1221
- case 'count':
1222
- $return_value = 0;
1223
- break;
1224
- }
1225
-
1226
- $this->debug(' <span class=osh-loop>start <span class=osh-replacement>'.self::esc($operation).'</span> '
1227
- .'<span class=osh-key>'.self::esc($reference).'</span>'
1228
- .(isset($conditions) ? ' where <span class=osh-replacement>'.self::esc($conditions).'</span></span>' : '')
1229
- );
1230
- $this->addDebugIndent();
1231
-
1232
- $properties = array();
1233
- $this->_preg_match_all('#(?:item|product|p)\.([a-z0-9_\+\-\.]+)#i', $conditions, $properties_regex_result);
1234
- foreach ($properties_regex_result as $property_regex_result) {
1235
- if (!isset($properties[$property_regex_result[0]])) $properties[$property_regex_result[0]] = $property_regex_result;
1236
- }
1237
- krsort($properties); // To avoid shorter replace
1238
-
1239
- if ($items) {
1240
- foreach ($items as $item) {
1241
- $this->debug(' <span class=osh-loop>&bull; item</span> = <span class=osh-formula>'.self::esc((string)$item).'</span>');
1242
- $this->addDebugIndent();
1243
- if (isset($conditions) && $conditions!='') {
1244
- $formula = $conditions;
1245
- foreach ($properties as $property) {
1246
- $value = $this->_getItemProperty($item, $property[0]);
1247
- $from = $property[0];
1248
- $to = $this->_autoEscapeStrings($value);
1249
- $this->debug(' replace <span class=osh-replacement>'.self::esc($from).'</span> by <span class=osh-replacement>'.self::esc($to).'</span> =&gt; <span class=osh-formula>'.self::esc(str_replace($from, '<span class=osh-replacement>'.$to.'</span>', $formula)).'</span>');
1250
- $formula = str_replace($from, $to, $formula);
1251
- }
1252
- $eval_result = $this->_evalFormula($formula, $row, $property_name, $is_checking);
1253
- if (!isset($eval_result)) $return_value = 'null';
1254
- }
1255
- else $eval_result = true;
1256
-
1257
- if ($eval_result==true) {
1258
- if ($operation=='count') {
1259
- $return_value = (isset($return_value) ? $return_value : 0) + $item->qty;
1260
- } else {
1261
- $value = $this->_getItemProperty($item, $reference);
1262
- $this->debug(' &raquo; <span class=osh-key>'.self::esc($reference).'</span> = <span class=osh-formula>'.self::esc($value).'</span>'
1263
- .($operation=='sum' ? ' x <span class=osh-formula>'.$item->qty.'</span>' : ''));
1264
- switch ($operation) {
1265
- case 'min': if (!isset($return_value) || $value<$return_value) $return_value = $value; break;
1266
- case 'max': if (!isset($return_value) || $value>$return_value) $return_value = $value; break;
1267
- case 'sum':
1268
- //$this->debug(self::esc($item->getProduct()->sku).'.'.self::esc($reference).' = "'.self::esc($value).'" x '.self::esc($item->qty));
1269
- $return_value = (isset($return_value) ? $return_value : 0) + $value*$item->qty;
1270
- break;
1271
- case 'count distinct':
1272
- if (!isset($return_value)) $return_value = 0;
1273
- if (!isset($distinct_values)) $distinct_values = array();
1274
- if (!in_array($value, $distinct_values)) {
1275
- $distinct_values[] = $value;
1276
- $return_value++;
1277
- }
1278
- break;
1279
- }
1280
- }
1281
- }
1282
- $this->debug(' &raquo; <span class=osh-info>'.self::esc($operation).' result</span> = <span class=osh-formula>'.self::esc($return_value).'</span>');
1283
- $this->removeDebugIndent();
1284
- }
1285
- }
1286
-
1287
- $this->removeDebugIndent();
1288
- $this->debug(' <span class=osh-loop>end</span>');
1289
-
1290
- return $return_value;
1291
- }
1292
-
1293
- /* For auto correction */
1294
- public function cleanProperty(&$row, $key)
1295
- {
1296
- $input = $row[$key]['value'];
1297
- if (is_string($input)) {
1298
- while (preg_match('/{{customVar code=([a-zA-Z0-9_-]+)}}/', $input, $resi)) {
1299
- $input = $this->replace($resi[0], '{customvar.'.$resi[1].'}', $input, 'warning', 'replace deprecated');
1300
- }
1301
-
1302
- $regex = "{(weight|products_quantity|price_including_tax|price_excluding_tax|country)}";
1303
- if (preg_match('/'.$regex.'/', $input, $resi)) {
1304
- $this->addMessage('warning', $row, $key, 'Usage of deprecated syntax %s', '<span class=osh-formula>'.$resi[0].'</span>');
1305
- while (preg_match('/'.$regex.'/', $input, $resi)) {
1306
- switch ($resi[1]) {
1307
- case 'price_including_tax': $to = "{cart.price+tax+discount}"; break;
1308
- case 'price_excluding_tax': $to = "{cart.price-tax+discount}"; break;
1309
- case 'weight': $to = "{cart.{$resi[1]}}"; break;
1310
- case 'products_quantity': $to = "{cart.qty}"; break;
1311
- case 'country': $to = "{shipto.country_name}"; break;
1312
- }
1313
- $input = str_replace($resi[0], $to, $input);
1314
- }
1315
- }
1316
-
1317
- $regex1 = "{copy '([a-zA-Z0-9_]+)'\.'([a-zA-Z0-9_]+)'}";
1318
- if (preg_match('/'.$regex1.'/', $input, $resi)) {
1319
- $this->addMessage('warning', $row, $key, 'Usage of deprecated syntax %s', '<span class=osh-formula>'.$resi[0].'</span>');
1320
- while (preg_match('/'.$regex1.'/', $input, $resi)) $input = str_replace($resi[0], '{'.$resi[1].'.'.$resi[2].'}', $input);
1321
- }
1322
-
1323
- $regex1 = "{(count|all|any) (attribute|option) '([^'\)]+)' ?((?:==|<=|>=|<|>|!=) ?(?:".self::FLOAT_REGEX."|true|false|'[^'\)]*'))}";
1324
- $regex2 = "{(sum) (attribute|option) '([^'\)]+)'}";
1325
- if (preg_match('/'.$regex1.'/', $input, $resi) || preg_match('/'.$regex2.'/', $input, $resi)) {
1326
- $this->addMessage('warning', $row, $key, 'Usage of deprecated syntax %s', '<span class=osh-formula>'.$resi[0].'</span>');
1327
- while (preg_match('/'.$regex1.'/', $input, $resi) || preg_match('/'.$regex2.'/', $input, $resi)) {
1328
- switch ($resi[1]) {
1329
- case 'count': $to = "{count items where product.{$resi[2]}.{$resi[3]}{$resi[4]}}"; break;
1330
- case 'all': $to = "{count items where product.{$resi[2]}.{$resi[3]}{$resi[4]}}=={cart.qty}"; break;
1331
- case 'any': $to = "{count items where product.{$resi[2]}.{$resi[3]}{$resi[4]}}>0"; break;
1332
- case 'sum': $to = "{sum product.{$resi[2]}.{$resi[3]}}"; break;
1333
- }
1334
- $input = str_replace($resi[0], $to, $input);
1335
- }
1336
- }
1337
-
1338
- $regex = "((?:{| )product.(?:attribute|option))s.";
1339
- if (preg_match('/'.$regex.'/', $input, $resi)) {
1340
- $this->addMessage('warning', $row, $key, 'Usage of deprecated syntax %s', '<span class=osh-formula>'.$resi[0].'</span>');
1341
- while (preg_match('/'.$regex.'/', $input, $resi)) {
1342
- $input = str_replace($resi[0], $resi[1].'.', $input);
1343
- }
1344
- }
1345
-
1346
- $regex = "{table '([^']+)' (".self::COUPLE_REGEX."(?:, *".self::COUPLE_REGEX.")*)}";
1347
- if (preg_match('/'.$regex.'/', $input, $resi)) {
1348
- $this->addMessage('warning', $row, $key, 'Usage of deprecated syntax %s', '<span class=osh-formula>'.$resi[0].'</span>');
1349
- while (preg_match('/'.$regex.'/', $input, $resi)) {
1350
- switch ($resi[1]) {
1351
- case 'products_quantity':
1352
- $input = str_replace($resi[0], "{table {cart.weight} in {$resi[2]}}*{cart.qty}", $input);
1353
- break;
1354
- default:
1355
- $input = str_replace($resi[0], "{table {cart.{$resi[1]}} in {$resi[2]}}", $input);
1356
- break;
1357
- }
1358
- }
1359
- }
1360
-
1361
- $aliases = array(
1362
- '{destination.country.code}' => '{shipto.country_id}',
1363
- '{destination.country.name}' => '{shipto.country_name}',
1364
- '{destination.region.code}' => '{shipto.region_code}',
1365
- '{destination.postcode}' => '{shipto.postcode}',
1366
- '.destination}' => '.shipto}',
1367
- '{cart.price_excluding_tax}' => '{cart.price-tax+discount}',
1368
- '{cart.price_including_tax}' => '{cart.price+tax+discount}',
1369
- '{cart.weight.unit}' => '{cart.weight_unit}',
1370
- '{cart.coupon}' => '{cart.coupon_code}',
1371
- '{cart.weight.for-charge}' => '{cart.weight_for_charge}',
1372
- '{c.price_excluding_tax}' => '{c.price-tax+discount}',
1373
- '{c.price_including_tax}' => '{c.price+tax+discount}',
1374
- '{c.weight.unit}' => '{c.weight_unit}',
1375
- '{c.coupon}' => '{c.coupon_code}',
1376
- '{free_shipping}' => '{cart.free_shipping}',
1377
- '{c.weight.for-charge}' => '{c.weight_for_charge}',
1378
- '{customer.group.id}' => '{customer_group.id}',
1379
- '{customer.group.code}' => '{customer_group.code}',
1380
- '{origin.country.code}' => '{origin.country_id}',
1381
- '{origin.country.name}' => '{origin.country_name}',
1382
- '{origin.region.code}' => '{origin.region_id}',
1383
- '{selection.quantity}' => '{selection.qty}',
1384
- 'product.quantity' => 'item.qty',
1385
- 'product.stock.quantity' => 'product.stock.qty',
1386
- 'product.options.' => 'item.option.',
1387
- 'product.option.' => 'item.option.',
1388
- 'product.o.' => 'item.o.',
1389
- 'p.quantity' => 'item.qty',
1390
- 'p.stock.quantity' => 'p.stock.qty',
1391
- 'p.options.' => 'item.option.',
1392
- 'p.option.' => 'item.option.',
1393
- 'p.o.' => 'item.o.',
1394
- 'count products ' => 'count items ',
1395
- 'product.attribute.price+tax+discount' => 'item.price+tax+discount',
1396
- 'product.attribute.price+tax-discount' => 'item.price+tax-discount',
1397
- 'product.attribute.price-tax+discount' => 'item.price-tax+discount',
1398
- 'product.attribute.price-tax-discount' => 'item.price-tax-discount',
1399
- );
1400
- foreach ($aliases as $from => $to) {
1401
- if (mb_strpos($input, $from)!==false) {
1402
- $input = $this->replace($from, $to, $input, 'warning', 'replace deprecated');
1403
- }
1404
- }
1405
- }
1406
- $row[$key]['value'] = $input;
1407
- }
1408
 
1409
  }
1410
 
1411
  class OS2_Data
1412
  {
1413
- protected $_data;
1414
-
1415
- public function __construct($data=null)
1416
- {
1417
- $this->_data = (array)$data;
1418
- }
1419
-
1420
- public function __sleep()
1421
- {
1422
- return array_keys($this->_data);
1423
- }
1424
-
1425
- public function __get($name)
1426
- {
1427
- return isset($this->_data[$name]) ? $this->_data[$name] : null;
1428
- }
1429
-
1430
- public function set($name, $value)
1431
- {
1432
- $this->_data[$name] = $value;
1433
- }
1434
  }
1435
 
1436
  class OS_Message
1437
  {
1438
- public $type;
1439
- public $message;
1440
- public $args;
1441
-
1442
- public function __construct($type, $args)
1443
- {
1444
- $this->type = $type;
1445
- $this->message = array_shift($args);
1446
- $this->args = $args;
1447
- }
1448
-
1449
- public function __toString()
1450
- {
1451
- return vsprintf($this->message, $this->args);
1452
- }
1453
  }
1454
 
1455
  class OS_Result
1456
  {
1457
- public $success;
1458
- public $result;
1459
-
1460
- public function __construct($success, $result=null)
1461
- {
1462
- $this->success = $success;
1463
- $this->result = $result;
1464
- }
1465
-
1466
- public function __toString()
1467
- {
1468
- return OwebiaShippingHelper::toString($this->result);
1469
- }
1470
  }
1471
 
24
 
25
  class OwebiaShippingHelper
26
  {
27
+ const FLOAT_REGEX = '[-]?\d+(?:[.]\d+)?';
28
+ const COUPLE_REGEX = '(?:[0-9.]+|\*) *(?:\[|\])? *\: *[0-9.]+';
29
+
30
+ public static $DEBUG_INDEX_COUNTER = 0;
31
+ public static $UNCOMPRESSED_STRINGS = array(
32
+ ' product.attribute.',
33
+ ' item.option.',
34
+ '{product.attribute.',
35
+ '{item.option.',
36
+ '{product.',
37
+ '{cart.',
38
+ '{selection.',
39
+ );
40
+ public static $COMPRESSED_STRINGS = array(
41
+ ' p.a.',
42
+ ' item.o.',
43
+ '{p.a.',
44
+ '{item.o.',
45
+ '{p.',
46
+ '{c.',
47
+ '{s.',
48
+ );
49
+
50
+ public static function esc($input)
51
+ {
52
+ $input = htmlspecialchars($input, ENT_NOQUOTES, 'UTF-8');
53
+ return preg_replace('/&lt;(\/?)span([^&]*)&gt;/', '<\1span\2>', $input);
54
+ }
55
+
56
+ public static function toString($value)
57
+ {
58
+ if (!isset($value)) return 'null';
59
+ else if (is_bool($value)) return $value ? 'true' : 'false';
60
+ else if (is_float($value)) return str_replace(',', '.', (string)$value); // To avoid locale problems
61
+ else if (is_array($value)) return 'array(size:'.count($value).')';
62
+ else if (is_object($value)) return get_class($value).'';
63
+ else return $value;
64
+ }
65
+
66
+ public static function parseSize($size)
67
+ {
68
+ $size = trim($size);
69
+ $last = strtolower($size[strlen($size)-1]);
70
+ switch ($last) {
71
+ case 'g': $size *= 1024;
72
+ case 'm': $size *= 1024;
73
+ case 'k': $size *= 1024;
74
+ }
75
+ return (float)$size;
76
+ }
77
+
78
+ public static function formatSize($size)
79
+ {
80
+ $unit = array('B', 'KB', 'MB', 'GB', 'TB', 'PB');
81
+ return self::toString(@round($size/pow(1024, ($i=floor(log($size, 1024)))), 2)).' '.$unit[$i];
82
+ }
83
+
84
+ public static function getInfos()
85
+ {
86
+ $properties = array(
87
+ 'server_os' => PHP_OS,
88
+ 'server_software' => $_SERVER['SERVER_SOFTWARE'],
89
+ 'php_version' => PHP_VERSION,
90
+ 'memory_limit' => self::formatSize(self::parseSize(ini_get('memory_limit'))),
91
+ 'memory_usage' => self::formatSize(memory_get_usage(true)),
92
+ );
93
+ return $properties;
94
+ }
95
+
96
+ public static function getDefaultProcessData()
97
+ {
98
+ return array(
99
+ 'info' => new OS2_Data(self::getInfos()),
100
+ 'cart' => new OS2_Data(),
101
+ 'quote' => new OS2_Data(),
102
+ 'selection' => new OS2_Data(),
103
+ 'customer' => new OS2_Data(),
104
+ 'customer_group' => new OS2_Data(),
105
+ 'customvar' => new OS2_Data(),
106
+ 'date' => new OS2_Data(),
107
+ 'origin' => new OS2_Data(),
108
+ 'shipto' => new OS2_Data(),
109
+ 'billto' => new OS2_Data(),
110
+ 'store' => new OS2_Data(),
111
+ 'request' => new OS2_Data(),
112
+ 'address_filter' => new OS2_Data(),
113
+ );
114
+ }
115
+
116
+ public static function jsonEncode($data, $beautify = false, $html = false, $level = 0, $current_indent = '')
117
+ {
118
+ //$html = true;
119
+ $indent = "\t";//$html ? '&nbsp;&nbsp;&nbsp;&nbsp;' : "\t";//
120
+ $line_break = $html ? '<br/>' : "\n";
121
+ $new_indent = $current_indent.$indent;
122
+ switch ($type = gettype($data)) {
123
+ case 'NULL':
124
+ return ($html ? '<span class=json-reserved>' : '').'null'.($html ? '</span>' : '');
125
+ case 'boolean':
126
+ return ($html ? '<span class=json-reserved>' : '').($data ? 'true' : 'false').($html ? '</span>' : '');
127
+ case 'integer':
128
+ case 'double':
129
+ case 'float':
130
+ return ($html ? '<span class=json-numeric>' : '').$data.($html ? '</span>' : '');
131
+ case 'string':
132
+ return ($html ? '<span class=json-string>' : '').'"'.str_replace(array("\\", '"', "\n", "\r"), array("\\\\", '\"', "\\n", "\\r"), $html ? htmlspecialchars($data, ENT_COMPAT, 'UTF-8') : $data).'"'.($html ? '</span>' : '');
133
+ case 'object':
134
+ $data = (array)$data;
135
+ case 'array':
136
+ $output_index_count = 0;
137
+ $output = array();
138
+ foreach ($data as $key => $value) {
139
+ if ($output_index_count!==null && $output_index_count++!==$key) {
140
+ $output_index_count = null;
141
+ }
142
+ }
143
+ $is_associative = $output_index_count===null;
144
+ foreach ($data as $key => $value) {
145
+ if ($is_associative) {
146
+ $classes = array();
147
+ if ($key=='about') $classes[] = 'json-about';
148
+ if ($key=='conditions' || $key=='fees') $classes[] = 'json-formula';
149
+ $property_classes = array('json-property');
150
+ if ($level==0) $property_classes[] = 'json-id';
151
+ $output[] = ($html && $classes ? '<span class="'.implode(' ', $classes).'">' : '')
152
+ .($html ? '<span class="'.implode(' ', $property_classes).'">' : '')
153
+ .self::jsonEncode((string)$key)
154
+ .($html ? '</span>' : '').':'
155
+ .($beautify ? ' ' : '')
156
+ .self::jsonEncode($value, $beautify, $html, $level+1, $new_indent)
157
+ .($html && $classes ? '</span>' : '');
158
+ } else {
159
+ $output[] = self::jsonEncode($value, $beautify, $html, $level+1, $current_indent);
160
+ }
161
+ }
162
+ if ($is_associative) {
163
+ $classes = array();
164
+ if (isset($data['type']) && $data['type']=='meta') $classes[] = 'json-meta';
165
+ $output = ($html && $classes ? '<span class="'.implode(' ', $classes).'">' : '')
166
+ .'{'
167
+ .($beautify ? "{$line_break}{$new_indent}" : '')
168
+ .implode(','.($beautify ? "{$line_break}{$new_indent}" : ''), $output)
169
+ .($beautify ? "{$line_break}{$current_indent}" : '')
170
+ .'}'
171
+ .($html && $classes ? '</span>' : '');
172
+ //echo $output;
173
+ return $output;
174
+ } else {
175
+ return '['.implode(','.($beautify ? ' ' : ''), $output).']';
176
+ }
177
+ default:
178
+ return ''; // Not supported
179
+ }
180
+ }
181
+
182
+ protected static function json_decode($input)
183
+ {
184
+ if (function_exists('json_decode')) { // PHP >= 5.2.0
185
+ $output = json_decode($input);
186
+ if (function_exists('json_last_error')) { // PHP >= 5.3.0
187
+ $error = json_last_error();
188
+ if ($error!=JSON_ERROR_NONE) throw new Exception($error);
189
+ }
190
+ return $output;
191
+ } else {
192
+ return Zend_Json::decode($input);
193
+ }
194
+ }
195
+
196
+ protected static function json_encode($input)
197
+ {
198
+ if (function_exists('json_encode')) {
199
+ return json_encode($input);
200
+ } else {
201
+ return Zend_Json::encode($input);
202
+ }
203
+ }
204
+
205
+ public static function escapeString($input)
206
+ {
207
+ $escaped = self::json_encode($input);
208
+ $escaped = preg_replace_callback('/\\\\u([0-9a-fA-F]{4})/', function ($match) {
209
+ return mb_convert_encoding(pack('H*', $match[1]), 'UTF-8', 'UCS-2BE');
210
+ }, $escaped);
211
+ return $escaped;
212
+ }
213
+
214
+ protected $_input;
215
+ protected $_config = array();
216
+ protected $_messages = array();
217
+ protected $_formula_cache = array();
218
+ protected $_expression_cache = array();
219
+ public $debug_code = null;
220
+ public $debug_output = '';
221
+ public $debug_header = null;
222
+ protected $debug_prefix = '';
223
+
224
+ public function __construct($input, $auto_correction)
225
+ {
226
+ $this->_input = $input;
227
+ $this->_parseInput($auto_correction);
228
+ }
229
+
230
+ public function addDebugIndent()
231
+ {
232
+ $this->debug_prefix .= ' ';
233
+ }
234
+
235
+ public function removeDebugIndent()
236
+ {
237
+ $this->debug_prefix = substr($this->debug_prefix, 0, strlen($this->debug_prefix)-3);
238
+ }
239
+
240
+ public function debug($text)
241
+ {
242
+ $this->debug_output .= "<p>{$this->debug_prefix}{$text}</p>";
243
+ }
244
+
245
+ public function getDebug()
246
+ {
247
+ $index = $this->debug_code.'-'.self::$DEBUG_INDEX_COUNTER++;
248
+ $output = "<style rel=stylesheet type=\"text/css\">"
249
+ .".osh-debug{background:#000;color:#bbb;-webkit-opacity:0.9;-moz-opacity:0.9;opacity:0.9;text-align:left;white-space:pre-wrap;overflow:auto;}"
250
+ .".osh-debug p{margin:2px 0;}"
251
+ .".osh-formula{color:#f90;} .osh-key{color:#0099f7;} .osh-loop{color:#ff0;}"
252
+ .".osh-error{color:#f00;} .osh-warning{color:#ff0;} .osh-info{color:#7bf700;}"
253
+ .".osh-debug-content{padding:10px;font-family:monospace}"
254
+ .".osh-replacement{color:#ff3000;}"
255
+ ."</style>"
256
+ ."<div id=osh-debug-{$index} class=osh-debug><div class=osh-debug-content><span class=osh-close style=\"float:right;cursor:pointer;\" onclick=\"document.getElementById('osh-debug-{$index}').style.display = 'none';\">[<span style=\"padding:0 5px;color:#f00;\">X</span>]</span>"
257
+ ."<p>{$this->debug_header}</p>{$this->debug_output}</div></div>";
258
+ return $output;
259
+ }
260
+
261
+ public function initDebug($code, $process)
262
+ {
263
+ $header = 'DEBUG OwebiaShippingHelper.php<br/>';
264
+ foreach ($process as $index => $process_option) {
265
+ if (in_array($index, array('data', 'options'))) {
266
+ $header .= ' <span class=osh-key>'.self::esc(str_replace('.', '</span>.<span class=osh-key>', $index)).'</span> &gt;&gt;<br/>';
267
+ foreach ($process_option as $object_name => $data) {
268
+ if (is_object($data) || is_array($data)) {
269
+ $header .= ' <span class=osh-key>'.self::esc(str_replace('.', '</span>.<span class=osh-key>', $object_name)).'</span> &gt;&gt;<br/>';
270
+ $children = array();
271
+ if (is_object($data)) $children = $data->__sleep();
272
+ else if (is_array($data)) $children = array_keys($data);
273
+ foreach ($children as $name) {
274
+ $key = $name;
275
+ if ($key=='*') {
276
+ $header .= ' .<span class=osh-key>'.self::esc(str_replace('.', '</span>.<span class=osh-key>', $key)).'</span> = …<br/>';
277
+ } else {
278
+ if (is_object($data)) $value = $data->{$name};
279
+ else if (is_array($data)) $children = $data[$name];
280
+ $header .= ' .<span class=osh-key>'.self::esc(str_replace('.', '</span>.<span class=osh-key>', $key)).'</span> = <span class=osh-formula>'.self::esc(self::toString($value)).'</span> ('.gettype($value).')<br/>';
281
+ }
282
+ }
283
+ } else {
284
+ $header .= ' .<span class=osh-key>'.self::esc(str_replace('.', '</span>.<span class=osh-key>', $object_name)).'</span> = <span class=osh-formula>'.self::esc(self::toString($data)).'</span> ('.gettype($data).')<br/>';
285
+ }
286
+ }
287
+ } else {
288
+ $header .= ' <span class=osh-key>'.self::esc(str_replace('.', '</span>.<span class=osh-key>', $index)).'</span> = <span class=osh-formula>'.self::esc(self::toString($process_option)).'</span> ('.gettype($process_option).')<br/>';
289
+ }
290
+ }
291
+ $this->debug_code = $code;
292
+ $this->debug_header = $header;
293
+ }
294
+
295
+ public function getConfig()
296
+ {
297
+ return $this->_config;
298
+ }
299
+
300
+ public function getConfigRow($id)
301
+ {
302
+ return isset($this->_config[$id]) ? $this->_config[$id] : null;
303
+ }
304
+
305
+ public function setConfig($config)
306
+ {
307
+ return $this->_config = $config;
308
+ }
309
+
310
+ public function getMessages()
311
+ {
312
+ $messages = $this->_messages;
313
+ $this->_messages = array();
314
+ return $messages;
315
+ }
316
+
317
+ public function sortProperties($k1, $k2)
318
+ {
319
+ $i1 = isset($this->properties_sort[$k1]) ? $this->properties_sort[$k1] : 1000;
320
+ $i2 = isset($this->properties_sort[$k2]) ? $this->properties_sort[$k2] : 1000;
321
+ return $i1==$i2 ? strcmp($k1, $k2) : $i1-$i2;
322
+ }
323
+
324
+ public function formatConfig($compress, $keys_to_remove=array(), $html = false)
325
+ {
326
+ $object_array = array();
327
+ $this->properties_sort = array_flip(array(
328
+ 'type',
329
+ 'about',
330
+ 'enabled',
331
+ 'label',
332
+ 'description',
333
+ 'shipto',
334
+ 'billto',
335
+ 'origin',
336
+ 'conditions',
337
+ 'fees',
338
+ 'tracking_url',
339
+ ));
340
+ foreach ($this->_config as $code => $row) {
341
+ $object = array();
342
+ foreach ($row as $key => $property) {
343
+ if (substr($key, 0, 1)!='*' && !in_array($key, $keys_to_remove)) {
344
+ $object[$key] = $property['value'];
345
+ }
346
+ }
347
+ uksort($object, array($this, 'sortProperties'));
348
+ $object_array[$code] = $object;
349
+ }
350
+ $output = self::jsonEncode($object_array, $beautify = !$compress, $html);
351
+ return $compress ? $this->compress($output) : $this->uncompress($output);
352
+ }
353
+
354
+ public function checkConfig()
355
+ {
356
+ $timestamp = time();
357
+ $process = array(
358
+ 'config' => $this->_config,
359
+ 'data' => self::getDefaultProcessData(),
360
+ 'result' => null,
361
+ );
362
+ foreach ($this->_config as $code => &$row) {
363
+ $this->processRow($process, $row, $check_all_conditions=true);
364
+ foreach ($row as $property_name => $property_value) {
365
+ if (substr($property_name, 0, 1)!='*') {
366
+ $this->debug(' check '.$property_name);
367
+ $this->getRowProperty($row, $property_name);
368
+ }
369
+ }
370
+ }
371
+ }
372
+
373
+ public function processRow($process, &$row, $is_checking=false)
374
+ {
375
+ if (!isset($row['*id'])) {
376
+ $this->debug('skip row with unknown id');
377
+ return new OS_Result(false);
378
+ }
379
+ $this->debug('process row <span class=osh-key>'.self::esc($row['*id']).'</span>');
380
+
381
+ if (isset($row['about'])) { // Display on debug
382
+ $about = $this->getRowProperty($row, 'about');
383
+ }
384
+
385
+ $type = $this->getRowProperty($row, 'type');
386
+ if ($type=='data') {
387
+ foreach ($row as $key => $data) {
388
+ if (in_array($key, array('*id', 'code', 'type'))) continue;
389
+ $value = isset($data['value']) ? $data['value'] : $data;
390
+ $this->debug(' .<span class=osh-key>'.self::esc($key).'</span> = <span class=osh-formula>'.self::esc(self::toString($value)).'</span> ('.gettype($value).')');
391
+ }
392
+ return new OS_Result(false);
393
+ }
394
+ if (isset($type) && $type!='method') return new OS_Result(false);
395
+
396
+ if (!isset($row['label']['value'])) $row['label']['value'] = '***';
397
+
398
+ $enabled = $this->getRowProperty($row, 'enabled');
399
+ if (isset($enabled)) {
400
+ if (!$is_checking && !$enabled) {
401
+ $this->addMessage('info', $row, 'enabled', 'Configuration disabled');
402
+ return new OS_Result(false);
403
+ }
404
+ }
405
+
406
+ $conditions = $this->getRowProperty($row, 'conditions');
407
+ if (isset($conditions)) {
408
+ $result = $this->processFormula($process, $row, 'conditions', $conditions, $is_checking);
409
+ if (!$is_checking) {
410
+ if (!$result->success) return $result;
411
+ if (!$result->result) {
412
+ $this->addMessage('info', $row, 'conditions', "The cart doesn't match conditions");
413
+ return new OS_Result(false);
414
+ }
415
+ }
416
+ }
417
+
418
+ $address_properties = array(
419
+ 'shipto' => "Shipping zone not allowed",
420
+ 'billto' => "Billing zone not allowed",
421
+ 'origin' => "Shipping origin not allowed",
422
+ );
423
+ foreach ($address_properties as $property_name => $failure_message) {
424
+ $property_value = $this->getRowProperty($row, $property_name);
425
+ if (isset($property_value)) {
426
+ $match = $this->_addressMatch($process, $row, $property_name, $property_value, $process['data'][$property_name]);
427
+ if (!$is_checking && !$match) {
428
+ $this->addMessage('info', $row, $property_name, $failure_message);
429
+ return new OS_Result(false);
430
+ }
431
+ }
432
+ }
433
+
434
+ $customer_groups = $this->getRowProperty($row, 'customer_groups');
435
+ if (isset($customer_groups)) {
436
+ $groups = explode(',', $customer_groups);
437
+ $group_match = false;
438
+ $customer_group = $process['data']['customer_group'];
439
+ foreach ($groups as $group) {
440
+ $group = trim($group);
441
+ if ($group=='*' || $group==$customer_group->code || ctype_digit($group) && $group==$customer_group->id) {
442
+ $this->debug(' group <span class=osh-replacement>'.self::esc($customer_group->code).'</span> (id:<span class=osh-replacement>'.self::esc($customer_group->id).'</span>) matches');
443
+ $group_match = true;
444
+ break;
445
+ }
446
+ }
447
+ if (!$is_checking && !$group_match) {
448
+ $this->addMessage('info', $row, 'customer_groups', "Customer group not allowed (%s)", $customer_group->code);
449
+ return new OS_Result(false);
450
+ }
451
+ }
452
+
453
+ $fees = $this->getRowProperty($row, 'fees');
454
+ if (isset($fees)) {
455
+ $result = $this->processFormula($process, $row, 'fees', $fees, $is_checking);
456
+ if (!$result->success) return $result;
457
+ $this->debug(' &raquo; <span class=osh-info>result</span> = <span class=osh-formula>'.self::esc(self::toString($result->result)).'</span>');
458
+ return new OS_Result(true, (float)$result->result);
459
+ }
460
+ return new OS_Result(false);
461
+ }
462
+
463
+ public function getRowProperty(&$row, $key, $original_row=null, $original_key=null)
464
+ {
465
+ $property = null;
466
+ $output = null;
467
+ if (isset($original_row) && isset($original_key) && $original_row['*id']==$row['*id'] && $original_key==$key) {
468
+ $this->addMessage('error', $row, $key, 'Infinite loop %s', "<span class=\"code\">{{$row['*id']}.{$key}}</span>");
469
+ return array('error' => 'Infinite loop');
470
+ }
471
+ if (isset($row[$key]['value'])) {
472
+ $property = $row[$key]['value'];
473
+ $output = $property;
474
+ $this->debug(' get <span class=osh-key>'.self::esc($row['*id']).'</span>.<span class=osh-key>'.self::esc($key).'</span> = <span class=osh-formula>'.self::esc(self::toString($property)).'</span>');
475
+ preg_match_all('/{([a-z0-9_]+)\.([a-z0-9_]+)}/i', $output, $result_set, PREG_SET_ORDER);
476
+ foreach ($result_set as $result) {
477
+ list($original, $ref_code, $ref_key) = $result;
478
+ if ($ref_code==$row['*id'] && $ref_key==$key) {
479
+ $this->addMessage('error', $row, $key, 'Infinite loop %s', "<span class=\"code\">{$original}</span>");
480
+ return null;
481
+ }
482
+ if (isset($this->_config[$ref_code][$ref_key]['value'])) {
483
+ $replacement = $this->getRowProperty($this->_config[$ref_code], $ref_key,
484
+ isset($original_row) ? $original_row : $row, isset($original_key) ? $original_key : $key);
485
+ if (is_array($replacement) && isset($replacement['error'])) {
486
+ return isset($original_row) ? $replacement : 'false';
487
+ }
488
+ $output = $this->replace('{'.$original.'}', $this->_autoEscapeStrings($replacement), $output);
489
+ $output = $this->replace($original, $replacement, $output);
490
+ } else {
491
+ $replacement = $original;
492
+ $output = $this->replace($original, $replacement, $output);
493
+ }
494
+ //$this->addMessage('error', $row, $key, $original.' => '.$replacement.' = '.$output);
495
+ }
496
+ } else {
497
+ $this->debug(' get <span class=osh-key>'.self::esc($row['*id']).'</span>.<span class=osh-key>'.self::esc($key).'</span> = <span class=osh-formula>null</span>');
498
+ }
499
+ return $output;
500
+ }
501
+
502
+ public function evalInput($process, $row, $property_name, $input)
503
+ {
504
+ $result = $this->_prepareFormula($process, $row, $property_name, $input, $is_checking=false, $use_cache=true);
505
+ return $result->success ? $result->result : $input;
506
+ }
507
+
508
+ public function compress($input)
509
+ {
510
+ $input = str_replace(
511
+ self::$UNCOMPRESSED_STRINGS,
512
+ self::$COMPRESSED_STRINGS,
513
+ $input
514
+ );
515
+ if (function_exists('gzcompress') && function_exists('base64_encode')) {
516
+ $input = 'gz64'.base64_encode(gzcompress($input));
517
+ }
518
+ return '$$'.$input;
519
+ }
520
+
521
+ public function uncompress($input)
522
+ {
523
+ if (substr($input, 0, 4)=='gz64' && function_exists('gzuncompress') && function_exists('base64_decode')) {
524
+ $input = gzuncompress(base64_decode(substr($input, 4, strlen($input))));
525
+ }
526
+ return str_replace(
527
+ self::$COMPRESSED_STRINGS,
528
+ self::$UNCOMPRESSED_STRINGS,
529
+ $input
530
+ );
531
+ }
532
+
533
+ public function parseProperty($input)
534
+ {
535
+ if ($input==='false') return false;
536
+ if ($input==='true') return true;
537
+ if ($input==='null') return null;
538
+ if (is_numeric($input)) return (double)$input;
539
+ $value = str_replace('\"', '"', preg_replace('/^(?:"|\')(.*)(?:"|\')$/s', '$1', $input));
540
+ return $value==='' ? null : $value;
541
+ }
542
+
543
+ protected function replace($from, $to, $input, $class_name=null, $message='replace')
544
+ {
545
+ if ($from===$to) return $input;
546
+ if (mb_strpos($input, $from)===false) return $input;
547
+ $to = self::toString($to);
548
+ $to = preg_replace('/[\r\n\t]+/', ' ', $to);
549
+ $this->debug(' '
550
+ .($class_name ? '<span class="osh-'.$class_name.'">' : '')
551
+ .$message.' <span class=osh-replacement>'.self::esc(self::toString($from)).'</span> by <span class=osh-replacement>'.self::esc($to).'</span>'
552
+ .' =&gt; <span class=osh-formula>'.self::esc(str_replace($from, '<span class=osh-replacement>'.$to.'</span>', $input)).'</span>'
553
+ .($class_name ? '</span>' : ''));
554
+ return str_replace($from, $to, $input);
555
+ }
556
+
557
+ protected function _min()
558
+ {
559
+ $args = func_get_args();
560
+ $min = null;
561
+ foreach ($args as $arg) {
562
+ if (isset($arg) && (!isset($min) || $min>$arg)) $min = $arg;
563
+ }
564
+ return $min;
565
+ }
566
+
567
+ protected function _max()
568
+ {
569
+ $args = func_get_args();
570
+ $max = null;
571
+ foreach ($args as $arg) {
572
+ if (isset($arg) && (!isset($max) || $max<$arg)) $max = $arg;
573
+ }
574
+ return $max;
575
+ }
576
+
577
+ protected function _range($value=-1, $min_value=0, $max_value=1, $include_min_value=true, $include_max_value=true)
578
+ {
579
+ return ($value>$min_value || $include_min_value && $value==$min_value) && ($value<$max_value || $include_max_value && $value==$max_value);
580
+ }
581
+
582
+ protected function _array_match_any()
583
+ {
584
+ $args = func_get_args();
585
+ $result = call_user_func_array('array_intersect', $args);
586
+ return (bool)$result;
587
+ }
588
+
589
+ protected function _array_match_all()
590
+ {
591
+ $args = func_get_args();
592
+ if (!isset($args[0])) return false;
593
+ $result = call_user_func_array('array_intersect', $args);
594
+ return count($result)==count($args[0]);
595
+ }
596
+
597
+ public function processFormula($process, &$row, $property_name, $formula_string, $is_checking, $use_cache=true)
598
+ {
599
+ $result = $this->_prepareFormula($process, $row, $property_name, $formula_string, $is_checking, $use_cache);
600
+ if (!$result->success) return $result;
601
+
602
+ $eval_result = $this->_evalFormula($result->result, $row, $property_name, $is_checking);
603
+ if (!$is_checking && !isset($eval_result)) {
604
+ $this->addMessage('error', $row, $property_name, 'Empty result');
605
+ $result = new OS_Result(false);
606
+ if ($use_cache) $this->_setCache($formula_string, $result);
607
+ return $result;
608
+ }
609
+ $result = new OS_Result(true, $eval_result);
610
+ if ($use_cache) $this->_setCache($formula_string, $result);
611
+ return $result;
612
+ }
613
+
614
+ protected function _setCache($expression, $value)
615
+ {
616
+ if ($value instanceof OS_Result) {
617
+ $this->_formula_cache[$expression] = $value;
618
+ $this->debug(' cache <span class=osh-replacement>'.self::esc($expression).'</span> = <span class=osh-formula>'.self::esc(self::toString($value->result)).'</span> ('.gettype($value->result).')');
619
+ } else {
620
+ $this->_expression_cache[$expression] = $value; //self::toString($value); // In order to make isset work
621
+ $this->debug(' cache <span class=osh-replacement>'.self::esc($expression).'</span> = <span class=osh-formula>'.self::esc(self::toString($value)).'</span> ('.gettype($value).')');
622
+ }
623
+ }
624
+
625
+ protected function _getCachedExpression($original)
626
+ {
627
+ $replacement = $this->_expression_cache[$original];
628
+ $this->debug(' get cached expression <span class=osh-replacement>'.self::esc($original).'</span> = <span class=osh-formula>'.self::esc(self::toString($replacement)).'</span> ('.gettype($replacement).')');
629
+ return $replacement;
630
+ }
631
+
632
+ protected function _prepare_regexp($regexp)
633
+ {
634
+ if (!isset($this->constants)) {
635
+ $reflector = new ReflectionClass(get_class($this));
636
+ $this->constants = $reflector->getConstants();
637
+ }
638
+ foreach ($this->constants as $name => $value) {
639
+ $regexp = str_replace('{'.$name.'}', $value, $regexp);
640
+ }
641
+ return $regexp;
642
+ }
643
+
644
+ protected function _preg_match($regexp, $input, &$result, $debug=false)
645
+ {
646
+ $regexp = $this->_prepare_regexp($regexp);
647
+ if ($debug) $this->debug(' preg_match <span class=osh-replacement>'.self::esc($regexp).'</span>');
648
+ return preg_match($regexp, $input, $result);
649
+ }
650
+
651
+ protected function _preg_match_all($regexp, $input, &$result, $debug=false)
652
+ {
653
+ $regexp = $this->_prepare_regexp($regexp);
654
+ if ($debug) $this->debug(' preg_match_all <span class=osh-replacement>'.self::esc($regexp).'</span>');
655
+ $return = preg_match_all($regexp, $input, $result, PREG_SET_ORDER);
656
+ }
657
+
658
+ protected function _loadValue($process, $object_name, $attribute)
659
+ {
660
+ switch ($object_name) {
661
+ case 'item': return isset($process['data']['cart']->items[0]) ? $process['data']['cart']->items[0]->{$attribute} : null;
662
+ case 'product': return isset($process['data']['cart']->items[0]) ? $process['data']['cart']->items[0]->getProduct()->{$attribute} : null;
663
+ default: return isset($process['data'][$object_name]) ? $process['data'][$object_name]->{$attribute} : null;
664
+ }
665
+ }
666
+
667
+ protected function _prepareFormula($process, $row, $property_name, $formula_string, $is_checking, $use_cache=true)
668
+ {
669
+ if ($use_cache && isset($this->_formula_cache[$formula_string])) {
670
+ $result = $this->_formula_cache[$formula_string];
671
+ $this->debug(' get cached formula <span class=osh-replacement>'.self::esc($formula_string).'</span> = <span class=osh-formula>'.self::esc(self::toString($result->result)).'</span>');
672
+ return $result;
673
+ }
674
+
675
+ $formula = $formula_string;
676
+ //$this->debug(' formula = <span class=osh-formula>'.self::esc($formula).'</span>');
677
+
678
+ // foreach
679
+ while ($this->_preg_match("#{foreach ((?:item|product|p)\.[a-z0-9_\+\-\.]+)}(.*){/foreach}#iU", $formula, $result)) { // ungreedy
680
+ $original = $result[0];
681
+ if ($use_cache && array_key_exists($original, $this->_expression_cache)) {
682
+ $replacement = $this->_getCachedExpression($original);
683
+ } else {
684
+ $replacement = 0;
685
+ $loop_var = $result[1];
686
+ $selections = array();
687
+ $this->debug(' foreach <span class=osh-key>'.self::esc($loop_var).'</span>');
688
+ $this->addDebugIndent();
689
+ $items = $process['data']['cart']->items;
690
+ if ($items) {
691
+ foreach ($items as $item) {
692
+ $tmp_value = $this->_getItemProperty($item, $loop_var);
693
+ $values = (array)$tmp_value;
694
+ foreach ($values as $value_i) {
695
+ $key = self::_autoEscapeStrings($value_i);
696
+ $sel = isset($selections[$key]) ? $selections[$key] : null;
697
+ $selections[$key]['items'][] = $item;
698
+ }
699
+ $this->debug(' items[<span class=osh-formula>'.self::esc((string)$item).'</span>].<span class=osh-key>'.self::esc($loop_var).'</span> = [<span class=osh-formula>'.self::esc(implode('</span>, <span class=osh-formula>', $values)).'</span>]');
700
+ }
701
+ }
702
+ $this->removeDebugIndent();
703
+ $this->debug(' <span class=osh-loop>start foreach</span>');
704
+ $this->addDebugIndent();
705
+ foreach ($selections as $key => $selection) {
706
+ $this->debug(' <span class=osh-loop>&bull; value</span> = <span class=osh-formula>'.self::esc($key).'</span>');
707
+ $this->addDebugIndent();
708
+ $this->debug(' #### count '.count($process['data']['cart']->items));
709
+ $process2 = $process;
710
+ $process2['data']['cart'] = clone $process2['data']['cart']; // Important to not override previous items
711
+ $process2['data']['cart']->items = $selection['items'];
712
+ $selection['qty'] = 0;
713
+ $selection['weight'] = 0;
714
+ foreach ($selection['items'] as $item) {
715
+ $selection['qty'] += $item->qty;
716
+ $selection['weight'] += $item->weight;
717
+ }
718
+ if (isset($process2['data']['selection'])) {
719
+ $process2['data']['selection']->set('qty', $selection['qty']);
720
+ $process2['data']['selection']->set('weight', $selection['weight']);
721
+ }
722
+ $process_result = $this->processFormula($process2, $row, $property_name, $result[2], $is_checking, $tmp_use_cache=false);
723
+ $replacement += $process_result->result;
724
+ $this->debug(' &raquo; <span class=osh-info>foreach sum result</span> = <span class=osh-formula>'.self::esc(self::toString($replacement)).'</span>');
725
+ $this->removeDebugIndent();
726
+ }
727
+ $this->removeDebugIndent();
728
+ $this->debug(' <span class=osh-loop>end</span>');
729
+ if ($use_cache) $this->_setCache($original, $replacement);
730
+ }
731
+ $formula = $this->replace($original, $replacement, $formula);
732
+ }
733
+
734
+ if (isset($process['data']['selection'])) {
735
+ if ($process['data']['selection']->weight==null) $process['data']['selection']->set('weight', $process['data']['cart']->weight);
736
+ if ($process['data']['selection']->qty==null) $process['data']['selection']->set('qty', $process['data']['cart']->qty);
737
+ }
738
+
739
+ // data
740
+ $aliases = array(
741
+ 'p' => 'product',
742
+ 'c' => 'cart',
743
+ 's' => 'selection',
744
+ );
745
+ $formula = $this->_replaceData($process, $formula, 'item|product|p|c|s', $aliases);
746
+
747
+ // count, sum, min, max
748
+ //while ($this->_preg_match("/{(count) products(?: where ([^}]+))?}/i", $formula, $result)
749
+ // || $this->_preg_match("/{(sum|min|max|count distinct) {PRODUCT_REGEX}\.({ATTRIBUTE_REGEX}|{OPTION_REGEX}|stock)\.([a-z0-9_+-]+)(?: where ([^}]+))?}/i", $formula, $result)
750
+ // || $this->_preg_match("/{(sum|min|max|count distinct) {PRODUCT_REGEX}\.(quantity)()(?: where ([^}]+))?}/i", $formula, $result)
751
+ while ($this->_preg_match("/{(count)\s+items\s*(?:\s+where\s+((?:[^\"'}]|'[^']+'|\"[^\"]+\")+))?}/i", $formula, $result)
752
+ || $this->_preg_match("/{(sum|min|max|count distinct) ((?:item|product|p)\.[a-z0-9_\+\-\.]+)(?: where ((?:[^\"'}]|'[^']+'|\"[^\"]+\")+))?}/i", $formula, $result)
753
+ ) {
754
+ $original = $result[0];
755
+ if ($use_cache && array_key_exists($original, $this->_expression_cache)) {
756
+ $replacement = $this->_getCachedExpression($original);
757
+ } else {
758
+ $replacement = $this->_processProduct($process['data']['cart']->items, $result, $row, $property_name, $is_checking);
759
+ if ($use_cache) $this->_setCache($result[0], $replacement);
760
+ }
761
+ $formula = $this->replace($original, $replacement, $formula);
762
+ }
763
+
764
+ // switch
765
+ while (preg_match("/{switch ([^}]+) in ([^}]+)}/i", $formula, $result)) {
766
+ $original = $result[0];
767
+ if ($use_cache && array_key_exists($original, $this->_expression_cache)) {
768
+ $replacement = $this->_getCachedExpression($original);
769
+ } else {
770
+ $reference_value = $this->_evalFormula($result[1], $row, $property_name, $is_checking);
771
+ $fees_table_string = $result[2];
772
+
773
+ $couple_regex = '[^}:]+ *\: *[0-9.]+ *';
774
+ if (!preg_match('#^ *'.$couple_regex.'(?:, *'.$couple_regex.')*$#', $fees_table_string)) {
775
+ $this->addMessage('error', $row, $property_name, 'Error in switch %s', '<span class=osh-formula>'.self::esc($result[0]).'</span>');
776
+ $result = new OS_Result(false);
777
+ if ($use_cache) $this->_setCache($formula_string, $result);
778
+ return $result;
779
+ }
780
+ $fees_table = explode(',', $fees_table_string);
781
+
782
+ $replacement = null;
783
+ foreach ($fees_table as $item) {
784
+ $fee_data = explode(':', $item);
785
+
786
+ $fee = trim($fee_data[1]);
787
+ $value = trim($fee_data[0]);
788
+ $value = $value=='*' ? '*' : $this->_evalFormula($fee_data[0], $row, $property_name, $is_checking);
789
+
790
+ if ($value=='*' || $reference_value===$value) {
791
+ $replacement = $fee;
792
+ $this->debug(' compare <span class=osh-formula>'.self::esc($this->_autoEscapeStrings($reference_value)).'</span> == <span class=osh-formula>'.self::esc($this->_autoEscapeStrings($value)).'</span>');
793
+ break;
794
+ }
795
+ $this->debug(' compare <span class=osh-formula>'.self::esc($this->_autoEscapeStrings($reference_value)).'</span> != <span class=osh-formula>'.self::esc($this->_autoEscapeStrings($value)).'</span>');
796
+ }
797
+ //$replacement = self::toString($replacement);
798
+ if ($use_cache) $this->_setCache($original, $replacement);
799
+ }
800
+ $formula = $this->replace($original, $replacement, $formula);
801
+ }
802
+
803
+ // range table
804
+ while (preg_match("/{table ([^}]+) in ([0-9\.:,\*\[\] ]+)}/i", $formula, $result)) {
805
+ $original = $result[0];
806
+ if ($use_cache && array_key_exists($original, $this->_expression_cache)) {
807
+ $replacement = $this->_getCachedExpression($original);
808
+ } else {
809
+ $reference_value = $this->_evalFormula($result[1], $row, $property_name, $is_checking);
810
+ $replacement = null;
811
+ if (isset($reference_value)) {
812
+ $fees_table_string = $result[2];
813
+
814
+ if (!preg_match('#^'.self::COUPLE_REGEX.'(?:, *'.self::COUPLE_REGEX.')*$#', $fees_table_string)) {
815
+ $this->addMessage('error', $row, $property_name, 'Error in table %s', '<span class=osh-formula>'.self::esc($result[0]).'</span>');
816
+ $result = new OS_Result(false);
817
+ if ($use_cache) $this->_setCache($formula_string, $result);
818
+ return $result;
819
+ }
820
+ $fees_table = explode(',', $fees_table_string);
821
+ foreach ($fees_table as $item) {
822
+ $fee_data = explode(':', $item);
823
+
824
+ $fee = trim($fee_data[1]);
825
+ $max_value = trim($fee_data[0]);
826
+
827
+ $last_char = $max_value{strlen($max_value)-1};
828
+ if ($last_char=='[') $including_max_value = false;
829
+ else if ($last_char==']') $including_max_value = true;
830
+ else $including_max_value = true;
831
+
832
+ $max_value = str_replace(array('[', ']'), '', $max_value);
833
+
834
+ if ($max_value=='*' || $including_max_value && $reference_value<=$max_value || !$including_max_value && $reference_value<$max_value) {
835
+ $replacement = $fee;
836
+ break;
837
+ }
838
+ }
839
+ }
840
+ //$replacement = self::toString($replacement);
841
+ if ($use_cache) $this->_setCache($original, $replacement);
842
+ }
843
+ $formula = $this->replace($original, $replacement, $formula);
844
+ }
845
+ $result = new OS_Result(true, $formula);
846
+ return $result;
847
+ }
848
+
849
+ protected function _evalFormula($formula, &$row, $property_name=null, $is_checking=false)
850
+ {
851
+ if (is_bool($formula)) return $formula;
852
+ if (!preg_match('/^(?:'
853
+ .'\b(?:'
854
+ .'E|e|int|float|string|boolean|object|array|true|false|null|and|or|in'
855
+ .'|floor|ceil|round|rand|pow|pi|sqrt|log|exp|abs|substr|strtolower|preg_match|in_array'
856
+ .'|max|min|range|array_match_any|array_match_all'
857
  .'|date|strtotime'
858
+ .')\b'
859
+ .'|\'[^\']*\'|\"[^\"]*\"|[0-9,\'\.\-\(\)\*\/\?\:\+\<\>\=\&\|%!]|\s)*$/', $formula)) {
860
+ $errors = array(
861
+ PREG_NO_ERROR => 'PREG_NO_ERROR',
862
+ PREG_INTERNAL_ERROR => 'PREG_INTERNAL_ERROR',
863
+ PREG_BACKTRACK_LIMIT_ERROR => 'PREG_BACKTRACK_LIMIT_ERROR',
864
+ PREG_RECURSION_LIMIT_ERROR => 'PREG_RECURSION_LIMIT_ERROR',
865
+ PREG_BAD_UTF8_ERROR => 'PREG_BAD_UTF8_ERROR',
866
+ defined('PREG_BAD_UTF8_OFFSET_ERROR') ? PREG_BAD_UTF8_OFFSET_ERROR : 'PREG_BAD_UTF8_OFFSET_ERROR' => 'PREG_BAD_UTF8_OFFSET_ERROR',
867
+ );
868
+ $error = preg_last_error();
869
+ if (isset($errors[$error])) $error = $errors[$error];
870
+ if ($is_checking) $this->addMessage('error', $row, $property_name, $error.' ('.$formula.')');
871
+ $this->debug(' eval <span class=osh-formula>'.self::esc($formula).'</span>');
872
+ $this->debug(' doesn\'t match ('.self::esc($error).')');
873
+ return null;
874
+ }
875
+ $formula = preg_replace('@\b(min|max|range|array_match_any|array_match_all)\(@', '\$this->_\1', $formula);
876
+ $eval_result = null;
877
+ //echo $formula.'<br/>';
878
+ @eval('$eval_result = ('.$formula.');');
879
+ $this->debug(' evaluate <span class=osh-formula>'.self::esc($formula).'</span> = <span class=osh-replacement>'.self::esc($this->_autoEscapeStrings($eval_result)).'</span>');
880
+ return $eval_result;
881
+ }
882
+
883
+ protected function _parseInput($auto_correction)
884
+ {
885
+ $config_string = str_replace(
886
+ array('&gt;', '&lt;', '“', '”', utf8_encode(chr(147)), utf8_encode(chr(148)), '&laquo;', '&raquo;', "\r\n", "\t"),
887
+ array('>', '<', '"', '"', '"', '"', '"', '"', "\n", ' '),
888
+ $this->_input
889
+ );
890
+
891
+ if (substr($config_string, 0, 2)=='$$') $config_string = $this->uncompress(substr($config_string, 2, strlen($config_string)));
892
+
893
+ //echo ini_get('pcre.backtrack_limit');
894
+ //exit;
895
+
896
+ $this->debug('parse config (auto correction = '.self::esc(self::toString($auto_correction)).')');
897
+ $config = null;
898
+ $last_json_error = null;
899
+ try {
900
+ $config = self::json_decode($config_string);
901
+ } catch (Exception $e) {
902
+ $last_json_error = $e;
903
+ }
904
+ $auto_correction_warnings = array();
905
+ $missing_enquote_of_property_name = array();
906
+ if ($config) {
907
+ foreach ($config as $code => $object) {
908
+ if (!is_object($object)) {
909
+ $config = null;
910
+ break;
911
+ }
912
+ }
913
+ }
914
+ if ($auto_correction && !$config && $config_string!='[]') {
915
+ if (preg_match_all('/((?:#+[^{\\n]*\\s+)+)\\s*{/s', $config_string, $result, PREG_SET_ORDER)) {
916
+ $auto_correction_warnings[] = 'JSON: usage of incompatible comments';
917
+ foreach ($result as $set) {
918
+ $comment_lines = explode("\n", $set[1]);
919
+ foreach ($comment_lines as $i => $line) {
920
+ $comment_lines[$i] = preg_replace('/^#+\\s/', '', $line);
921
+ }
922
+ $comment = trim(implode("\n", $comment_lines));
923
+ $config_string = str_replace($set[0], '{"about": "'.str_replace('"', '\\"', $comment).'",', $config_string);
924
+ }
925
+ }
926
+ $property_regex = '\\s*(?<property_name>"?[a-z0-9_]+"?)\\s*:\\s*(?<property_value>"(?:(?:[^"]|\\\\")*[^\\\\])?"|'.self::FLOAT_REGEX.'|false|true|null)\\s*(?<property_separator>,)?\\s*(?:\\n)?';
927
+ $object_regex = '(?:(?<object_name>"?[a-z0-9_]+"?)\\s*:\\s*)?{\\s*('.$property_regex.')+\\s*}\\s*(?<object_separator>,)?\\s*';
928
+ preg_match_all('/('.$object_regex.')/is', $config_string, $object_set, PREG_SET_ORDER);
929
+ //print_r($object_set);
930
+ $json = array();
931
+ $objects_count = count($object_set);
932
+ $to_ignore_counter = -1;
933
+ foreach ($object_set as $i => $object) {
934
+ $pos = strpos($config_string, $object[0]);
935
+ $to_ignore = trim(substr($config_string, 0, $pos));
936
+ if ($to_ignore) {
937
+ $to_ignore_counter++;
938
+ if ($to_ignore_counter==0) {
939
+ $bracket_pos = strpos($to_ignore, '{');
940
+ if ($bracket_pos!==false) {
941
+ $to_ignore = explode('{', $to_ignore, 2);
942
+ }
943
+ }
944
+ $to_ignore = (array)$to_ignore;
945
+ foreach ($to_ignore as $to_ignore_i) {
946
+ $to_ignore_i = trim($to_ignore_i);
947
+ if (!$to_ignore_i) continue;
948
+ $auto_correction_warnings[] = 'JSON: ignored lines (<span class=osh-formula>'.self::toString($to_ignore_i).'</span>)';
949
+ $n = 0;
950
+ do {
951
+ $key = 'meta'.$n;
952
+ $n++;
953
+ } while(isset($json[$key]));
954
+ $json[$key] = array(
955
+ 'type' => 'meta',
956
+ 'ignored' => $to_ignore_i,
957
+ );
958
+ }
959
+ $config_string = substr($config_string, $pos, strlen($config_string));
960
+ }
961
+ $config_string = str_replace($object[0], '', $config_string);
962
+ $object_name = isset($object['object_name']) ? $object['object_name'] : null;
963
+ $object_separator = isset($object['object_separator']) ? $object['object_separator'] : null;
964
+ $is_last_object = ($i==$objects_count-1);
965
+ if (!$is_last_object && $object_separator!=',') {
966
+ $auto_correction_warnings[] = 'JSON: missing object separator (comma)';
967
+ } else if ($is_last_object && $object_separator==',') {
968
+ $auto_correction_warnings[] = 'JSON: no trailing object separator (comma) allowed';
969
+ }
970
+ $json_object = array();
971
+ preg_match_all('/'.$property_regex.'/i', $object[0], $property_set, PREG_SET_ORDER);
972
+ $properties_count = count($property_set);
973
+ foreach ($property_set as $j => $property) {
974
+ $name = $property['property_name'];
975
+ if ($name{0}!='"' || $name{strlen($name)-1}!='"') {
976
+ $auto_correction_warnings['missing_enquote_of_property_name'] = 'JSON: missing enquote of property name: %s';
977
+ $missing_enquote_of_property_name[] = self::toString(trim($name, '"'));
978
+ }
979
+ $property_separator = isset($property['property_separator']) ? $property['property_separator'] : null;
980
+ $is_last_property = ($j==$properties_count-1);
981
+ if (!$is_last_property && $property_separator!=',') {
982
+ $auto_correction_warnings[] = 'JSON: missing property separator (comma)';
983
+ } else if ($is_last_property && $property_separator==',') {
984
+ $auto_correction_warnings[] = 'JSON: no trailing property separator (comma) allowed';
985
+ }
986
+ $json_object[trim($name, '"')] = $this->parseProperty($property['property_value']);
987
+ }
988
+ if ($object_name) $json[trim($object_name, '"')] = $json_object;
989
+ else if (isset($json_object['code'])) {
990
+ $code = $json_object['code'];
991
+ unset($json_object['code']);
992
+ $json[$code] = $json_object;
993
+ } else $json[] = $json_object;
994
+ }
995
+ $to_ignore = trim($config_string);
996
+ if ($to_ignore) {
997
+ $bracket_pos = strpos($to_ignore, '}');
998
+ if ($bracket_pos!==false) {
999
+ $to_ignore = explode('}', $to_ignore, 2);
1000
+ }
1001
+ $to_ignore = (array)$to_ignore;
1002
+ foreach ($to_ignore as $to_ignore_i) {
1003
+ $to_ignore_i = trim($to_ignore_i);
1004
+ if (!$to_ignore_i) continue;
1005
+ $auto_correction_warnings[] = 'JSON: ignored lines (<span class=osh-formula>'.self::toString($to_ignore_i).'</span>)';
1006
+ $n = 0;
1007
+ do {
1008
+ $key = 'meta'.$n;
1009
+ $n++;
1010
+ } while(isset($json[$key]));
1011
+ $json[$key] = array(
1012
+ 'type' => 'meta',
1013
+ 'ignored' => $to_ignore_i,
1014
+ );
1015
+ }
1016
+ }
1017
+ $config_string = $this->jsonEncode($json);//'['.$config_string2.']';
1018
+ $config_string = str_replace(array("\n"), array("\\n"), $config_string);
1019
+ //echo $config_string;
1020
+
1021
+ $last_json_error = null;
1022
+ try {
1023
+ $config = self::json_decode($config_string);
1024
+ } catch (Exception $e) {
1025
+ $last_json_error = $e;
1026
+ }
1027
+ }
1028
+ if ($last_json_error) {
1029
+ $auto_correction_warnings[] = 'JSON: unable to parse config ('.$last_json_error->getMessage().')';
1030
+ }
1031
+
1032
+ $row = null;
1033
+ $auto_correction_warnings = array_unique($auto_correction_warnings);
1034
+ foreach ($auto_correction_warnings as $key => $warning) {
1035
+ if ($key=='missing_enquote_of_property_name') {
1036
+ $missing_enquote_of_property_name = array_unique($missing_enquote_of_property_name);
1037
+ $warning = str_replace('%s', '<span class=osh-key>'.self::esc(implode('</span>, <span class=osh-key>', $missing_enquote_of_property_name)).'</span>', $warning);
1038
+ }
1039
+ $this->addMessage('warning', $row, null, $warning);
1040
+ }
1041
+ $config = (array)$config;
1042
+
1043
+ $this->_config = array();
1044
+ $available_keys = array('type', 'about', 'label', 'enabled', 'description', 'fees', 'conditions', 'shipto', 'billto', 'origin', 'customer_groups', 'tracking_url');
1045
+ $reserved_keys = array('*id');
1046
+ if ($auto_correction) {
1047
+ $available_keys = array_merge($available_keys, array(
1048
+ 'destination', 'code',
1049
+ ));
1050
+ }
1051
+
1052
+ $deprecated_properties = array();
1053
+ $unknown_properties = array();
1054
+
1055
+ foreach ($config as $code => $object) {
1056
+ $object = (array)$object;
1057
+ if ($auto_correction) {
1058
+ if (isset($object['destination'])) {
1059
+ if (!in_array('destination', $deprecated_properties)) $deprecated_properties[] = 'destination';
1060
+ $object['shipto'] = $object['destination'];
1061
+ unset($object['destination']);
1062
+ }
1063
+ if (isset($object['code'])) {
1064
+ if (!in_array('code', $deprecated_properties)) $deprecated_properties[] = 'code';
1065
+ $code = $object['code'];
1066
+ unset($object['code']);
1067
+ }
1068
+ }
1069
+
1070
+ $row = array();
1071
+ $i = 1;
1072
+ foreach ($object as $property_name => $property_value) {
1073
+ if (in_array($property_name, $reserved_keys)) {
1074
+ continue;
1075
+ }
1076
+ if (in_array($property_name, $available_keys)
1077
+ || substr($property_name, 0, 1)=='_'
1078
+ || in_array($object['type'], array('data', 'meta'))) {
1079
+ if (isset($property_value)) {
1080
+ $row[$property_name] = array('value' => $property_value, 'original_value' => $property_value);
1081
+ if ($auto_correction) $this->cleanProperty($row, $property_name);
1082
+ }
1083
+ } else {
1084
+ if (!in_array($property_name, $unknown_properties)) $unknown_properties[] = $property_name;
1085
+ }
1086
+ $i++;
1087
+ }
1088
+ $this->addRow($code, $row);
1089
+ }
1090
+ $row = null;
1091
+ 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>');
1092
+ 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>');
1093
+ }
1094
+
1095
+ public function addRow($code, &$row)
1096
+ {
1097
+ if ($code) {
1098
+ if (isset($this->_config[$code])) $this->addMessage('error', $row, 'code', 'The id must be unique, `%s` has been found twice', $code);
1099
+ while (isset($this->_config[$code])) $code .= rand(0, 9);
1100
+ }
1101
+ $row['*id'] = $code;
1102
+ $this->_config[$code] = $row;
1103
+ }
1104
+
1105
+ public function addMessage($type, &$row, $property)
1106
+ {
1107
+ $args = func_get_args();
1108
+ array_shift($args);
1109
+ array_shift($args);
1110
+ array_shift($args);
1111
+ $message = new OS_Message($type, $args);
1112
+ if (isset($row)) {
1113
+ if (isset($property)) {
1114
+ $row[$property]['messages'][] = $message;
1115
+ } else {
1116
+ $row['*messages'][] = $message;
1117
+ }
1118
+ }
1119
+ $this->_messages[] = $message;
1120
+ $this->debug(' => <span class=osh-'.$message->type.'>'.self::esc((string)$message).'</span>');
1121
+ }
1122
+
1123
+ protected function _replaceVariable(&$process, $input, $original, $replacement)
1124
+ {
1125
+ if (mb_strpos($input, '{'.$original.'}')!==false) {
1126
+ $input = $this->replace('{'.$original.'}', $this->_autoEscapeStrings($replacement), $input);
1127
+ }
1128
+ if (mb_strpos($input, $original)!==false) {
1129
+ if (!isset($process['options']->auto_escaping) || $process['options']->auto_escaping) {
1130
+ $input = $this->replace($original, $this->_autoEscapeStrings($replacement), $input);
1131
+ } else {
1132
+ $input = $this->replace($original, $replacement, $input);
1133
+ }
1134
+ }
1135
+ return $input;
1136
+ }
1137
+
1138
+ protected function _replaceData(&$process, $input, $keys = '', $aliases = array())
1139
+ {
1140
+ $keys = ($keys ? $keys.'|' : '').implode('|', array_keys($process['data']));
1141
+ $keys = preg_replace('/[^a-z_\|]/', '_', $keys);
1142
+ // data
1143
+ while ($this->_preg_match("#{({$keys})\.([a-z0-9_\+\-\.]+)}#i", $input, $result)) {
1144
+ $original = $result[0];
1145
+ $object_name = isset($aliases[$result[1]]) ? $aliases[$result[1]] : $result[1];
1146
+ $replacement = $this->_loadValue($process, $object_name, $result[2]);
1147
+ $input = $this->_replaceVariable($process, $input, $original, $replacement);
1148
+ }
1149
+ return $input;
1150
+ }
1151
+
1152
+ protected function _addressMatch(&$process, &$row, $property_name, $address_filter, $address)
1153
+ {
1154
+ //$address_filter = '(* - ( europe (FR-(25,26),DE(40,42) ))';
1155
+ //echo '<pre>';
1156
+ $address_filter = $this->_replaceData($process, $address_filter);
1157
+ $parser = new OS2_AddressFilterParser();
1158
+ $address_filter = $parser->parse($address_filter);
1159
+
1160
+ $this->debug(' address filter = <span class=osh-formula>'.self::esc($address_filter).'</span>');
1161
+ $data = array(
1162
+ '{c}' => $address->country_id,
1163
+ '{p}' => $address->postcode,
1164
+ '{r}' => $address->region_code,
1165
+ );
1166
+ foreach ($data as $original => $replacement) {
1167
+ $address_filter = $this->_replaceVariable($process, $address_filter, $original, $replacement);
1168
+ }
1169
+ return (bool)$this->_evalFormula($address_filter, $row, $property_name, $is_checking=false);
1170
+ }
1171
+
1172
+ protected function _getItemProperty($item, $property_name)
1173
+ {
1174
+ $elems = explode('.', $property_name, $limit=2);
1175
+ switch ($elems[0]) {
1176
+ case 'p':
1177
+ case 'product': return $item->getProduct()->{$elems[1]};
1178
+ case 'item': return $item->{$elems[1]};
1179
+ }
1180
+ return null;
1181
+ }
1182
+
1183
+ protected function _autoEscapeStrings($input)
1184
+ {
1185
+ if (is_array($input)) {
1186
+ $items = array();
1187
+ foreach ($input as $v) {
1188
+ $items[] = isset($v) && (is_string($v) || empty($v)) ? self::escapeString($v) : self::toString($v);
1189
+ }
1190
+ return 'array('.join(',', $items).')';
1191
+ } else {
1192
+ return isset($input) && (is_string($input)/* || empty($input)*/) ? self::escapeString($input) : self::toString($input);
1193
+ }
1194
+ }
1195
+
1196
+ protected function _processProduct($items, $regex_result, &$row, $property_name, $is_checking)
1197
+ {
1198
+ // count, sum, min, max, count distinct
1199
+ $operation = strtolower($regex_result[1]);
1200
+ $return_value = null;
1201
+ $reference = 'items';
1202
+ switch ($operation) {
1203
+ case 'sum':
1204
+ case 'min':
1205
+ case 'max':
1206
+ case 'count distinct':
1207
+ $reference = $regex_result[2];
1208
+ $conditions = isset($regex_result[3]) ? $regex_result[3] : null;
1209
+ break;
1210
+ case 'count':
1211
+ $conditions = isset($regex_result[2]) ? $regex_result[2] : null;
1212
+ break;
1213
+ }
1214
+ switch ($operation) {
1215
+ case 'sum':
1216
+ case 'count distinct':
1217
+ case 'count':
1218
+ $return_value = 0;
1219
+ break;
1220
+ }
1221
+
1222
+ $this->debug(' <span class=osh-loop>start <span class=osh-replacement>'.self::esc($operation).'</span> '
1223
+ .'<span class=osh-key>'.self::esc($reference).'</span>'
1224
+ .(isset($conditions) ? ' where <span class=osh-replacement>'.self::esc($conditions).'</span></span>' : '')
1225
+ );
1226
+ $this->addDebugIndent();
1227
+
1228
+ $properties = array();
1229
+ $this->_preg_match_all('#(?:item|product|p)\.([a-z0-9_\+\-\.]+)#i', $conditions, $properties_regex_result);
1230
+ foreach ($properties_regex_result as $property_regex_result) {
1231
+ if (!isset($properties[$property_regex_result[0]])) $properties[$property_regex_result[0]] = $property_regex_result;
1232
+ }
1233
+ krsort($properties); // To avoid shorter replace
1234
+
1235
+ if ($items) {
1236
+ foreach ($items as $item) {
1237
+ $this->debug(' <span class=osh-loop>&bull; item</span> = <span class=osh-formula>'.self::esc((string)$item).'</span>');
1238
+ $this->addDebugIndent();
1239
+ if (isset($conditions) && $conditions!='') {
1240
+ $formula = $conditions;
1241
+ foreach ($properties as $property) {
1242
+ $value = $this->_getItemProperty($item, $property[0]);
1243
+ $from = $property[0];
1244
+ $to = $this->_autoEscapeStrings($value);
1245
+ $this->debug(' replace <span class=osh-replacement>'.self::esc($from).'</span> by <span class=osh-replacement>'.self::esc($to).'</span> =&gt; <span class=osh-formula>'.self::esc(str_replace($from, '<span class=osh-replacement>'.$to.'</span>', $formula)).'</span>');
1246
+ $formula = str_replace($from, $to, $formula);
1247
+ }
1248
+ $eval_result = $this->_evalFormula($formula, $row, $property_name, $is_checking);
1249
+ if (!isset($eval_result)) $return_value = 'null';
1250
+ }
1251
+ else $eval_result = true;
1252
+
1253
+ if ($eval_result==true) {
1254
+ if ($operation=='count') {
1255
+ $return_value = (isset($return_value) ? $return_value : 0) + $item->qty;
1256
+ } else {
1257
+ $value = $this->_getItemProperty($item, $reference);
1258
+ $this->debug(' &raquo; <span class=osh-key>'.self::esc($reference).'</span> = <span class=osh-formula>'.self::esc($value).'</span>'
1259
+ .($operation=='sum' ? ' x <span class=osh-formula>'.$item->qty.'</span>' : ''));
1260
+ switch ($operation) {
1261
+ case 'min': if (!isset($return_value) || $value<$return_value) $return_value = $value; break;
1262
+ case 'max': if (!isset($return_value) || $value>$return_value) $return_value = $value; break;
1263
+ case 'sum':
1264
+ //$this->debug(self::esc($item->getProduct()->sku).'.'.self::esc($reference).' = "'.self::esc($value).'" x '.self::esc($item->qty));
1265
+ $return_value = (isset($return_value) ? $return_value : 0) + $value*$item->qty;
1266
+ break;
1267
+ case 'count distinct':
1268
+ if (!isset($return_value)) $return_value = 0;
1269
+ if (!isset($distinct_values)) $distinct_values = array();
1270
+ if (!in_array($value, $distinct_values)) {
1271
+ $distinct_values[] = $value;
1272
+ $return_value++;
1273
+ }
1274
+ break;
1275
+ }
1276
+ }
1277
+ }
1278
+ $this->debug(' &raquo; <span class=osh-info>'.self::esc($operation).' result</span> = <span class=osh-formula>'.self::esc($return_value).'</span>');
1279
+ $this->removeDebugIndent();
1280
+ }
1281
+ }
1282
+
1283
+ $this->removeDebugIndent();
1284
+ $this->debug(' <span class=osh-loop>end</span>');
1285
+
1286
+ return $return_value;
1287
+ }
1288
+
1289
+ /* For auto correction */
1290
+ public function cleanProperty(&$row, $key)
1291
+ {
1292
+ $input = $row[$key]['value'];
1293
+ if (is_string($input)) {
1294
+ while (preg_match('/{{customVar code=([a-zA-Z0-9_-]+)}}/', $input, $resi)) {
1295
+ $input = $this->replace($resi[0], '{customvar.'.$resi[1].'}', $input, 'warning', 'replace deprecated');
1296
+ }
1297
+
1298
+ $regex = "{(weight|products_quantity|price_including_tax|price_excluding_tax|country)}";
1299
+ if (preg_match('/'.$regex.'/', $input, $resi)) {
1300
+ $this->addMessage('warning', $row, $key, 'Usage of deprecated syntax %s', '<span class=osh-formula>'.$resi[0].'</span>');
1301
+ while (preg_match('/'.$regex.'/', $input, $resi)) {
1302
+ switch ($resi[1]) {
1303
+ case 'price_including_tax': $to = "{cart.price+tax+discount}"; break;
1304
+ case 'price_excluding_tax': $to = "{cart.price-tax+discount}"; break;
1305
+ case 'weight': $to = "{cart.{$resi[1]}}"; break;
1306
+ case 'products_quantity': $to = "{cart.qty}"; break;
1307
+ case 'country': $to = "{shipto.country_name}"; break;
1308
+ }
1309
+ $input = str_replace($resi[0], $to, $input);
1310
+ }
1311
+ }
1312
+
1313
+ $regex1 = "{copy '([a-zA-Z0-9_]+)'\.'([a-zA-Z0-9_]+)'}";
1314
+ if (preg_match('/'.$regex1.'/', $input, $resi)) {
1315
+ $this->addMessage('warning', $row, $key, 'Usage of deprecated syntax %s', '<span class=osh-formula>'.$resi[0].'</span>');
1316
+ while (preg_match('/'.$regex1.'/', $input, $resi)) $input = str_replace($resi[0], '{'.$resi[1].'.'.$resi[2].'}', $input);
1317
+ }
1318
+
1319
+ $regex1 = "{(count|all|any) (attribute|option) '([^'\)]+)' ?((?:==|<=|>=|<|>|!=) ?(?:".self::FLOAT_REGEX."|true|false|'[^'\)]*'))}";
1320
+ $regex2 = "{(sum) (attribute|option) '([^'\)]+)'}";
1321
+ if (preg_match('/'.$regex1.'/', $input, $resi) || preg_match('/'.$regex2.'/', $input, $resi)) {
1322
+ $this->addMessage('warning', $row, $key, 'Usage of deprecated syntax %s', '<span class=osh-formula>'.$resi[0].'</span>');
1323
+ while (preg_match('/'.$regex1.'/', $input, $resi) || preg_match('/'.$regex2.'/', $input, $resi)) {
1324
+ switch ($resi[1]) {
1325
+ case 'count': $to = "{count items where product.{$resi[2]}.{$resi[3]}{$resi[4]}}"; break;
1326
+ case 'all': $to = "{count items where product.{$resi[2]}.{$resi[3]}{$resi[4]}}=={cart.qty}"; break;
1327
+ case 'any': $to = "{count items where product.{$resi[2]}.{$resi[3]}{$resi[4]}}>0"; break;
1328
+ case 'sum': $to = "{sum product.{$resi[2]}.{$resi[3]}}"; break;
1329
+ }
1330
+ $input = str_replace($resi[0], $to, $input);
1331
+ }
1332
+ }
1333
+
1334
+ $regex = "((?:{| )product.(?:attribute|option))s.";
1335
+ if (preg_match('/'.$regex.'/', $input, $resi)) {
1336
+ $this->addMessage('warning', $row, $key, 'Usage of deprecated syntax %s', '<span class=osh-formula>'.$resi[0].'</span>');
1337
+ while (preg_match('/'.$regex.'/', $input, $resi)) {
1338
+ $input = str_replace($resi[0], $resi[1].'.', $input);
1339
+ }
1340
+ }
1341
+
1342
+ $regex = "{table '([^']+)' (".self::COUPLE_REGEX."(?:, *".self::COUPLE_REGEX.")*)}";
1343
+ if (preg_match('/'.$regex.'/', $input, $resi)) {
1344
+ $this->addMessage('warning', $row, $key, 'Usage of deprecated syntax %s', '<span class=osh-formula>'.$resi[0].'</span>');
1345
+ while (preg_match('/'.$regex.'/', $input, $resi)) {
1346
+ switch ($resi[1]) {
1347
+ case 'products_quantity':
1348
+ $input = str_replace($resi[0], "{table {cart.weight} in {$resi[2]}}*{cart.qty}", $input);
1349
+ break;
1350
+ default:
1351
+ $input = str_replace($resi[0], "{table {cart.{$resi[1]}} in {$resi[2]}}", $input);
1352
+ break;
1353
+ }
1354
+ }
1355
+ }
1356
+
1357
+ $aliases = array(
1358
+ '{destination.country.code}' => '{shipto.country_id}',
1359
+ '{destination.country.name}' => '{shipto.country_name}',
1360
+ '{destination.region.code}' => '{shipto.region_code}',
1361
+ '{destination.postcode}' => '{shipto.postcode}',
1362
+ '.destination}' => '.shipto}',
1363
+ '{cart.price_excluding_tax}' => '{cart.price-tax+discount}',
1364
+ '{cart.price_including_tax}' => '{cart.price+tax+discount}',
1365
+ '{cart.weight.unit}' => '{cart.weight_unit}',
1366
+ '{cart.coupon}' => '{cart.coupon_code}',
1367
+ '{cart.weight.for-charge}' => '{cart.weight_for_charge}',
1368
+ '{c.price_excluding_tax}' => '{c.price-tax+discount}',
1369
+ '{c.price_including_tax}' => '{c.price+tax+discount}',
1370
+ '{c.weight.unit}' => '{c.weight_unit}',
1371
+ '{c.coupon}' => '{c.coupon_code}',
1372
+ '{free_shipping}' => '{cart.free_shipping}',
1373
+ '{c.weight.for-charge}' => '{c.weight_for_charge}',
1374
+ '{customer.group.id}' => '{customer_group.id}',
1375
+ '{customer.group.code}' => '{customer_group.code}',
1376
+ '{origin.country.code}' => '{origin.country_id}',
1377
+ '{origin.country.name}' => '{origin.country_name}',
1378
+ '{origin.region.code}' => '{origin.region_id}',
1379
+ '{selection.quantity}' => '{selection.qty}',
1380
+ 'product.quantity' => 'item.qty',
1381
+ 'product.stock.quantity' => 'product.stock.qty',
1382
+ 'product.options.' => 'item.option.',
1383
+ 'product.option.' => 'item.option.',
1384
+ 'product.o.' => 'item.o.',
1385
+ 'p.quantity' => 'item.qty',
1386
+ 'p.stock.quantity' => 'p.stock.qty',
1387
+ 'p.options.' => 'item.option.',
1388
+ 'p.option.' => 'item.option.',
1389
+ 'p.o.' => 'item.o.',
1390
+ 'count products ' => 'count items ',
1391
+ 'product.attribute.price+tax+discount' => 'item.price+tax+discount',
1392
+ 'product.attribute.price+tax-discount' => 'item.price+tax-discount',
1393
+ 'product.attribute.price-tax+discount' => 'item.price-tax+discount',
1394
+ 'product.attribute.price-tax-discount' => 'item.price-tax-discount',
1395
+ );
1396
+ foreach ($aliases as $from => $to) {
1397
+ if (mb_strpos($input, $from)!==false) {
1398
+ $input = $this->replace($from, $to, $input, 'warning', 'replace deprecated');
1399
+ }
1400
+ }
1401
+ }
1402
+ $row[$key]['value'] = $input;
1403
+ }
 
 
 
 
1404
 
1405
  }
1406
 
1407
  class OS2_Data
1408
  {
1409
+ protected $_data;
1410
+
1411
+ public function __construct($data=null)
1412
+ {
1413
+ $this->_data = (array)$data;
1414
+ }
1415
+
1416
+ public function __sleep()
1417
+ {
1418
+ return array_keys($this->_data);
1419
+ }
1420
+
1421
+ public function __get($name)
1422
+ {
1423
+ return isset($this->_data[$name]) ? $this->_data[$name] : null;
1424
+ }
1425
+
1426
+ public function set($name, $value)
1427
+ {
1428
+ $this->_data[$name] = $value;
1429
+ }
1430
  }
1431
 
1432
  class OS_Message
1433
  {
1434
+ public $type;
1435
+ public $message;
1436
+ public $args;
1437
+
1438
+ public function __construct($type, $args)
1439
+ {
1440
+ $this->type = $type;
1441
+ $this->message = array_shift($args);
1442
+ $this->args = $args;
1443
+ }
1444
+
1445
+ public function __toString()
1446
+ {
1447
+ return vsprintf($this->message, $this->args);
1448
+ }
1449
  }
1450
 
1451
  class OS_Result
1452
  {
1453
+ public $success;
1454
+ public $result;
1455
+
1456
+ public function __construct($success, $result=null)
1457
+ {
1458
+ $this->success = $success;
1459
+ $this->result = $result;
1460
+ }
1461
+
1462
+ public function __toString()
1463
+ {
1464
+ return OwebiaShippingHelper::toString($this->result);
1465
+ }
1466
  }
1467
 
app/code/community/Owebia/Shipping2/sql/owebia_shipping2_setup/mysql4-install-2.5.13.php CHANGED
@@ -9,4 +9,3 @@ $installer->run("UPDATE `{$this->getTable('core_config_data')}` SET `path` = REP
9
  $installer->run("UPDATE `{$this->getTable('core_config_data')}` SET `path` = REPLACE(`path`, 'owebia-shipping2/configurable-product/', 'owebia_shipping2/configurable_product/') WHERE `path` LIKE 'owebia-shipping2/configurable-product/%';");
10
  $installer->run("UPDATE `{$this->getTable('core_config_data')}` SET `path` = REPLACE(`path`, 'owebia-shipping2/', 'owebia_shipping2/') WHERE `path` LIKE 'owebia-shipping2/%';");
11
  $installer->endSetup();
12
-
9
  $installer->run("UPDATE `{$this->getTable('core_config_data')}` SET `path` = REPLACE(`path`, 'owebia-shipping2/configurable-product/', 'owebia_shipping2/configurable_product/') WHERE `path` LIKE 'owebia-shipping2/configurable-product/%';");
10
  $installer->run("UPDATE `{$this->getTable('core_config_data')}` SET `path` = REPLACE(`path`, 'owebia-shipping2/', 'owebia_shipping2/') WHERE `path` LIKE 'owebia-shipping2/%';");
11
  $installer->endSetup();
 
app/etc/modules/Owebia_Shipping2.xml CHANGED
@@ -15,16 +15,16 @@
15
  *
16
  * @category Owebia
17
  * @package Owebia_Shipping
18
- * @copyright Copyright (c) 2008-2013 Owebia (http://www.owebia.com)
19
  * @author Antoine Lemoine
20
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21
  */
22
  -->
23
  <config>
24
- <modules>
25
- <Owebia_Shipping2>
26
- <active>true</active>
27
- <codePool>community</codePool>
28
- </Owebia_Shipping2>
29
- </modules>
30
  </config>
15
  *
16
  * @category Owebia
17
  * @package Owebia_Shipping
18
+ * @copyright Copyright (c) 2008-14 Owebia (http://www.owebia.com)
19
  * @author Antoine Lemoine
20
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21
  */
22
  -->
23
  <config>
24
+ <modules>
25
+ <Owebia_Shipping2>
26
+ <active>true</active>
27
+ <codePool>community</codePool>
28
+ </Owebia_Shipping2>
29
+ </modules>
30
  </config>
app/locale/en_US/Owebia_Shipping2.csv CHANGED
@@ -1,219 +1,219 @@
1
  # en-US
2
 
3
  # app/code/community/Owebia/Shipping2/Block/Adminhtml/Os2/Editor.php
4
- "New shipping method","New shipping method"
5
- "Remove","Remove"
6
- "[meta] %s","[meta] %s"
7
- "[data] %s","[data] %s"
8
- # Tools
9
- "Insert","Insert"
10
- "Tools","Tools"
11
- "Shipping country","Shipping country"
12
- "Cart weight","Cart weight"
13
- "Products quantity","Products quantity"
14
- "Price incl. tax","Price incl. tax"
15
- "Price excl. tax","Price excl. tax"
16
- "Weight","Weight"
17
- "Tracking number","Tracking number"
18
- "Human readable version","Human readable version"
19
- # Fields
20
- "ID","ID"
21
- "Type","Type"
22
- "Shipping Method (default)","Shipping Method (default)"
23
- "Data","Data"
24
- "Meta","Meta"
25
- "About","About"
26
- "Enabled","Enabled"
27
- "Enabled (default)","Enabled (default)"
28
- "Disabled","Disabled"
29
- "Label","Label"
30
- "Description","Description"
31
- "Shipping address","Shipping address"
32
- "Billing address","Billing address"
33
- "Origin address","Origin address"
34
- "Conditions","Conditions"
35
- "Fees","Fees"
36
- "Customer groups","Customer groups"
37
- "Tracking url","Tracking url"
38
 
39
  # app/code/community/Owebia/Shipping2/Block/Adminhtml/Os2/Help.php
40
- "Refresh","Refresh"
41
- "Previous page","Previous page"
42
- "Summary","Summary"
43
 
44
  # app/code/community/Owebia/Shipping2/Block/Adminhtml/System/Config/Form/Field/Config.php
45
- "Help","Help"
46
- "Apply","Apply"
47
- "Cancel","Cancel"
48
- "Source &amp; Correction","Source &amp; Correction"
49
- "Download configuration templates","Download configuration templates (in French)"
50
- # JS
51
- "Dissociate","Dissociate"
52
- "Remove","Remove"
53
- "Edit","Edit"
54
- "Enter the new value:","Enter the new value:"
55
- "[No label]","[No label]"
56
- "Loading...","Loading..."
57
 
58
  # app/code/community/Owebia/Shipping2/Block/Adminhtml/System/Config/Form/Field/Config.php
59
- "Version: %s","Version: %s"
60
 
61
  # app/code/community/Owebia/Shipping2/Controller/Abstract.php
62
- "Owebia Shipping 2 Editor","Owebia Shipping 2 Editor"
63
- "Source &amp; Correction","Source &amp; Correction"
64
- "Help","Help"
65
- "Donate","Donate"
66
- "Close","Close"
67
 
68
  # app/code/community/Owebia/Shipping2/controllers/Adminhtml/Os2/AjaxController.php
69
- "Editor","Editor"
70
- "Source","Source"
71
- "Correction","Correction"
72
- "Debug","Debug"
73
- "Apply","Apply"
74
- "Export","Export"
75
- "Add a shipping method","Add a shipping method"
76
- "New shipping method","New shipping method"
77
- "You appreciate this extension and would like to help?","You appreciate this extension and would like to help?"
78
- "{os2editor.donate-page.content}","<p>The extension Owebia Shipping 2 is offered by the company Owebia (<a href=""http://www.owebia.com/"">http://www.owebia.com/</a>).<br/>If you want to support the developement of the extension, you can make a donation.</p><p>You will receive an invoice to keep trace of the donation.</p><p>Thanks to all donators.</p>"
79
 
80
  # app/code/community/Owebia/Shipping2/etc/system.xml
81
- "Configuration","Configuration"
82
- "Tracking URL","Tracking URL"
83
- "Debug","Debug"
84
- "{debug_help}","Debug displayed on cart while making a shipping estimation"
85
- "Compression","Compression"
86
- "{compression_help}","Gz + base64 compression. This is the editor that compress/uncompress."
87
- "Auto-escaping","Auto-escaping"
88
- "{auto_escaping_help}","Enable systematic auto-escaping of variables"
89
- "Auto-correction","Auto-correction"
90
- "{auto_correction_help}","This option enables backward compatibility but consommme resources"
91
- "Stop to first match","Stop to first match"
92
- "General Configuration","General Configuration"
93
- "Weight unit","Weight unit"
94
- "Bundle Product Management","Bundle Product Management"
95
- "Configurable Product Management","Configurable Product Management"
96
- "If ""Self"" is selected, options bellow are ignored","If ""Self"" is selected, options bellow are ignored"
97
- "Item processing","Item processing"
98
- "Item options on","Item options on"
99
- "Item data on","Item data on"
100
- "Product data on","Product data on"
101
 
102
  # app/code/community/Owebia/Shipping2/includes/OwebiaShippingHelper.php
103
- "Configuration disabled","Configuration disabled"
104
- "The cart doesn't match conditions","The cart doesn't match conditions"
105
- "Infinite loop %s","Infinite loop %s"
106
- "Error in table %s","Error in table %s"
107
- "Usage of deprecated syntax %s","Usage of deprecated syntax %s"
108
- "Usage of unknown properties %s","Usage of unknown properties %s"
109
- "Usage of deprecated properties %s","Usage of deprecated properties %s"
110
 
111
  # app/code/community/Owebia/Shipping2/Model/Carrier/Abstract.php
112
- "track the package","track the package"
113
 
114
  # app/code/community/Owebia/Shipping2/Model/Os2/Data/AddressFilter.php
115
- "Africa","Africa"
116
- "Asia","Asia"
117
- "Europa","Europa"
118
- "North America","North America"
119
- "South America","South America"
120
- "Oceania","Oceania"
121
- "Antartica","Antartica"
122
- "European Union","European Union"
123
 
124
  # app/code/community/Owebia/Shipping2/Model/System/Config/Source/LoadOnParent.php
125
- "Self","Self"
126
- "Parent","Parent"
127
 
128
  # Help
129
- "{os2editor.help.summary}","
130
  <h4>Summary</h4>
131
  <div class=""table-of-contents"">
132
  <table><tr>
133
- <td>
134
- <ol class=level1>
135
- <li class=new><a href=""#introduction"">Introduction: JSON syntax, items and properties</a></li>
136
- <li><a href=""#unique_id"">The unique identifier</a></li>
137
- <li class=new>The item types:
138
- <ul>
139
- <li><a href=""#type_method""><property>method</property>: shipping method</a></li>
140
- <li><a href=""#type_data""><property>data</property>: data</a></li>
141
- <li><a href=""#type_meta""><property>meta</property>: meta data</a></li>
142
- </ul>
143
- </li>
144
- <li class=new>Common properties:
145
- <ul>
146
- <li><a href=""#property_type""><property>type</property>: the type of the item</a></li>
147
- <li><a href=""#property_about""><property>about</property>: comment on the item</a></li>
148
- </ul>
149
- </li>
150
- <li>Properties of <property>method</property> items:
151
- <ul>
152
- <li class=important><a href=""#property_label""><property>label</property></a></li>
153
- <li><a href=""#property_description""><property>description</property></a></li>
154
- <li class=important><a href=""#property_conditions""><property>conditions</property></a></li>
155
- <li class=new><a href=""#property_shipto""><property>shipto</property>: the shipping address</a> (<property>destination</property> bef. 2.4.8)</li>
156
- <li class=new><a href=""#property_shipto""><property>billto</property>: the billing address</a> (since 2.4.8)</li>
157
- <li><a href=""#property_shipto""><property>origin</property>: the origin address</a></li>
158
- <li><a href=""#property_customer_groups""><property>customer_groups</property></a></li>
159
- <li class=important><a href=""#property_fees""><property>fees</property>: the shipping fees</a></li>
160
- <li><a href=""#property_tracking_url""><property>tracking_url</property></a></li>
161
- <li><a href=""#property_enabled""><property>enabled</property></a></li>
162
- </ul>
163
- </li>
164
- </ol>
165
- </td>
166
- <td>
167
- <ol class=level1 start=6>
168
- <li><a href=""#more_formulas"">Introduction to Formulas</a>
169
- <ol>
170
- <li class=new><a href=""#more_vars"">Available variables</a></li>
171
- <li class=new><a href=""#more_special-functions"">Special Functions in Formulas</a> (update 2.5)<br/>&nbsp; &nbsp; min, max, range, substr, in_array, array_match_any, array_match_all</li>
172
- <li><a href=""#more_copy"">Make a copy of a property from an other item</a></li>
173
- <li><a href=""#more_tables"">Using <c>table</c></a></li>
174
- <li><a href=""#more_switch"">Using <c>switch</c></a> (update 2.4.5)</li>
175
- <li class=new><a href=""#more_attributes-options"">Using product properties (sum, count, min, max)</a> (update 2.4.8)</li>
176
- <li><a href=""#more_foreach"">Using <c>foreach</c> loops</a></li>
177
- <li class=new><a href=""#more_categories"">Particular case: examples of use of product categories</a> (update 2.5)</li>
178
- </ol>
179
- </li>
180
- <li><a href=""#changelog"">Changelog</a></li>
181
- </ol>
182
- </td>
183
  </tr></table>
184
  </div>
185
  "
186
- "{os2editor.help.introduction}","
187
  <h4>Introduction: JSON syntax, items and properties</h4>
188
  <p class=new>
189
- If you have a question, use the following topic: <a href=""http://www.magentocommerce.com/boards/viewthread/38223/"" target=_blank>http://www.magentocommerce.com/boards/viewthread/38223/</a>
190
  </p>
191
 
192
  <p>
193
- <span class=new>Since version 2.5, the syntax of configuration is full JSON <a href=""http://en.wikipedia.org/wiki/JavaScript_Object_Notation"" target=_blank>JSON</a>.</span>
194
  </p>
195
  <p>
196
- Example:
197
  </p>
198
  {code=json}{
199
  ""ex0"":{""about"":""National"",""label"":""National"",""shipto"":""AD,FR,MC"",""conditions"":""{cart.price-tax+discount}<1000.00"",""fees"":""1.30 + {table {cart.weight} in 0.5:5.30, 1.0:6.50, 2.0:7.40, 3.0:8.30, 5.0:10.10}""}
200
  }{/code}
201
 
202
  <p>
203
- The configuration is a JSON object containing <strong>properties</strong>.<br/>
204
- Each property has a unique name, wich will serve as <a href=""#unique_id"">unique identifier</a>.<br/>
205
- Each property will consiste on a configuration <strong>item</strong> (also a JSON object).<br/>
206
  </p>
207
  <p>
208
- Items have always a <property>type</property> property. This sets the type of the item:
209
  </p>
210
  <ul>
211
- <li><a href=""#type_method""><property>method</property>: shipping method (default if not specified)</a></li>
212
- <li><a href=""#type_data""><property>data</property>: data that can be used in shipping methods</a></li>
213
- <li><a href=""#type_meta""><property>meta</property>: informative data</a></li>
214
  </p>
215
  "
216
- "{os2editor.help.unique_id}","
217
  <h4>The unique identifier</h4>
218
  <p>Each configuration item has a unique identifier. This unique identifier is then used to reference the item.</p>
219
  <p>Example:</p>
@@ -224,7 +224,7 @@
224
 
225
  <p class=warning><strong><u>Warning</u>:</strong> to avoid conflicts, use only the following characters <c>a-z</c>, <c>A-Z</c>, <c>0-9</c>, <c>-</c> and <c>_</c> to make the unique identifier.<br/>You have also to avoid identifiers that match to any variable name (<c>cart</c>, <c>product</c>, <c>item</c>…).</p>
226
  "
227
- "{os2editor.help.type_method}","
228
  <h4><property>method</property> item</h4>
229
  <p>A <property>method</property> item allow to specify a shipping method.</p>
230
  <p>Example with only required properties:</p>
@@ -236,7 +236,7 @@
236
  ""ex0"":{""about"":""Colissimo National"",""type"":""method"",""label"":""Colissimo"",""description"":""Delivery within 24/48h"",""enabled"":true,""conditions"":""range({cart.weight},0.2,1.0)"",""shipto"":""FR(01,02,39600,/^25[0-9]{3}$/),CH,DE"",""billto"":""FR"",""origin"":""DE"",""customer_groups"":""NOT LOGGED IN,Retailer"",""fees"":""{table {cart.weight} in 0.5:5.30, 1.0:6.50}""}
237
  }{/code}
238
  "
239
- "{os2editor.help.type_data}","
240
  <h4><property>data</property> item</h4>
241
  <p>A <property>data</property> item allow to specify data that can be used in shipping methods.</p>
242
  <p>Example of <property>data</property> item:</p>
@@ -248,7 +248,7 @@
248
  ""ex0"":{""type"":""method"",""label"":""Colissimo"",""fees"":""{mydata.reference}*1.5""}
249
  }{/code}
250
  "
251
- "{os2editor.help.type_meta}","
252
  <h4><property>meta</property> item</h4>
253
  <p>A <property>meta</property> item allow to add informative data (author, date…).</p>
254
  <p>Example:</p>
@@ -256,13 +256,13 @@
256
  ""about"":{""type"":""meta"",""author"":""Owebia"",""date"":""16/11/2012"",""about"":""Prices 2012""}
257
  }{/code}
258
  "
259
- "{os2editor.help.property_type}","
260
  <h4><property>type</property>: the type of the item</h4>
261
  <p>This sets the type of the item:</p>
262
  <ul>
263
- <li><a href=""#type_method""><property>method</property>: shipping method (default if not specified)</a></li>
264
- <li><a href=""#type_data""><property>data</property>: data that can be used in shipping methods</a></li>
265
- <li><a href=""#type_meta""><property>meta</property>: informative data</a></li>
266
  </p>
267
  {code=json}{
268
  ""about"":{""type"":""meta"",""author"":""Owebia"",""date"":""16/11/2012"",""about"":""Prices 2012""},
@@ -270,44 +270,44 @@
270
  ""ex0"":{""type"":""method"",""label"":""Colissimo"",""fees"":""{mydata.reference}*1.5""}
271
  }{/code}
272
  "
273
- "{os2editor.help.property_about}","
274
  <h4><property>about</property>: comment on the item</h4>
275
  <p>You can add a comment to a configuration item.</p>
276
  {code=json}{""ex0"":{""about"":""My comment"",""label"":""Example with a comment"",""fees"":10}}{/code}
277
  "
278
- "{os2editor.help.property_label}","
279
  <h4>The <property>label</property></h4>
280
  <p>The name given to the shipping method.</p>
281
  <p>We can insert some data like the package weight in the label.<br/>
282
  To do that, use the following variables:</p>
283
  <ul>
284
- <li>The shipping address:
285
- <ul>
286
- <li class=new><c><strike>{destination.country.name}</strike> {shipto.country_name}</c></li>
287
- <li class=new><c><strike>{destination.country.code}</strike> {shipto.country_id}</c></li>
288
- <li class=new><c><strike>{destination.region.code}</strike> {shipto.region_code}</c></li>
289
- <li class=new><c><strike>{destination.postcode}</strike> {shipto.postcode}</c></li>
290
- </ul>
291
- </li>
292
- <li><c>{cart.weight}</c>: the package weight</li>
293
- <li class=new><c><strike>{cart.weight.unit}</strike> {cart.weight_unit}</c>: the weight unit</li>
294
- <li><a href=""#more_vars"">See the full list of variables</a></li>
295
  </ul>
296
  {code=json}{
297
  ""ex0"":{""label"":""Colissimo ({cart.weight} / {shipto.country_name})"",""fees"":10}
298
  }{/code}
299
  <p>The above line will display for example <string>""Colissimo (3.0kg / France)""</string>.</p>
300
  "
301
- "{os2editor.help.property_description}","
302
  <h4>The <property>description</property></h4>
303
  <p>The description of the shipping method.</p>
304
  <p>The usage is the same as <a href=""#property_label""><property>label</property></a> property.</p>
305
  "
306
- "{os2editor.help.property_conditions}","
307
  <h4><property>conditions</property></h4>
308
  <p>
309
- <property>conditions</property> property is specified as a <a href=""#more_formulas"">formula (see introduction to formulas)</a>
310
- that must return a boolean value (<c>true</c> or <c>false</c>).
311
  </p>
312
 
313
  {code=json}{
@@ -323,24 +323,24 @@ To do that, use the following variables:</p>
323
  ""ex9"":{""label"":""If all products have 'size' option greater or equal to '1'"",""conditions"":""{count items where product.option.size>='1'}=={cart.qty}"",""fees"":10}
324
  }{/code}
325
  "
326
- "{os2editor.help.property_shipto}","
327
  <h4>Addresses: <property>shipto</property>, <property>billto</property> and <property>origin</property></h4>
328
  <p>
329
- The extension allow to filter addresses:
330
  </p>
331
  <ul>
332
- <li class=new>The shipping address <strike><property>destination</property></strike> <property>shipto</property>.</li>
333
- <li class=new>The billing address <property>billto</property></li>
334
- <li>The origin address <property>origin</property></li>
335
  </ul>
336
  <p>
337
- Country codes used are those used by Magento.<br/>
338
- It's possible to specify region codes (only with <property>shipto</property>) or postcodes.
339
  </p>
340
  <p class=new>
341
- You can use the wildcard character <c>*</c> or regular expressions to filter postcodes.<br/>
342
- A regular expression must start and end width the character <c>/</c>. If you want to use characters <c>(</c>, <c>)</c> or <c>,</c>, you have to escape them with character <c>\</c> (ex: <string>""FR(/^25\([0-9]{3}\)$/)""</string>).<br/>
343
- You can use the case insensitive modifier (ex: <string>""GB(/^PO.*$/i)""</string>).
344
  </p>
345
 
346
  {code=json}{
@@ -353,34 +353,34 @@ To do that, use the following variables:</p>
353
  }{/code}
354
 
355
  <div class=""tips"">
356
- <p><strong>Tip</strong><br/>To shorten the seizure of countries, you can use the following variables:</p>
357
- <ul>
358
- <li><c>{address_filter.AF}</c>: countries of Africa</li>
359
- <li><c>{address_filter.AS}</c>: countries of Asia</li>
360
- <li><c>{address_filter.EU}</c>: countries of Europa</li>
361
- <li><c>{address_filter.NA}</c>: countries of North America</li>
362
- <li><c>{address_filter.SA}</c>: countries of South America</li>
363
- <li><c>{address_filter.OC}</c>: countries of Oceania</li>
364
- <li><c>{address_filter.AN}</c>: countries of Antartica</li>
365
- <li><c>{address_filter.EU-27}</c>: countries of the European Union</li>
366
- <li><c>{address_filter.DOM}</c>: country codes of overseas french department</li>
367
- <li><c>{address_filter.COM}</c>: country codes of overseas french communities</li>
368
- </ul>
369
  </div>
370
 
371
  {code=json}{
372
  ""ex0"":{""label"":""Europa except France"",""shipto"":""({address_filter.EU-27}) - (FR)"",""fees"":10}
373
  }{/code}
374
  "
375
- "{os2editor.help.property_billto}","
376
  <h4><property>billto</property>: the billing address</h4>
377
  <p><a href=""#property_shipto"">Filtering addresses</a></p>
378
  "
379
- "{os2editor.help.property_origin}","
380
  <h4><property>origin</property>: the origin address</h4>
381
  <p><a href=""#property_shipto"">Filtering addresses</a></p>
382
  "
383
- "{os2editor.help.property_customer_groups}","
384
  <h4><property>customer_groups</property></h4>
385
  <p>We can use the name or the ID of customer groups.</p>
386
 
@@ -390,10 +390,10 @@ To do that, use the following variables:</p>
390
  ""ex2"":{""label"":""Retailer group"",""customer_groups"":""Retailer"",""fees"":10}
391
  }{/code}
392
  "
393
- "{os2editor.help.property_fees}","
394
  <h4><property>fees</property>: the shipping fees</h4>
395
  <p>
396
- <property>fees</property> property is specified as a <a href=""#more_formulas"">formula (see introduction to formulas)</a>.
397
  </p>
398
  {code=json}{
399
  ""ex0"":{""label"":""Fixed fees"",""fees"":10},
@@ -402,16 +402,16 @@ To do that, use the following variables:</p>
402
  ""ex3"":{""label"":""Combination"",""fees"":""0.1 * {cart.price-tax+discount} + {table {cart.weight} in 0.5:5.30, 1.0:6.50} + 10.00""}
403
  }{/code}
404
  "
405
- "{os2editor.help.property_tracking_url}","
406
  <h4><property>tracking_url</property></h4>
407
  <p class=warning>
408
- <strong>The use of <property>tracking_url</property> property is reserved for experienced users. If you don't understand the instructions below, it is recommended that you avoid using this feature.</strong>
409
  </p>
410
  <p>
411
- The <property>tracking_url</property> property overrides the field ""Tracking URL"" of an Owebia Shipping shipping mode. So you can specify a tracking URL <strong>foreach shipping method</strong> rather than one for all shipping mode.
412
  </p>
413
  <p>
414
- To automatically insert the tracking number in the tracking URL, you must use <c>{tracking_number}</c>.
415
  </p>
416
 
417
  {code=json}{
@@ -419,21 +419,21 @@ To do that, use the following variables:</p>
419
  }{/code}
420
 
421
  <p>
422
- Magento does not support tracking links but tracking statuses. The extension Owebia Shipping 2 provides an HTML link instead of the status, link allowing you to go on the carrier's website and follow the progress of the parcel.
423
  </p>
424
  <p>
425
- When the tracking URL is built by the extension, the only information available is the tracking number and there was nowhere an access to the shipping method selected. In order to find the tracking URL in the configuration, you must specify the shipping method inside the tracking number, for example: <c>colissimo:8Lxxxxxxxxxxx</c> where <c>colissimo</c> is the code of the shipping method selected.<br/>
426
- If no code is specified (if you enter only the tracking number), the URL used will be the one of the shipping mode.
427
  </p>
428
  <p class=warning>
429
- To answer a recurrent question, Magento displays the tracking status from the back office or front office. <strong>If you want to insert the tracking URL in shipping mails, you need to develop yourself the retrieval of tracking URL and its incorporation in the mail, in fact, the Owebia Shipping extension simply provides customizable shipping methods without making big changes to Magento core to reduce incompatibility and update problems.</strong>
430
  </p>
431
  <p class=warning>
432
- If you get a blank popup when you click on the tracking link, your problem is most likely related to the fact that you did not specify the code of the shipping method in the tracking number (see instructions above) and your global field ""Tracking URL"" is empty.
433
  </p>
434
  <p class=warning>There are currently no plans to change this feature.</p>
435
  "
436
- "{os2editor.help.property_enabled}","
437
  <h4><property>enabled</property></h4>
438
  <p>Allow to activate or desactivate the shipping method.</p>
439
  <p>The value must be boolean.</p>
@@ -441,173 +441,173 @@ To do that, use the following variables:</p>
441
  ""ex0"":{""enabled"":true,""label"":""Example with activation"",""fees"":10}
442
  }{/code}
443
  "
444
- "{os2editor.help.more_formulas}","
445
  <h4>Introduction to formulas</h4>
446
  <p>
447
- Properties <property>fees</property> and <property>conditions</property> are specified as formulas.
448
  </p>
449
  <p>
450
- Mathematical signs available:
451
  </p>
452
  <ul>
453
- <li>operators: <c>*</c>, <c>/, <c>+</c> and <c>-</c></li>
454
- <li>modulo: <c>%</c></li>
455
- <li>brackets: <c>(</c> et <c>)</c></li>
456
- <li>boolean operators <c>&amp;&amp;</c>, <c>and</c>, <c>||</c>, <c>or</c>, <c>==</c>, <c>&lt;</c>, <c>&gt;</c>, <c>&lt;=</c>, <c>&gt;=</c></li>
457
- <li>binary operators <c>&amp;</c> and <c>|</c></li>
458
- <li>operators group <c>C ? X : Y</c> (ex: <c><span class=string>""{cart.price_exluding_tax}&gt;100 ? 15*{cart.weight} : 20*{cart.weight}""</span></c>)</li>
459
  </ul>
460
  <p>
461
- Variables available:
462
  </p>
463
  <ul>
464
 
465
- <li><c>{cart.weight}</c>: full package weight</li>
466
- <li><c>{cart.qty}</c>: items count in cart</li>
467
- <li><c>{cart.price-tax+discount}</c>: price excluding tax after discount</li>
468
- <li><c>{cart.price+tax+discount}</c>: price including tax after discount</li>
469
- <li><c>{cart.price-tax-discount}</c>: price excluding tax before discount</li>
470
- <li><c>{cart.price+tax-discount}</c>: price including tax before discount</li>
471
- <li><a href=""#more_vars"">See full list of variables</a></li>
472
  </ul>
473
  <p>
474
- You can put spaces and line returns in formulas (to air).
475
  </p>
476
  <p>
477
- Functions available:
478
  </p>
479
  <ul>
480
- <li>rounds: <c>round(x)</c>, <c>floor(x)</c>, <c>ceil(x)</c></li>
481
- <li>absolute value: <c>abs(x)</c></li>
482
- <li>maximum: <c>max(x,y)</c></li>
483
- <li>minimum: <c>min(x,y)</c></li>
484
- <li>random integer: <c>rand(min,max)</c></li>
485
- <li>power: <c>pow(x,puissance)</c></li>
486
- <li>PI number: <c>pi()</c></li>
487
- <li>square root: <c>sqrt(x)</c></li>
488
- <li>logarithm: <c>log(x)</c> for the natural logarithm or <c>log(x,base)</c></li>
489
- <li>exponential: <c>exp(x)</c></li>
490
  </ul>
491
  <p>
492
- Ability to use advanced features like: casting to integer <c>(int)</c> casting to floating number <c>(float)</c>, comparison with <c>null</c> or boolean values <c>true</c> and <c>false</c>.
493
  </p>
494
  <p class=""new"" style=""font-weight: bold;"">
495
- You can also use advanced features such as rates tables, copy of a property of another method,
496
- special functions, usage of product's attributes and options or usage of custom variables.
497
  </p>
498
  <p class=new style=""font-weight: bold;"">
499
- When you use alphanumeric variables, you can escape them with quotes or you can use the autoescape syntax <c>{{ }}</c>.
500
  </p>
501
  {code=json}{
502
  ""ex0"":{""label"":""Escaping with quotes"",""conditions"":""'{cart.coupon_code}'=='test'"",""fees"":10},
503
  ""ex1"":{""about"":""Since version 2.4.5, {{cart.coupon_code}} will be replaced by 'moncoupon' or by null depending on its value"",""label"":""Auto-escaping"",""conditions"":""{{cart.coupon_code}}!='test'"",""fees"":10}
504
  }{/code}
505
  "
506
- "{os2editor.help.more_vars}","
507
  <h4>Variables available</h4>
508
  <p>
509
- The following variables can be used in different properties of shipping methods (in particular in properties <property>conditions</property> and <property>fees</property>).
510
  </p>
511
  <ul>
512
- <li>The cart:
513
- <ul>
514
- <li><c>{cart.weight}</c>: package weight</li>
515
- <li><c class=new><strike>{cart.quantity}</strike> {cart.qty}</c>: items quantity</li>
516
- <li class=new><c><strike>{cart.price_excluding_tax}</strike> {cart.price-tax+discount}</c>: price excl. tax after discount</li>
517
- <li class=new><c><strike>{cart.price_including_tax}</strike> {cart.price+tax+discount}</c>: price incl. tax after discount</li>
518
- <li class=new><c>{cart.price-tax-discount}</c>: price excl. tax before discount</li>
519
- <li class=new><c>{cart.price+tax-discount}</c>: price incl. tax before discount</li>
520
- <li class=new><c><strike>{cart.coupon}</strike> {cart.coupon_code}</c></li>
521
- <li><c class=new><strike>{free_shipping}</strike> {cart.free_shipping}</c>: shipping offered (by a rule in Magento) [true/false]</li>
522
- <li><c class=new><strike>{cart.weight.unit}</strike> {cart.weight_unit}</c></li>
523
- <li><c class=new><strike>{cart.weight.for-charge}</strike> {cart.weight_for_charge}</c>: weight of goods whose delivery is not offered (by a cart price rule in Magento)</li>
524
- </ul>
525
- </li>
526
- <li class=new>The customer group:
527
- <ul>
528
- <li><c><strike>{customer.group.id}</strike> {customer_group.id}</c></li>
529
- <li><c><strike>{customer.group.code}</strike> {customer_group.code}</c>: name of customer group</li>
530
- <li><c>{customer_group.*}</c>: property of customer group (ex: <c>{customer_group.tax_class_id}</c>)</li>
531
- </ul>
532
- </li>
533
- <li class=new>The customer:
534
- <ul>
535
- <li><c>{customer.id}</c></li>
536
- <li><c>{customer.attribute.*}</c>: attribute of the customer (ex: lastname, firstname, group_id…)</li>
537
- <li class=new><c>{customer.attribute.*.value}</c>: in case of attributes of type dropdown, <c>{customer.attribute.*}</c> returns the id, to get the value you must use <c>{customer.attribute.*.value}</c></li>
538
- <li><c>{customer.*}</c>: same as <c>{customer.attribute.*}</c> if the variable isn't defined (ex: <c>{customer.id}</c> is already defined)</li>
539
- </ul>
540
- </li>
541
- <li class=new>Custom Variables (since version 1.4.0.1 of Magento):
542
- <ul>
543
- <li><c>{customvar.*}</c>: Magento custom variable (ex: <c>{customvar.my_var}</c>)</li>
544
- <li><c><strike>{{customVar code=*}}</strike></c>: use the syntax above</li>
545
- </ul>
546
- </li>
547
- <li>The shipping address:
548
- <ul>
549
- <li><c class=new><strike>{destination.country.name}</strike> {shipto.country_name}</c></li>
550
- <li><c class=new><strike>{destination.country.code}</strike> {shipto.country_id}</c>: the country code</li>
551
- <li class=new><c>{shipto.region_id}</c></li>
552
- <li><c class=new><strike>{destination.region.code}</strike> {shipto.region_code}</c></li>
553
- <li class=new><c>{shipto.street}</c></li>
554
- <li class=new><c>{shipto.city}</c></li>
555
- <li><c class=new><strike>{destination.postcode}</strike> {shipto.postcode}</c></li>
556
- </ul>
557
- </li>
558
- <li class=new>The billing address:
559
- <ul>
560
- <li><c>{billto.country_name}</c></li>
561
- <li><c>{billto.country_id}</c>: the country code</li>
562
- <li><c>{billto.postcode}</c></li>
563
- <li><c>{billto.*}</c>: property of the billing address (ex: <c>{billto.city}</c>)</li>
564
- </ul>
565
- </li>
566
- <li>The origin address:
567
- <ul>
568
- <li><c class=new><strike>{origin.country.name}</strike> {origin.country_name}</c></li>
569
- <li><c class=new><strike>{origin.country.code}</strike> {origin.country_id}</c>: the country code</li>
570
- <li><c class=new><strike>{origin.region.code}</strike> {origin.region_id}</c></li>
571
- <li class=new><c>{origin.city}</c></li>
572
- <li><c>{origin.postcode}</c></li>
573
- </ul>
574
- </li>
575
- <li>The store:
576
- <ul>
577
- <li><c>{store.id}</c> <c>{store.code}</c> <c>{store.name}</c> <c>{store.address}</c> <c>{store.phone}</c>: id, code, name, address and phone number of the store</li>
578
- </ul>
579
- </li>
580
- <li>The current date:
581
- <ul>
582
- <li><c>{date.timestamp}</c>: UNIX timestamp of current date</li>
583
- <li><c>{date.year}</c> <c>{date.month}</c> <c>{date.day}</c> <c>{date.hour}</c> <c>{date.minute}</c></li>
584
- <li><c>{date.weekday}</c>: weekday for current date from 0 (Sunday) to 6 (Saturday)</li>
585
- </ul>
586
- </li>
587
- <li class=new>The <c>request</c> object:
588
- <ul>
589
- <li><c>{request.*}</c>: property of the request object (Mage_Shipping_Model_Rate_Request) parameter given by Magento (ex: <c>{request.package_qty}</c>). Use the ""Debug"" option to have more details on available properties.</li>
590
- </ul>
591
- </li>
592
  </ul>
593
  "
594
- "{os2editor.help.more_special-functions}","
595
  <h4>Special functions in formulas</h4>
596
 
597
  <p>
598
- You can use special functions in formulas.
599
  </p>
600
  <p>
601
- List of special functions:
602
  </p>
603
  <ul>
604
- <li><c>min(x, y, …)</c> : calculate the minimum of several values (possibly more than two values). If one value is null, it is ignored.</li>
605
- <li><c>max(x, y, …)</c> : calculate the maximum of several values (possibly more than two values). If one value is null, it is ignored.</li>
606
- <li class=new><c>range(value, min, max, include_min, include_max)</c> : returns <c>true</c> if <c>value</c> is between <c>min</c> and <c>max</c>. By default, <c>include_min</c> and <c>include_max</c> are set to <c>true</c>.</li>
607
- <li class=new><c>substr(string, start, length)</c> : returns a segment of a string.</li>
608
- <li class=new><c>in_array(value, array(value1, value2, …))</c> : returns true if the value is in the array.</li>
609
- <li class=new><c>array_match_any(array(value1, value2, …), array(value1, value2, …))</c> : returns true if any value is in both arrays.</li>
610
- <li class=new><c>array_match_all(array(value1, value2, …), array(value1, value2, …))</c> : returns true if both arrays have the same values.</li>
611
  </ul>
612
 
613
  {code=json}{
@@ -621,10 +621,10 @@ To do that, use the following variables:</p>
621
  }{/code}
622
 
623
  <p class=new>
624
- * About strings escaping, refer to the <a href=""#more_formulas"">introduction to formulas</a>.
625
  </p>
626
  "
627
- "{os2editor.help.more_copy}","
628
  <h4>Make a copy of a property of another method</h4>
629
  <p>It is possible to make a copy of a property in another using the syntax below.</p>
630
  <p>You can use this technique in all properties (<property>conditions</property>, <property>fees</property>, …).</p>
@@ -635,10 +635,10 @@ To do that, use the following variables:</p>
635
  ""ex2"":{""label"":""Copy of fees from another method"",""fees"":""({colissimo.fees}) + 15.00""}
636
  }{/code}
637
  "
638
- "{os2editor.help.more_tables}","
639
  <h4>Using <c>table</c></h4>
640
  <p>
641
- In a <c>table</c>, you can include or exclude a limit value with characters <c>[</c> et <c>]</c>:
642
  </p>
643
  {code=json}{
644
  ""f0"":{""label"":""Upper limit included"",""fees"":""{table {cart.weight} in 1.0]:5.00}""},
@@ -646,8 +646,8 @@ To do that, use the following variables:</p>
646
  }{/code}
647
 
648
  <p>
649
- In a <c>table</c>, you must specify the reference value. For this, we can use one of the <a href=""#more_vars"">available variables</a>.<br/>
650
- You can also use a formula to define another reference variable.
651
  </p>
652
 
653
  {code=json}{
@@ -658,12 +658,12 @@ To do that, use the following variables:</p>
658
  ""ex4"":{""label"":""Table with user defined value"",""fees"":""{table ceil({cart.weight}/10) in 1:5.30, 2:6.50}""}
659
  }{/code}
660
  "
661
- "{os2editor.help.more_switch}","
662
  <h4>Using <c>switch</c></h4>
663
 
664
  <p>
665
- In a <c>switch</c>, you must specify the reference value. For this, we can use one of the <a href=""#more_vars"">available variables</a>.<br/>
666
- You can also use a formula to define another reference variable.
667
  </p>
668
 
669
  {code=json}{
@@ -671,81 +671,81 @@ To do that, use the following variables:</p>
671
  ""ex1"":{""label"":""Switch with shipping country"",""fees"":""{switch {{shipto.country_id}} in 'FR':5.30, 'BE':6.50, 'DE':10.00, *:7.50}""}
672
  }{/code}
673
  "
674
- "{os2editor.help.more_attributes-options}","
675
  <h4>Using product properties</h4>
676
 
677
  <p class=new>
678
- In order to match to Magento Models, the version 2.4.8 of the extension adds a separation between <c>item</c> and <c>product</c>.
679
- An <c>item</c> is a <c>product</c> variation with some options. Each <c>item</c> has a quantity.
680
  </p>
681
  <p>
682
- List of available properties:
683
  </p>
684
  <ul>
685
- <li class=new>The <c>item</c>:
686
- <ul>
687
- <li><c>item.qty</c>: the quantity in cart</li>
688
- <li><c>item.price-tax+discount</c>: the price excl. tax after discount</li>
689
- <li><c>item.price-tax-discount</c>: the price excl. tax before discount</li>
690
- <li><c>item.price+tax+discount</c>: the price incl. tax after discount</li>
691
- <li><c>item.price+tax-discount</c>: the price incl. tax before discount</li>
692
- <li><c>item.option.*</c>: option (depends on product)</li>
693
- </ul>
694
- </li>
695
- <li>The <c>product</c>:
696
- <ul>
697
- <li><c><strike>product.quantity</strike></c>: use <c class=new>item.qty</c></li>
698
- <li><c>product.attribute.*</c>: attribute<br/>List of interesting attributes:
699
- <ul>
700
- <li><c>sku</c></li>
701
- <li><c>name</c></li>
702
- <li><c>weight</c></li>
703
- <li><c>price</c> (as defined in product)</li>
704
- <li><c>special_price</c> (as defined in product)</li>
705
- <li><c><strike>price-tax+discount</strike></c>: use <c class=new>item.price-tax+discount</c></li>
706
- <li><c><strike>price-tax-discount</strike></c>: use <c class=new>item.price-tax-discount</c></li>
707
- <li><c><strike>price+tax+discount</strike></c>: use <c class=new>item.price+tax+discount</c></li>
708
- <li><c><strike>price+tax-discount</strike></c>: use <c class=new>item.price+tax-discount</c></li>
709
- </ul>
710
- </li>
711
- <li class=new><c>product.attribute.*.value</c>: value of the attribute<br/>In case of attributes of type dropdown, <c>product.attribute.*</c> returns the id. To get the value, you must use <c>product.attribute.*.value</c></li>
712
- <li class=new><c>product.*</c>: same as <c>product.attribute.*</c> if variable is not defined (ex: <c>product.category</c> is defined)</li>
713
- <li><c><strike>product.option.*</strike></c>: use <c class=new>item.option.*</c></li>
714
- <li>First category of the product:
715
- <ul>
716
- <li><c>product.category</c>: name of the category</li>
717
- <li><c>product.category.id</c></li>
718
- <li class=new><c>product.category.*</c>: attribute of the category (ex: <c>product.category.is_active</c>)<br/>List of interesting attributes:
719
- <ul>
720
- <li><c>is_active</c></li>
721
- <li><c>name</c></li>
722
- <li>…</li>
723
- </ul>
724
- </li>
725
- </ul>
726
- </li>
727
- <li>All categories of the product (returns an array, <a href=""#more_categories"">explanation section</a>) :
728
- <ul>
729
- <li><c>product.categories</c>: array of categories names</li>
730
- <li><c>product.categories.id</c>: array of categories ids</li>
731
- </ul>
732
- </li>
733
- <li>Attribute set of the product:
734
- <ul>
735
- <li><c>product.attribute_set</c>: name of attribute set</li>
736
- <li><c>product.attribute_set.id</c></li>
737
- <li class=new><c>product.attribute_set.*</c>: attribute of attribute set (ex: <c>product.attribute_set.attribute_set_name</c>)</li>
738
- </ul>
739
- </li>
740
- <li class=new><c>product.stock.*</c>: attribute of product stock<br/>List of interesting attributes:
741
- <ul>
742
- <li><c>is_in_stock</c></li>
743
- <li><c>qty</c>: product stock</li>
744
- <li>…</li>
745
- </ul>
746
- </li>
747
- </ul>
748
- </li>
749
  </ul>
750
 
751
  {code=json}{
@@ -763,17 +763,17 @@ To do that, use the following variables:</p>
763
  Available prefixes list:
764
  </p>
765
  <ul>
766
- <li><c>count</c>: count (always followed by <c>items</c>)</li>
767
- <li><c>count distinct</c> : distinct count (always followed by a property)</li>
768
- <li><c>sum</c> : sum (always followed by a property)</li>
769
- <li class=new><c>min</c> : minimum (always followed by a property)</li>
770
- <li class=new><c>max</c> : maximum (always followed by a property)</li>
771
  </ul>
772
  <p>
773
- It's possible to specify conditions that must be met by products to be taken into account. To do this, simply add <c> where </c> followed by a formula.
774
  </p>
775
  <p>
776
- If the property type is <strong>Yes/No</strong>, you should use <c>true</c>/<c>false</c> or <c>1</c>/<c>0</c> without quotes.
777
  </p>
778
  {code=json}{
779
  ""ex0"":{""label"":""Example property of type Yes/No: 0"",""conditions"":""{count items where product.attribute.colissimo_allowed==0}"",""fees"":10},
@@ -781,7 +781,7 @@ Available prefixes list:
781
  }{/code}
782
 
783
  <p>
784
- If the property type is <strong>Drop-down</strong> and you want to make a comparison with the value rather than with the id, you must use the following syntax:
785
  </p>
786
  <strike>{code=json}{
787
  ""ex0"":{""label"":""If the color attribute's id is different to 1"",""conditions"":""{count items where product.color.id!=1}"",""fees"":10}
@@ -790,27 +790,27 @@ Available prefixes list:
790
  ""ex0"":{""label"":""If the value of color attribute is different to 'Bleu'"",""conditions"":""{count items where product.color.value!='Bleu'}"",""fees"":10}
791
  }{/code}
792
  "
793
- "{os2editor.help.more_foreach}","
794
  <h4>Using <c>foreach</c> loops</h4>
795
 
796
  <p>
797
- <c>foreach</c> loops can perform calculations on groups of products rather than consider all the products in the basket.<br/>
798
- The overall result of a <c>foreach</c> loop is the sum of the results of each pass through the loop.
799
  </p>
800
  <p>
801
- Inside a <c>foreach</c> loop, it is possible to use new variables:
802
  </p>
803
  <ul>
804
- <li><c>{selection.weight}</c></li>
805
- <li><c class=new><strike>{selection.quantity}</strike> {selection.qty}</c>: items count in the selection</li>
806
  </ul>
807
  <p>
808
- When the selection is done on the sku, each selection is composed of a single article. We can use other variables:
809
  </p>
810
  <ul>
811
- <li><c>{item.*}</c></li>
812
- <li><c>{product.*}</c></li>
813
- <li><a href=""#more_attributes-options"">See the full list of products properties</a></li>
814
  </ul>
815
 
816
  {code=json}{
@@ -818,20 +818,20 @@ Available prefixes list:
818
  ""ex1"":{""label"":""Individual calculation of shipping fees"",""fees"":""{foreach product.attribute.sku}{product.attribute.shipping}*{item.qty}{/foreach}""}
819
  }{/code}
820
  "
821
- "{os2editor.help.more_categories}","
822
  <h4>Particular case: examples of use of the product categories</h4>
823
 
824
  <p>
825
- Since version 2.4.2, it is possible to use product categories in formulas.
826
  </p>
827
  <p class=warning>
828
- <strong>Warning, you must notice that in Magento, a product can be in more than one category.</strong> So be particularly careful how you use this property.
829
  </p>
830
  <p>
831
- To filter products found in several specific categories, you can use <c>array_match_any()</c> function.
832
  </p>
833
  <p>
834
- Examples of use:
835
  </p>
836
  {code=json}{
837
  ""ex0"":{""label"":""foreach loop with an iteration on categories"",""fees"":""{foreach product.categories}{selection.weight}{/foreach}""},
@@ -844,7 +844,7 @@ Available prefixes list:
844
  ""ex7"":{""label"":""Sum of weights of products having the id of the first category equal to 12"",""fees"":""{sum product.weight where product.category.id==12}""}
845
  }{/code}
846
  "
847
- "{os2editor.help.changelog}","
848
  <h4>Changelog</h4>
849
  <div class=changelog>{changelog}</div>
850
  "
1
  # en-US
2
 
3
  # app/code/community/Owebia/Shipping2/Block/Adminhtml/Os2/Editor.php
4
+ "New shipping method","New shipping method"
5
+ "Remove","Remove"
6
+ "[meta] %s","[meta] %s"
7
+ "[data] %s","[data] %s"
8
+ # Tools
9
+ "Insert","Insert"
10
+ "Tools","Tools"
11
+ "Shipping country","Shipping country"
12
+ "Cart weight","Cart weight"
13
+ "Products quantity","Products quantity"
14
+ "Price incl. tax","Price incl. tax"
15
+ "Price excl. tax","Price excl. tax"
16
+ "Weight","Weight"
17
+ "Tracking number","Tracking number"
18
+ "Human readable version","Human readable version"
19
+ # Fields
20
+ "ID","ID"
21
+ "Type","Type"
22
+ "Shipping Method (default)","Shipping Method (default)"
23
+ "Data","Data"
24
+ "Meta","Meta"
25
+ "About","About"
26
+ "Enabled","Enabled"
27
+ "Enabled (default)","Enabled (default)"
28
+ "Disabled","Disabled"
29
+ "Label","Label"
30
+ "Description","Description"
31
+ "Shipping address","Shipping address"
32
+ "Billing address","Billing address"
33
+ "Origin address","Origin address"
34
+ "Conditions","Conditions"
35
+ "Fees","Fees"
36
+ "Customer groups","Customer groups"
37
+ "Tracking url","Tracking url"
38
 
39
  # app/code/community/Owebia/Shipping2/Block/Adminhtml/Os2/Help.php
40
+ "Refresh","Refresh"
41
+ "Previous page","Previous page"
42
+ "Summary","Summary"
43
 
44
  # app/code/community/Owebia/Shipping2/Block/Adminhtml/System/Config/Form/Field/Config.php
45
+ "Help","Help"
46
+ "Apply","Apply"
47
+ "Cancel","Cancel"
48
+ "Source &amp; Correction","Source &amp; Correction"
49
+ "Download configuration templates","Download configuration templates (in French)"
50
+ # JS
51
+ "Dissociate","Dissociate"
52
+ "Remove","Remove"
53
+ "Edit","Edit"
54
+ "Enter the new value:","Enter the new value:"
55
+ "[No label]","[No label]"
56
+ "Loading...","Loading..."
57
 
58
  # app/code/community/Owebia/Shipping2/Block/Adminhtml/System/Config/Form/Field/Config.php
59
+ "Version: %s","Version: %s"
60
 
61
  # app/code/community/Owebia/Shipping2/Controller/Abstract.php
62
+ "Owebia Shipping 2 Editor","Owebia Shipping 2 Editor"
63
+ "Source &amp; Correction","Source &amp; Correction"
64
+ "Help","Help"
65
+ "Donate","Donate"
66
+ "Close","Close"
67
 
68
  # app/code/community/Owebia/Shipping2/controllers/Adminhtml/Os2/AjaxController.php
69
+ "Editor","Editor"
70
+ "Source","Source"
71
+ "Correction","Correction"
72
+ "Debug","Debug"
73
+ "Apply","Apply"
74
+ "Export","Export"
75
+ "Add a shipping method","Add a shipping method"
76
+ "New shipping method","New shipping method"
77
+ "You appreciate this extension and would like to help?","You appreciate this extension and would like to help?"
78
+ "{os2editor.donate-page.content}","<p>The extension Owebia Shipping 2 is offered by the company Owebia (<a href=""http://www.owebia.com/"">http://www.owebia.com/</a>).<br/>If you want to support the developement of the extension, you can make a donation.</p><p>You will receive an invoice to keep trace of the donation.</p><p>Thanks to all donators.</p>"
79
 
80
  # app/code/community/Owebia/Shipping2/etc/system.xml
81
+ "Configuration","Configuration"
82
+ "Tracking URL","Tracking URL"
83
+ "Debug","Debug"
84
+ "{debug_help}","Debug displayed on cart while making a shipping estimation"
85
+ "Compression","Compression"
86
+ "{compression_help}","Gz + base64 compression. This is the editor that compress/uncompress."
87
+ "Auto-escaping","Auto-escaping"
88
+ "{auto_escaping_help}","Enable systematic auto-escaping of variables"
89
+ "Auto-correction","Auto-correction"
90
+ "{auto_correction_help}","This option enables backward compatibility but consommme resources"
91
+ "Stop to first match","Stop to first match"
92
+ "General Configuration","General Configuration"
93
+ "Weight unit","Weight unit"
94
+ "Bundle Product Management","Bundle Product Management"
95
+ "Configurable Product Management","Configurable Product Management"
96
+ "If ""Self"" is selected, options bellow are ignored","If ""Self"" is selected, options bellow are ignored"
97
+ "Item processing","Item processing"
98
+ "Item options on","Item options on"
99
+ "Item data on","Item data on"
100
+ "Product data on","Product data on"
101
 
102
  # app/code/community/Owebia/Shipping2/includes/OwebiaShippingHelper.php
103
+ "Configuration disabled","Configuration disabled"
104
+ "The cart doesn't match conditions","The cart doesn't match conditions"
105
+ "Infinite loop %s","Infinite loop %s"
106
+ "Error in table %s","Error in table %s"
107
+ "Usage of deprecated syntax %s","Usage of deprecated syntax %s"
108
+ "Usage of unknown properties %s","Usage of unknown properties %s"
109
+ "Usage of deprecated properties %s","Usage of deprecated properties %s"
110
 
111
  # app/code/community/Owebia/Shipping2/Model/Carrier/Abstract.php
112
+ "track the package","track the package"
113
 
114
  # app/code/community/Owebia/Shipping2/Model/Os2/Data/AddressFilter.php
115
+ "Africa","Africa"
116
+ "Asia","Asia"
117
+ "Europa","Europa"
118
+ "North America","North America"
119
+ "South America","South America"
120
+ "Oceania","Oceania"
121
+ "Antartica","Antartica"
122
+ "European Union","European Union"
123
 
124
  # app/code/community/Owebia/Shipping2/Model/System/Config/Source/LoadOnParent.php
125
+ "Self","Self"
126
+ "Parent","Parent"
127
 
128
  # Help
129
+ "{os2editor.help.summary}","
130
  <h4>Summary</h4>
131
  <div class=""table-of-contents"">
132
  <table><tr>
133
+ <td>
134
+ <ol class=level1>
135
+ <li class=new><a href=""#introduction"">Introduction: JSON syntax, items and properties</a></li>
136
+ <li><a href=""#unique_id"">The unique identifier</a></li>
137
+ <li class=new>The item types:
138
+ <ul>
139
+ <li><a href=""#type_method""><property>method</property>: shipping method</a></li>
140
+ <li><a href=""#type_data""><property>data</property>: data</a></li>
141
+ <li><a href=""#type_meta""><property>meta</property>: meta data</a></li>
142
+ </ul>
143
+ </li>
144
+ <li class=new>Common properties:
145
+ <ul>
146
+ <li><a href=""#property_type""><property>type</property>: the type of the item</a></li>
147
+ <li><a href=""#property_about""><property>about</property>: comment on the item</a></li>
148
+ </ul>
149
+ </li>
150
+ <li>Properties of <property>method</property> items:
151
+ <ul>
152
+ <li class=important><a href=""#property_label""><property>label</property></a></li>
153
+ <li><a href=""#property_description""><property>description</property></a></li>
154
+ <li class=important><a href=""#property_conditions""><property>conditions</property></a></li>
155
+ <li class=new><a href=""#property_shipto""><property>shipto</property>: the shipping address</a> (<property>destination</property> bef. 2.4.8)</li>
156
+ <li class=new><a href=""#property_shipto""><property>billto</property>: the billing address</a> (since 2.4.8)</li>
157
+ <li><a href=""#property_shipto""><property>origin</property>: the origin address</a></li>
158
+ <li><a href=""#property_customer_groups""><property>customer_groups</property></a></li>
159
+ <li class=important><a href=""#property_fees""><property>fees</property>: the shipping fees</a></li>
160
+ <li><a href=""#property_tracking_url""><property>tracking_url</property></a></li>
161
+ <li><a href=""#property_enabled""><property>enabled</property></a></li>
162
+ </ul>
163
+ </li>
164
+ </ol>
165
+ </td>
166
+ <td>
167
+ <ol class=level1 start=6>
168
+ <li><a href=""#more_formulas"">Introduction to Formulas</a>
169
+ <ol>
170
+ <li class=new><a href=""#more_vars"">Available variables</a></li>
171
+ <li class=new><a href=""#more_special-functions"">Special Functions in Formulas</a> (update 2.5)<br/>&nbsp; &nbsp; min, max, range, substr, in_array, array_match_any, array_match_all</li>
172
+ <li><a href=""#more_copy"">Make a copy of a property from an other item</a></li>
173
+ <li><a href=""#more_tables"">Using <c>table</c></a></li>
174
+ <li><a href=""#more_switch"">Using <c>switch</c></a> (update 2.4.5)</li>
175
+ <li class=new><a href=""#more_attributes-options"">Using product properties (sum, count, min, max)</a> (update 2.4.8)</li>
176
+ <li><a href=""#more_foreach"">Using <c>foreach</c> loops</a></li>
177
+ <li class=new><a href=""#more_categories"">Particular case: examples of use of product categories</a> (update 2.5)</li>
178
+ </ol>
179
+ </li>
180
+ <li><a href=""#changelog"">Changelog</a></li>
181
+ </ol>
182
+ </td>
183
  </tr></table>
184
  </div>
185
  "
186
+ "{os2editor.help.introduction}","
187
  <h4>Introduction: JSON syntax, items and properties</h4>
188
  <p class=new>
189
+ If you have a question, use the following topic: <a href=""http://www.magentocommerce.com/boards/viewthread/38223/"" target=_blank>http://www.magentocommerce.com/boards/viewthread/38223/</a>
190
  </p>
191
 
192
  <p>
193
+ <span class=new>Since version 2.5, the syntax of configuration is full JSON <a href=""http://en.wikipedia.org/wiki/JavaScript_Object_Notation"" target=_blank>JSON</a>.</span>
194
  </p>
195
  <p>
196
+ Example:
197
  </p>
198
  {code=json}{
199
  ""ex0"":{""about"":""National"",""label"":""National"",""shipto"":""AD,FR,MC"",""conditions"":""{cart.price-tax+discount}<1000.00"",""fees"":""1.30 + {table {cart.weight} in 0.5:5.30, 1.0:6.50, 2.0:7.40, 3.0:8.30, 5.0:10.10}""}
200
  }{/code}
201
 
202
  <p>
203
+ The configuration is a JSON object containing <strong>properties</strong>.<br/>
204
+ Each property has a unique name, wich will serve as <a href=""#unique_id"">unique identifier</a>.<br/>
205
+ Each property will consiste on a configuration <strong>item</strong> (also a JSON object).<br/>
206
  </p>
207
  <p>
208
+ Items have always a <property>type</property> property. This sets the type of the item:
209
  </p>
210
  <ul>
211
+ <li><a href=""#type_method""><property>method</property>: shipping method (default if not specified)</a></li>
212
+ <li><a href=""#type_data""><property>data</property>: data that can be used in shipping methods</a></li>
213
+ <li><a href=""#type_meta""><property>meta</property>: informative data</a></li>
214
  </p>
215
  "
216
+ "{os2editor.help.unique_id}","
217
  <h4>The unique identifier</h4>
218
  <p>Each configuration item has a unique identifier. This unique identifier is then used to reference the item.</p>
219
  <p>Example:</p>
224
 
225
  <p class=warning><strong><u>Warning</u>:</strong> to avoid conflicts, use only the following characters <c>a-z</c>, <c>A-Z</c>, <c>0-9</c>, <c>-</c> and <c>_</c> to make the unique identifier.<br/>You have also to avoid identifiers that match to any variable name (<c>cart</c>, <c>product</c>, <c>item</c>…).</p>
226
  "
227
+ "{os2editor.help.type_method}","
228
  <h4><property>method</property> item</h4>
229
  <p>A <property>method</property> item allow to specify a shipping method.</p>
230
  <p>Example with only required properties:</p>
236
  ""ex0"":{""about"":""Colissimo National"",""type"":""method"",""label"":""Colissimo"",""description"":""Delivery within 24/48h"",""enabled"":true,""conditions"":""range({cart.weight},0.2,1.0)"",""shipto"":""FR(01,02,39600,/^25[0-9]{3}$/),CH,DE"",""billto"":""FR"",""origin"":""DE"",""customer_groups"":""NOT LOGGED IN,Retailer"",""fees"":""{table {cart.weight} in 0.5:5.30, 1.0:6.50}""}
237
  }{/code}
238
  "
239
+ "{os2editor.help.type_data}","
240
  <h4><property>data</property> item</h4>
241
  <p>A <property>data</property> item allow to specify data that can be used in shipping methods.</p>
242
  <p>Example of <property>data</property> item:</p>
248
  ""ex0"":{""type"":""method"",""label"":""Colissimo"",""fees"":""{mydata.reference}*1.5""}
249
  }{/code}
250
  "
251
+ "{os2editor.help.type_meta}","
252
  <h4><property>meta</property> item</h4>
253
  <p>A <property>meta</property> item allow to add informative data (author, date…).</p>
254
  <p>Example:</p>
256
  ""about"":{""type"":""meta"",""author"":""Owebia"",""date"":""16/11/2012"",""about"":""Prices 2012""}
257
  }{/code}
258
  "
259
+ "{os2editor.help.property_type}","
260
  <h4><property>type</property>: the type of the item</h4>
261
  <p>This sets the type of the item:</p>
262
  <ul>
263
+ <li><a href=""#type_method""><property>method</property>: shipping method (default if not specified)</a></li>
264
+ <li><a href=""#type_data""><property>data</property>: data that can be used in shipping methods</a></li>
265
+ <li><a href=""#type_meta""><property>meta</property>: informative data</a></li>
266
  </p>
267
  {code=json}{
268
  ""about"":{""type"":""meta"",""author"":""Owebia"",""date"":""16/11/2012"",""about"":""Prices 2012""},
270
  ""ex0"":{""type"":""method"",""label"":""Colissimo"",""fees"":""{mydata.reference}*1.5""}
271
  }{/code}
272
  "
273
+ "{os2editor.help.property_about}","
274
  <h4><property>about</property>: comment on the item</h4>
275
  <p>You can add a comment to a configuration item.</p>
276
  {code=json}{""ex0"":{""about"":""My comment"",""label"":""Example with a comment"",""fees"":10}}{/code}
277
  "
278
+ "{os2editor.help.property_label}","
279
  <h4>The <property>label</property></h4>
280
  <p>The name given to the shipping method.</p>
281
  <p>We can insert some data like the package weight in the label.<br/>
282
  To do that, use the following variables:</p>
283
  <ul>
284
+ <li>The shipping address:
285
+ <ul>
286
+ <li class=new><c><strike>{destination.country.name}</strike> {shipto.country_name}</c></li>
287
+ <li class=new><c><strike>{destination.country.code}</strike> {shipto.country_id}</c></li>
288
+ <li class=new><c><strike>{destination.region.code}</strike> {shipto.region_code}</c></li>
289
+ <li class=new><c><strike>{destination.postcode}</strike> {shipto.postcode}</c></li>
290
+ </ul>
291
+ </li>
292
+ <li><c>{cart.weight}</c>: the package weight</li>
293
+ <li class=new><c><strike>{cart.weight.unit}</strike> {cart.weight_unit}</c>: the weight unit</li>
294
+ <li><a href=""#more_vars"">See the full list of variables</a></li>
295
  </ul>
296
  {code=json}{
297
  ""ex0"":{""label"":""Colissimo ({cart.weight} / {shipto.country_name})"",""fees"":10}
298
  }{/code}
299
  <p>The above line will display for example <string>""Colissimo (3.0kg / France)""</string>.</p>
300
  "
301
+ "{os2editor.help.property_description}","
302
  <h4>The <property>description</property></h4>
303
  <p>The description of the shipping method.</p>
304
  <p>The usage is the same as <a href=""#property_label""><property>label</property></a> property.</p>
305
  "
306
+ "{os2editor.help.property_conditions}","
307
  <h4><property>conditions</property></h4>
308
  <p>
309
+ <property>conditions</property> property is specified as a <a href=""#more_formulas"">formula (see introduction to formulas)</a>
310
+ that must return a boolean value (<c>true</c> or <c>false</c>).
311
  </p>
312
 
313
  {code=json}{
323
  ""ex9"":{""label"":""If all products have 'size' option greater or equal to '1'"",""conditions"":""{count items where product.option.size>='1'}=={cart.qty}"",""fees"":10}
324
  }{/code}
325
  "
326
+ "{os2editor.help.property_shipto}","
327
  <h4>Addresses: <property>shipto</property>, <property>billto</property> and <property>origin</property></h4>
328
  <p>
329
+ The extension allow to filter addresses:
330
  </p>
331
  <ul>
332
+ <li class=new>The shipping address <strike><property>destination</property></strike> <property>shipto</property>.</li>
333
+ <li class=new>The billing address <property>billto</property></li>
334
+ <li>The origin address <property>origin</property></li>
335
  </ul>
336
  <p>
337
+ Country codes used are those used by Magento.<br/>
338
+ It's possible to specify region codes (only with <property>shipto</property>) or postcodes.
339
  </p>
340
  <p class=new>
341
+ You can use the wildcard character <c>*</c> or regular expressions to filter postcodes.<br/>
342
+ A regular expression must start and end width the character <c>/</c>. If you want to use characters <c>(</c>, <c>)</c> or <c>,</c>, you have to escape them with character <c>\</c> (ex: <string>""FR(/^25\([0-9]{3}\)$/)""</string>).<br/>
343
+ You can use the case insensitive modifier (ex: <string>""GB(/^PO.*$/i)""</string>).
344
  </p>
345
 
346
  {code=json}{
353
  }{/code}
354
 
355
  <div class=""tips"">
356
+ <p><strong>Tip</strong><br/>To shorten the seizure of countries, you can use the following variables:</p>
357
+ <ul>
358
+ <li><c>{address_filter.AF}</c>: countries of Africa</li>
359
+ <li><c>{address_filter.AS}</c>: countries of Asia</li>
360
+ <li><c>{address_filter.EU}</c>: countries of Europa</li>
361
+ <li><c>{address_filter.NA}</c>: countries of North America</li>
362
+ <li><c>{address_filter.SA}</c>: countries of South America</li>
363
+ <li><c>{address_filter.OC}</c>: countries of Oceania</li>
364
+ <li><c>{address_filter.AN}</c>: countries of Antartica</li>
365
+ <li><c>{address_filter.EU-27}</c>: countries of the European Union</li>
366
+ <li><c>{address_filter.DOM}</c>: country codes of overseas french department</li>
367
+ <li><c>{address_filter.COM}</c>: country codes of overseas french communities</li>
368
+ </ul>
369
  </div>
370
 
371
  {code=json}{
372
  ""ex0"":{""label"":""Europa except France"",""shipto"":""({address_filter.EU-27}) - (FR)"",""fees"":10}
373
  }{/code}
374
  "
375
+ "{os2editor.help.property_billto}","
376
  <h4><property>billto</property>: the billing address</h4>
377
  <p><a href=""#property_shipto"">Filtering addresses</a></p>
378
  "
379
+ "{os2editor.help.property_origin}","
380
  <h4><property>origin</property>: the origin address</h4>
381
  <p><a href=""#property_shipto"">Filtering addresses</a></p>
382
  "
383
+ "{os2editor.help.property_customer_groups}","
384
  <h4><property>customer_groups</property></h4>
385
  <p>We can use the name or the ID of customer groups.</p>
386
 
390
  ""ex2"":{""label"":""Retailer group"",""customer_groups"":""Retailer"",""fees"":10}
391
  }{/code}
392
  "
393
+ "{os2editor.help.property_fees}","
394
  <h4><property>fees</property>: the shipping fees</h4>
395
  <p>
396
+ <property>fees</property> property is specified as a <a href=""#more_formulas"">formula (see introduction to formulas)</a>.
397
  </p>
398
  {code=json}{
399
  ""ex0"":{""label"":""Fixed fees"",""fees"":10},
402
  ""ex3"":{""label"":""Combination"",""fees"":""0.1 * {cart.price-tax+discount} + {table {cart.weight} in 0.5:5.30, 1.0:6.50} + 10.00""}
403
  }{/code}
404
  "
405
+ "{os2editor.help.property_tracking_url}","
406
  <h4><property>tracking_url</property></h4>
407
  <p class=warning>
408
+ <strong>The use of <property>tracking_url</property> property is reserved for experienced users. If you don't understand the instructions below, it is recommended that you avoid using this feature.</strong>
409
  </p>
410
  <p>
411
+ The <property>tracking_url</property> property overrides the field ""Tracking URL"" of an Owebia Shipping shipping mode. So you can specify a tracking URL <strong>foreach shipping method</strong> rather than one for all shipping mode.
412
  </p>
413
  <p>
414
+ To automatically insert the tracking number in the tracking URL, you must use <c>{tracking_number}</c>.
415
  </p>
416
 
417
  {code=json}{
419
  }{/code}
420
 
421
  <p>
422
+ Magento does not support tracking links but tracking statuses. The extension Owebia Shipping 2 provides an HTML link instead of the status, link allowing you to go on the carrier's website and follow the progress of the parcel.
423
  </p>
424
  <p>
425
+ When the tracking URL is built by the extension, the only information available is the tracking number and there was nowhere an access to the shipping method selected. In order to find the tracking URL in the configuration, you must specify the shipping method inside the tracking number, for example: <c>colissimo:8Lxxxxxxxxxxx</c> where <c>colissimo</c> is the code of the shipping method selected.<br/>
426
+ If no code is specified (if you enter only the tracking number), the URL used will be the one of the shipping mode.
427
  </p>
428
  <p class=warning>
429
+ To answer a recurrent question, Magento displays the tracking status from the back office or front office. <strong>If you want to insert the tracking URL in shipping mails, you need to develop yourself the retrieval of tracking URL and its incorporation in the mail, in fact, the Owebia Shipping extension simply provides customizable shipping methods without making big changes to Magento core to reduce incompatibility and update problems.</strong>
430
  </p>
431
  <p class=warning>
432
+ If you get a blank popup when you click on the tracking link, your problem is most likely related to the fact that you did not specify the code of the shipping method in the tracking number (see instructions above) and your global field ""Tracking URL"" is empty.
433
  </p>
434
  <p class=warning>There are currently no plans to change this feature.</p>
435
  "
436
+ "{os2editor.help.property_enabled}","
437
  <h4><property>enabled</property></h4>
438
  <p>Allow to activate or desactivate the shipping method.</p>
439
  <p>The value must be boolean.</p>
441
  ""ex0"":{""enabled"":true,""label"":""Example with activation"",""fees"":10}
442
  }{/code}
443
  "
444
+ "{os2editor.help.more_formulas}","
445
  <h4>Introduction to formulas</h4>
446
  <p>
447
+ Properties <property>fees</property> and <property>conditions</property> are specified as formulas.
448
  </p>
449
  <p>
450
+ Mathematical signs available:
451
  </p>
452
  <ul>
453
+ <li>operators: <c>*</c>, <c>/, <c>+</c> and <c>-</c></li>
454
+ <li>modulo: <c>%</c></li>
455
+ <li>brackets: <c>(</c> et <c>)</c></li>
456
+ <li>boolean operators <c>&amp;&amp;</c>, <c>and</c>, <c>||</c>, <c>or</c>, <c>==</c>, <c>&lt;</c>, <c>&gt;</c>, <c>&lt;=</c>, <c>&gt;=</c></li>
457
+ <li>binary operators <c>&amp;</c> and <c>|</c></li>
458
+ <li>operators group <c>C ? X : Y</c> (ex: <c><span class=string>""{cart.price_exluding_tax}&gt;100 ? 15*{cart.weight} : 20*{cart.weight}""</span></c>)</li>
459
  </ul>
460
  <p>
461
+ Variables available:
462
  </p>
463
  <ul>
464
 
465
+ <li><c>{cart.weight}</c>: full package weight</li>
466
+ <li><c>{cart.qty}</c>: items count in cart</li>
467
+ <li><c>{cart.price-tax+discount}</c>: price excluding tax after discount</li>
468
+ <li><c>{cart.price+tax+discount}</c>: price including tax after discount</li>
469
+ <li><c>{cart.price-tax-discount}</c>: price excluding tax before discount</li>
470
+ <li><c>{cart.price+tax-discount}</c>: price including tax before discount</li>
471
+ <li><a href=""#more_vars"">See full list of variables</a></li>
472
  </ul>
473
  <p>
474
+ You can put spaces and line returns in formulas (to air).
475
  </p>
476
  <p>
477
+ Functions available:
478
  </p>
479
  <ul>
480
+ <li>rounds: <c>round(x)</c>, <c>floor(x)</c>, <c>ceil(x)</c></li>
481
+ <li>absolute value: <c>abs(x)</c></li>
482
+ <li>maximum: <c>max(x,y)</c></li>
483
+ <li>minimum: <c>min(x,y)</c></li>
484
+ <li>random integer: <c>rand(min,max)</c></li>
485
+ <li>power: <c>pow(x,puissance)</c></li>
486
+ <li>PI number: <c>pi()</c></li>
487
+ <li>square root: <c>sqrt(x)</c></li>
488
+ <li>logarithm: <c>log(x)</c> for the natural logarithm or <c>log(x,base)</c></li>
489
+ <li>exponential: <c>exp(x)</c></li>
490
  </ul>
491
  <p>
492
+ Ability to use advanced features like: casting to integer <c>(int)</c> casting to floating number <c>(float)</c>, comparison with <c>null</c> or boolean values <c>true</c> and <c>false</c>.
493
  </p>
494
  <p class=""new"" style=""font-weight: bold;"">
495
+ You can also use advanced features such as rates tables, copy of a property of another method,
496
+ special functions, usage of product's attributes and options or usage of custom variables.
497
  </p>
498
  <p class=new style=""font-weight: bold;"">
499
+ When you use alphanumeric variables, you can escape them with quotes or you can use the autoescape syntax <c>{{ }}</c>.
500
  </p>
501
  {code=json}{
502
  ""ex0"":{""label"":""Escaping with quotes"",""conditions"":""'{cart.coupon_code}'=='test'"",""fees"":10},
503
  ""ex1"":{""about"":""Since version 2.4.5, {{cart.coupon_code}} will be replaced by 'moncoupon' or by null depending on its value"",""label"":""Auto-escaping"",""conditions"":""{{cart.coupon_code}}!='test'"",""fees"":10}
504
  }{/code}
505
  "
506
+ "{os2editor.help.more_vars}","
507
  <h4>Variables available</h4>
508
  <p>
509
+ The following variables can be used in different properties of shipping methods (in particular in properties <property>conditions</property> and <property>fees</property>).
510
  </p>
511
  <ul>
512
+ <li>The cart:
513
+ <ul>
514
+ <li><c>{cart.weight}</c>: package weight</li>
515
+ <li><c class=new><strike>{cart.quantity}</strike> {cart.qty}</c>: items quantity</li>
516
+ <li class=new><c><strike>{cart.price_excluding_tax}</strike> {cart.price-tax+discount}</c>: price excl. tax after discount</li>
517
+ <li class=new><c><strike>{cart.price_including_tax}</strike> {cart.price+tax+discount}</c>: price incl. tax after discount</li>
518
+ <li class=new><c>{cart.price-tax-discount}</c>: price excl. tax before discount</li>
519
+ <li class=new><c>{cart.price+tax-discount}</c>: price incl. tax before discount</li>
520
+ <li class=new><c><strike>{cart.coupon}</strike> {cart.coupon_code}</c></li>
521
+ <li><c class=new><strike>{free_shipping}</strike> {cart.free_shipping}</c>: shipping offered (by a rule in Magento) [true/false]</li>
522
+ <li><c class=new><strike>{cart.weight.unit}</strike> {cart.weight_unit}</c></li>
523
+ <li><c class=new><strike>{cart.weight.for-charge}</strike> {cart.weight_for_charge}</c>: weight of goods whose delivery is not offered (by a cart price rule in Magento)</li>
524
+ </ul>
525
+ </li>
526
+ <li class=new>The customer group:
527
+ <ul>
528
+ <li><c><strike>{customer.group.id}</strike> {customer_group.id}</c></li>
529
+ <li><c><strike>{customer.group.code}</strike> {customer_group.code}</c>: name of customer group</li>
530
+ <li><c>{customer_group.*}</c>: property of customer group (ex: <c>{customer_group.tax_class_id}</c>)</li>
531
+ </ul>
532
+ </li>
533
+ <li class=new>The customer:
534
+ <ul>
535
+ <li><c>{customer.id}</c></li>
536
+ <li><c>{customer.attribute.*}</c>: attribute of the customer (ex: lastname, firstname, group_id…)</li>
537
+ <li class=new><c>{customer.attribute.*.value}</c>: in case of attributes of type dropdown, <c>{customer.attribute.*}</c> returns the id, to get the value you must use <c>{customer.attribute.*.value}</c></li>
538
+ <li><c>{customer.*}</c>: same as <c>{customer.attribute.*}</c> if the variable isn't defined (ex: <c>{customer.id}</c> is already defined)</li>
539
+ </ul>
540
+ </li>
541
+ <li class=new>Custom Variables (since version 1.4.0.1 of Magento):
542
+ <ul>
543
+ <li><c>{customvar.*}</c>: Magento custom variable (ex: <c>{customvar.my_var}</c>)</li>
544
+ <li><c><strike>{{customVar code=*}}</strike></c>: use the syntax above</li>
545
+ </ul>
546
+ </li>
547
+ <li>The shipping address:
548
+ <ul>
549
+ <li><c class=new><strike>{destination.country.name}</strike> {shipto.country_name}</c></li>
550
+ <li><c class=new><strike>{destination.country.code}</strike> {shipto.country_id}</c>: the country code</li>
551
+ <li class=new><c>{shipto.region_id}</c></li>
552
+ <li><c class=new><strike>{destination.region.code}</strike> {shipto.region_code}</c></li>
553
+ <li class=new><c>{shipto.street}</c></li>
554
+ <li class=new><c>{shipto.city}</c></li>
555
+ <li><c class=new><strike>{destination.postcode}</strike> {shipto.postcode}</c></li>
556
+ </ul>
557
+ </li>
558
+ <li class=new>The billing address:
559
+ <ul>
560
+ <li><c>{billto.country_name}</c></li>
561
+ <li><c>{billto.country_id}</c>: the country code</li>
562
+ <li><c>{billto.postcode}</c></li>
563
+ <li><c>{billto.*}</c>: property of the billing address (ex: <c>{billto.city}</c>)</li>
564
+ </ul>
565
+ </li>
566
+ <li>The origin address:
567
+ <ul>
568
+ <li><c class=new><strike>{origin.country.name}</strike> {origin.country_name}</c></li>
569
+ <li><c class=new><strike>{origin.country.code}</strike> {origin.country_id}</c>: the country code</li>
570
+ <li><c class=new><strike>{origin.region.code}</strike> {origin.region_id}</c></li>
571
+ <li class=new><c>{origin.city}</c></li>
572
+ <li><c>{origin.postcode}</c></li>
573
+ </ul>
574
+ </li>
575
+ <li>The store:
576
+ <ul>
577
+ <li><c>{store.id}</c> <c>{store.code}</c> <c>{store.name}</c> <c>{store.address}</c> <c>{store.phone}</c>: id, code, name, address and phone number of the store</li>
578
+ </ul>
579
+ </li>
580
+ <li>The current date:
581
+ <ul>
582
+ <li><c>{date.timestamp}</c>: UNIX timestamp of current date</li>
583
+ <li><c>{date.year}</c> <c>{date.month}</c> <c>{date.day}</c> <c>{date.hour}</c> <c>{date.minute}</c></li>
584
+ <li><c>{date.weekday}</c>: weekday for current date from 0 (Sunday) to 6 (Saturday)</li>
585
+ </ul>
586
+ </li>
587
+ <li class=new>The <c>request</c> object:
588
+ <ul>
589
+ <li><c>{request.*}</c>: property of the request object (Mage_Shipping_Model_Rate_Request) parameter given by Magento (ex: <c>{request.package_qty}</c>). Use the ""Debug"" option to have more details on available properties.</li>
590
+ </ul>
591
+ </li>
592
  </ul>
593
  "
594
+ "{os2editor.help.more_special-functions}","
595
  <h4>Special functions in formulas</h4>
596
 
597
  <p>
598
+ You can use special functions in formulas.
599
  </p>
600
  <p>
601
+ List of special functions:
602
  </p>
603
  <ul>
604
+ <li><c>min(x, y, …)</c> : calculate the minimum of several values (possibly more than two values). If one value is null, it is ignored.</li>
605
+ <li><c>max(x, y, …)</c> : calculate the maximum of several values (possibly more than two values). If one value is null, it is ignored.</li>
606
+ <li class=new><c>range(value, min, max, include_min, include_max)</c> : returns <c>true</c> if <c>value</c> is between <c>min</c> and <c>max</c>. By default, <c>include_min</c> and <c>include_max</c> are set to <c>true</c>.</li>
607
+ <li class=new><c>substr(string, start, length)</c> : returns a segment of a string.</li>
608
+ <li class=new><c>in_array(value, array(value1, value2, …))</c> : returns true if the value is in the array.</li>
609
+ <li class=new><c>array_match_any(array(value1, value2, …), array(value1, value2, …))</c> : returns true if any value is in both arrays.</li>
610
+ <li class=new><c>array_match_all(array(value1, value2, …), array(value1, value2, …))</c> : returns true if both arrays have the same values.</li>
611
  </ul>
612
 
613
  {code=json}{
621
  }{/code}
622
 
623
  <p class=new>
624
+ * About strings escaping, refer to the <a href=""#more_formulas"">introduction to formulas</a>.
625
  </p>
626
  "
627
+ "{os2editor.help.more_copy}","
628
  <h4>Make a copy of a property of another method</h4>
629
  <p>It is possible to make a copy of a property in another using the syntax below.</p>
630
  <p>You can use this technique in all properties (<property>conditions</property>, <property>fees</property>, …).</p>
635
  ""ex2"":{""label"":""Copy of fees from another method"",""fees"":""({colissimo.fees}) + 15.00""}
636
  }{/code}
637
  "
638
+ "{os2editor.help.more_tables}","
639
  <h4>Using <c>table</c></h4>
640
  <p>
641
+ In a <c>table</c>, you can include or exclude a limit value with characters <c>[</c> et <c>]</c>:
642
  </p>
643
  {code=json}{
644
  ""f0"":{""label"":""Upper limit included"",""fees"":""{table {cart.weight} in 1.0]:5.00}""},
646
  }{/code}
647
 
648
  <p>
649
+ In a <c>table</c>, you must specify the reference value. For this, we can use one of the <a href=""#more_vars"">available variables</a>.<br/>
650
+ You can also use a formula to define another reference variable.
651
  </p>
652
 
653
  {code=json}{
658
  ""ex4"":{""label"":""Table with user defined value"",""fees"":""{table ceil({cart.weight}/10) in 1:5.30, 2:6.50}""}
659
  }{/code}
660
  "
661
+ "{os2editor.help.more_switch}","
662
  <h4>Using <c>switch</c></h4>
663
 
664
  <p>
665
+ In a <c>switch</c>, you must specify the reference value. For this, we can use one of the <a href=""#more_vars"">available variables</a>.<br/>
666
+ You can also use a formula to define another reference variable.
667
  </p>
668
 
669
  {code=json}{
671
  ""ex1"":{""label"":""Switch with shipping country"",""fees"":""{switch {{shipto.country_id}} in 'FR':5.30, 'BE':6.50, 'DE':10.00, *:7.50}""}
672
  }{/code}
673
  "
674
+ "{os2editor.help.more_attributes-options}","
675
  <h4>Using product properties</h4>
676
 
677
  <p class=new>
678
+ In order to match to Magento Models, the version 2.4.8 of the extension adds a separation between <c>item</c> and <c>product</c>.
679
+ An <c>item</c> is a <c>product</c> variation with some options. Each <c>item</c> has a quantity.
680
  </p>
681
  <p>
682
+ List of available properties:
683
  </p>
684
  <ul>
685
+ <li class=new>The <c>item</c>:
686
+ <ul>
687
+ <li><c>item.qty</c>: the quantity in cart</li>
688
+ <li><c>item.price-tax+discount</c>: the price excl. tax after discount</li>
689
+ <li><c>item.price-tax-discount</c>: the price excl. tax before discount</li>
690
+ <li><c>item.price+tax+discount</c>: the price incl. tax after discount</li>
691
+ <li><c>item.price+tax-discount</c>: the price incl. tax before discount</li>
692
+ <li><c>item.option.*</c>: option (depends on product)</li>
693
+ </ul>
694
+ </li>
695
+ <li>The <c>product</c>:
696
+ <ul>
697
+ <li><c><strike>product.quantity</strike></c>: use <c class=new>item.qty</c></li>
698
+ <li><c>product.attribute.*</c>: attribute<br/>List of interesting attributes:
699
+ <ul>
700
+ <li><c>sku</c></li>
701
+ <li><c>name</c></li>
702
+ <li><c>weight</c></li>
703
+ <li><c>price</c> (as defined in product)</li>
704
+ <li><c>special_price</c> (as defined in product)</li>
705
+ <li><c><strike>price-tax+discount</strike></c>: use <c class=new>item.price-tax+discount</c></li>
706
+ <li><c><strike>price-tax-discount</strike></c>: use <c class=new>item.price-tax-discount</c></li>
707
+ <li><c><strike>price+tax+discount</strike></c>: use <c class=new>item.price+tax+discount</c></li>
708
+ <li><c><strike>price+tax-discount</strike></c>: use <c class=new>item.price+tax-discount</c></li>
709
+ </ul>
710
+ </li>
711
+ <li class=new><c>product.attribute.*.value</c>: value of the attribute<br/>In case of attributes of type dropdown, <c>product.attribute.*</c> returns the id. To get the value, you must use <c>product.attribute.*.value</c></li>
712
+ <li class=new><c>product.*</c>: same as <c>product.attribute.*</c> if variable is not defined (ex: <c>product.category</c> is defined)</li>
713
+ <li><c><strike>product.option.*</strike></c>: use <c class=new>item.option.*</c></li>
714
+ <li>First category of the product:
715
+ <ul>
716
+ <li><c>product.category</c>: name of the category</li>
717
+ <li><c>product.category.id</c></li>
718
+ <li class=new><c>product.category.*</c>: attribute of the category (ex: <c>product.category.is_active</c>)<br/>List of interesting attributes:
719
+ <ul>
720
+ <li><c>is_active</c></li>
721
+ <li><c>name</c></li>
722
+ <li>…</li>
723
+ </ul>
724
+ </li>
725
+ </ul>
726
+ </li>
727
+ <li>All categories of the product (returns an array, <a href=""#more_categories"">explanation section</a>) :
728
+ <ul>
729
+ <li><c>product.categories</c>: array of categories names</li>
730
+ <li><c>product.categories.id</c>: array of categories ids</li>
731
+ </ul>
732
+ </li>
733
+ <li>Attribute set of the product:
734
+ <ul>
735
+ <li><c>product.attribute_set</c>: name of attribute set</li>
736
+ <li><c>product.attribute_set.id</c></li>
737
+ <li class=new><c>product.attribute_set.*</c>: attribute of attribute set (ex: <c>product.attribute_set.attribute_set_name</c>)</li>
738
+ </ul>
739
+ </li>
740
+ <li class=new><c>product.stock.*</c>: attribute of product stock<br/>List of interesting attributes:
741
+ <ul>
742
+ <li><c>is_in_stock</c></li>
743
+ <li><c>qty</c>: product stock</li>
744
+ <li>…</li>
745
+ </ul>
746
+ </li>
747
+ </ul>
748
+ </li>
749
  </ul>
750
 
751
  {code=json}{
763
  Available prefixes list:
764
  </p>
765
  <ul>
766
+ <li><c>count</c>: count (always followed by <c>items</c>)</li>
767
+ <li><c>count distinct</c> : distinct count (always followed by a property)</li>
768
+ <li><c>sum</c> : sum (always followed by a property)</li>
769
+ <li class=new><c>min</c> : minimum (always followed by a property)</li>
770
+ <li class=new><c>max</c> : maximum (always followed by a property)</li>
771
  </ul>
772
  <p>
773
+ It's possible to specify conditions that must be met by products to be taken into account. To do this, simply add <c> where </c> followed by a formula.
774
  </p>
775
  <p>
776
+ If the property type is <strong>Yes/No</strong>, you should use <c>true</c>/<c>false</c> or <c>1</c>/<c>0</c> without quotes.
777
  </p>
778
  {code=json}{
779
  ""ex0"":{""label"":""Example property of type Yes/No: 0"",""conditions"":""{count items where product.attribute.colissimo_allowed==0}"",""fees"":10},
781
  }{/code}
782
 
783
  <p>
784
+ If the property type is <strong>Drop-down</strong> and you want to make a comparison with the value rather than with the id, you must use the following syntax:
785
  </p>
786
  <strike>{code=json}{
787
  ""ex0"":{""label"":""If the color attribute's id is different to 1"",""conditions"":""{count items where product.color.id!=1}"",""fees"":10}
790
  ""ex0"":{""label"":""If the value of color attribute is different to 'Bleu'"",""conditions"":""{count items where product.color.value!='Bleu'}"",""fees"":10}
791
  }{/code}
792
  "
793
+ "{os2editor.help.more_foreach}","
794
  <h4>Using <c>foreach</c> loops</h4>
795
 
796
  <p>
797
+ <c>foreach</c> loops can perform calculations on groups of products rather than consider all the products in the basket.<br/>
798
+ The overall result of a <c>foreach</c> loop is the sum of the results of each pass through the loop.
799
  </p>
800
  <p>
801
+ Inside a <c>foreach</c> loop, it is possible to use new variables:
802
  </p>
803
  <ul>
804
+ <li><c>{selection.weight}</c></li>
805
+ <li><c class=new><strike>{selection.quantity}</strike> {selection.qty}</c>: items count in the selection</li>
806
  </ul>
807
  <p>
808
+ When the selection is done on the sku, each selection is composed of a single article. We can use other variables:
809
  </p>
810
  <ul>
811
+ <li><c>{item.*}</c></li>
812
+ <li><c>{product.*}</c></li>
813
+ <li><a href=""#more_attributes-options"">See the full list of products properties</a></li>
814
  </ul>
815
 
816
  {code=json}{
818
  ""ex1"":{""label"":""Individual calculation of shipping fees"",""fees"":""{foreach product.attribute.sku}{product.attribute.shipping}*{item.qty}{/foreach}""}
819
  }{/code}
820
  "
821
+ "{os2editor.help.more_categories}","
822
  <h4>Particular case: examples of use of the product categories</h4>
823
 
824
  <p>
825
+ Since version 2.4.2, it is possible to use product categories in formulas.
826
  </p>
827
  <p class=warning>
828
+ <strong>Warning, you must notice that in Magento, a product can be in more than one category.</strong> So be particularly careful how you use this property.
829
  </p>
830
  <p>
831
+ To filter products found in several specific categories, you can use <c>array_match_any()</c> function.
832
  </p>
833
  <p>
834
+ Examples of use:
835
  </p>
836
  {code=json}{
837
  ""ex0"":{""label"":""foreach loop with an iteration on categories"",""fees"":""{foreach product.categories}{selection.weight}{/foreach}""},
844
  ""ex7"":{""label"":""Sum of weights of products having the id of the first category equal to 12"",""fees"":""{sum product.weight where product.category.id==12}""}
845
  }{/code}
846
  "
847
+ "{os2editor.help.changelog}","
848
  <h4>Changelog</h4>
849
  <div class=changelog>{changelog}</div>
850
  "
app/locale/fr_FR/Owebia_Shipping2.csv CHANGED
@@ -1,244 +1,244 @@
1
  # fr-FR
2
 
3
  # app/code/community/Owebia/Shipping2/Block/Adminhtml/Os2/Editor.php
4
- "New shipping method","Nouvelle méthode de livraison"
5
- "Remove","Supprimer"
6
- "[meta] %s","[meta] %s"
7
- "[data] %s","[data] %s"
8
- # Tools
9
- "Insert","Insérer"
10
- "Tools","Outils"
11
- "Shipping country","Pays de livraison"
12
- "Cart weight","Poids du panier"
13
- "Products quantity","Quantité d'articles"
14
- "Price incl. tax","Prix TTC"
15
- "Price excl. tax","Prix HT"
16
- "Weight","Poids"
17
- "Tracking number","Numéro de suivi"
18
- "Human readable version","Version lisible"
19
- # Fields
20
- "ID","ID"
21
- "Type","Type"
22
- "Shipping Method (default)","Méthode de livraison (par défaut)"
23
- "Data","Données"
24
- "Meta","Méta"
25
- "About","À propos"
26
- "Enabled","Activé"
27
- "Enabled (default)","Activé (par défaut)"
28
- "Disabled","Désactivé"
29
- "Label","Libellé"
30
- "Description","Description"
31
- "Shipping address","Adresse de livraison"
32
- "Billing address","Adresse de facturation"
33
- "Origin address","Adresse d'envoi"
34
- "Conditions","Conditions"
35
- "Fees","Coûts"
36
- "Customer groups","Groupes utilisateur"
37
- "Tracking url","URL de suivi"
38
 
39
  # app/code/community/Owebia/Shipping2/Block/Adminhtml/Os2/Help.php
40
- "Refresh","Rafraîchir"
41
- "Previous page","Page précédente"
42
- "Summary","Sommaire"
43
 
44
  # app/code/community/Owebia/Shipping2/Block/Adminhtml/System/Config/Form/Field/Config.php
45
- "Help","Aide"
46
- "Apply","Appliquer"
47
- "Cancel","Annuler"
48
- "Source &amp; Correction","Source &amp; Correction"
49
- "Download configuration templates","Télécharger des modèles de configuration"
50
- # JS
51
- "Dissociate","Dissocier"
52
- "Remove","Supprimer"
53
- "Edit","Modifier"
54
- "Enter the new value:","Veuillez saisir la nouvelle valeur :"
55
- "[No label]","[Pas de libellé]"
56
- "Loading...","En cours de chargement..."
57
 
58
  # app/code/community/Owebia/Shipping2/Block/Adminhtml/System/Config/Form/Field/Config.php
59
- "Version: %s","Version : %s"
60
 
61
  # app/code/community/Owebia/Shipping2/Controller/Abstract.php
62
- "Owebia Shipping 2 Editor","Éditeur Owebia Shipping 2"
63
- "Source &amp; Correction","Source &amp; Correction"
64
- "Help","Aide"
65
- "Donate","Faire un don"
66
- "Close","Fermer"
67
 
68
  # app/code/community/Owebia/Shipping2/controllers/Adminhtml/Os2/AjaxController.php
69
- "Editor","Éditeur"
70
- "Source","Source"
71
- "Correction","Correction"
72
- "Debug","Debug"
73
- "Apply","Appliquer"
74
- "Export","Exporter"
75
- "Add a shipping method","Ajouter une méthode de livraison"
76
- "New shipping method","Nouvelle méthode de livraison"
77
- "You appreciate this extension and would like to help?","Vous appréciez cette extension et vous aimeriez apporter votre soutien ?"
78
- "{os2editor.donate-page.content}","<p>L'extension Owebia Shipping 2 est développée bénévolement par l'entreprise Owebia (<a href=""http://www.owebia.com/"">http://www.owebia.com/</a>).<br/>Si vous souhaitez soutenir financièrement le développement de l'extension, vous pouvez faire un &laquo;&nbsp;don&nbsp;&raquo;.</p><p>En France, seules certaines associations peuvent recevoir des dons, c'est pourquoi nous ne pouvons recevoir une somme d'argent sans qu'elle soit déclarée.<br/>Pour cela, nous enverrons à chaque &laquo;&nbsp;donateur&nbsp;&raquo; une facture (acquitée) du montant du &laquo;&nbsp;don&nbsp;&raquo;.</p><p>Cela permettra à chacun de garder une trace de ces &laquo;&nbsp;dons&nbsp;&raquo;.</p><p><strong>Pour effectuer un &laquo;&nbsp;don&nbsp;&raquo;, merci d'envoyer un chèque à l'adresse suivante :</strong></p><p class=""owebia-address"">Owebia<br/>4, Rue du Collège<br/>25500 Morteau (France)</p><p><strong>N'oubliez pas de joindre à ce chèque les coordonnées qui doivent figurer sur la facture qui vous sera envoyée.</strong></p><p>Merci à tous les donateurs.</p>"
79
 
80
  # app/code/community/Owebia/Shipping2/etc/system.xml
81
- "Configuration","Configuration"
82
- "Tracking URL","URL de suivi"
83
- "Debug","Debug"
84
- "{debug_help}","Affichage du debug sur le panier lors d'une estimation de livraison"
85
- "Compression","Compression"
86
- "{compression_help}","Compression gz + base64 pour que la configuration prenne moins de place (utile avec certaines configurations). C'est l'éditeur qui effectue la compression/décompression."
87
- "Auto-escaping","Auto-échappement"
88
- "{auto_escaping_help}","Active l'auto-échappement systématique des variables"
89
- "Auto-correction","Auto-correction"
90
- "{auto_correction_help}","Cette option permet la compatibilité rétroactive mais elle consommme des ressources"
91
- "Stop to first match","Arrêt à la première correspondance trouvée"
92
- "General Configuration","Configuration générale"
93
- "Weight unit","Unité de poids"
94
- "Bundle Product Management","Gestion des produits packagés (Bundle Product)"
95
- "Configurable Product Management","Gestion des produits configurables (Configurable Product)"
96
- "If ""Self"" is selected, options bellow are ignored","Si ""Lui-même"" est sélectionné, les options ci-dessous sont ignorées"
97
- "Item processing","Traitement d'un article"
98
- "Item options on","Options de l'article sur"
99
- "Item data on","Données de l'article sur"
100
- "Product data on","Données du produit sur"
101
 
102
  # app/code/community/Owebia/Shipping2/includes/OwebiaShippingHelper.php
103
- "Configuration disabled","Configuration désactivée"
104
- "The cart doesn't match conditions","Le panier ne correspond pas aux conditions"
105
- "Infinite loop %s","Boucle infinie %s"
106
- "Error in table %s","Erreur dans la table %s"
107
- "Usage of deprecated syntax %s","Utilisation d'une syntaxe obsolète %s"
108
- "Usage of unknown properties %s","Utilisation de propriétés non reconnues %s"
109
- "Usage of deprecated properties %s","Utilisation de propriétés obsolètes %s"
110
 
111
  # app/code/community/Owebia/Shipping2/Model/Carrier/Abstract.php
112
- "track the package","suivre le colis"
113
 
114
  # app/code/community/Owebia/Shipping2/Model/Os2/Data/AddressFilter.php
115
- "Africa","Afrique"
116
- "Asia","Asie"
117
- "Europa","Europe"
118
- "North America","Amérique du Nord"
119
- "South America","Amérique du Sud"
120
- "Oceania","Océanie"
121
- "Antartica","Antartique"
122
- "European Union","Union Européenne"
123
 
124
  # app/code/community/Owebia/Shipping2/Model/System/Config/Source/LoadOnParent.php
125
- "Self","Lui-même"
126
- "Parent","Parent"
127
 
128
  # app/code/community/Owebia/Shipping2/Model/System/Config/Source/ProcessChildren.php
129
- "Self","Lui-même"
130
- "Children","Enfants"
131
 
132
  # Help
133
- "{os2editor.help.summary}","
134
  <h4>Sommaire</h4>
135
  <div class=""table-of-contents"">
136
  <table><tr>
137
- <td>
138
- <ol class=level1>
139
- <li class=new><a href=""#introduction"">Introduction : syntaxe JSON, éléments et propriétés</a></li>
140
- <li><a href=""#unique_id"">L'identifiant unique</a></li>
141
- <li class=new>Les types d'éléments :
142
- <ul>
143
- <li><a href=""#type_method""><property>method</property> : méthode de livraison</a></li>
144
- <li><a href=""#type_data""><property>data</property> : données</a></li>
145
- <li><a href=""#type_meta""><property>meta</property> : données méta</a></li>
146
- </ul>
147
- </li>
148
- <li class=new>Les propriétés communes :
149
- <ul>
150
- <li><a href=""#property_type""><property>type</property> : le type de l'élément</a></li>
151
- <li><a href=""#property_about""><property>about</property> : commentaire sur l'élément</a></li>
152
- </ul>
153
- </li>
154
- <li>Les propriétés des éléments <property>method</property> :
155
- <ul>
156
- <li class=important><a href=""#property_label""><property>label</property> : le libellé</a></li>
157
- <li><a href=""#property_description""><property>description</property> : la description</a></li>
158
- <li class=important><a href=""#property_conditions""><property>conditions</property> : les conditions</a></li>
159
- <li class=new><a href=""#property_shipto""><property>shipto</property> : l'adresse de livraison</a> (<property>destination</property> av. 2.4.8)</li>
160
- <li class=new><a href=""#property_shipto""><property>billto</property> : l'adresse de facturation</a> (depuis 2.4.8)</li>
161
- <li><a href=""#property_shipto""><property>origin</property> : l'adresse d'envoi</a></li>
162
- <li><a href=""#property_customer_groups""><property>customer_groups</property> : les groupes client</a></li>
163
- <li class=important><a href=""#property_fees""><property>fees</property> : les frais de port</a></li>
164
- <li><a href=""#property_tracking_url""><property>tracking_url</property> : l'URL de suivi</a> (maj doc 2.4.0)</li>
165
- <li><a href=""#property_enabled""><property>enabled</property> : l'activation/désactivation</a></li>
166
- </ul>
167
- </li>
168
- </ol>
169
- </td>
170
- <td>
171
- <ol class=level1 start=6>
172
- <li><a href=""#more_formulas"">Initiation aux formules</a>
173
- <ol>
174
- <li class=new><a href=""#more_vars"">Les variables disponibles</a></li>
175
- <li class=new><a href=""#more_special-functions"">Fonctions spéciales dans les formules</a> (maj 2.5)<br/>&nbsp; &nbsp; min, max, range, substr, in_array, array_match_any, array_match_all</li>
176
- <li><a href=""#more_copy"">Faire une copie d'une propriété d'un autre élément</a></li>
177
- <li><a href=""#more_tables"">Utilisation des tables <c>table</c></a></li>
178
- <li><a href=""#more_switch"">Utilisation des tables de correspondance <c>switch</c></a> (maj 2.4.5)</li>
179
- <li class=new><a href=""#more_attributes-options"">Utilisation des propriétés des produits (sum, count, min, max)</a> (maj 2.4.8)</li>
180
- <li><a href=""#more_foreach"">Utilisation des boucles <c>foreach</c></a></li>
181
- <li class=new><a href=""#more_categories"">Cas particulier : exemples d'utilisation des catégories de produits</a> (maj 2.5)</li>
182
- </ol>
183
- </li>
184
- <li><a href=""#changelog"">Changelog</a></li>
185
- </ol>
186
- </td>
187
  </tr></table>
188
  </div>
189
  "
190
- "{os2editor.help.introduction}","
191
  <h4>Introduction : syntaxe JSON, éléments et propriétés</h4>
192
  <p class=new>
193
- Si vous souhaitez poser une question, utilisez le sujet suivant sur le forum Magento : <a href=""http://www.magentocommerce.com/boards/viewthread/38223/"" target=_blank>http://www.magentocommerce.com/boards/viewthread/38223/</a>
194
  </p>
195
 
196
  <p>
197
- <strike>La syntaxe de configuration est une syntaxe proche de la syntaxe JSON.</strike><br/>
198
- <span class=new>Depuis la version 2.5, la syntaxe de configuration est 100% <a href=""http://fr.wikipedia.org/wiki/JavaScript_Object_Notation"" target=_blank>JSON</a>.</span>
199
  </p>
200
  <p>
201
- Exemple :
202
  </p>
203
  {code=json}{
204
  ""ex0"":{""about"":""National"",""label"":""National"",""shipto"":""AD,FR,MC"",""conditions"":""{cart.price-tax+discount}<1000.00"",""fees"":""1.30 + {table {cart.weight} in 0.5:5.30, 1.0:6.50, 2.0:7.40, 3.0:8.30, 5.0:10.10}""}
205
  }{/code}
206
 
207
  <p>
208
- La configuration est un objet JSON contenant plusieurs <strong>propriétés</strong>.<br/>
209
- Comme imposé par JSON, chaque propriété a un nom unique, qui servira d'<a href=""#unique_id"">identifiant unique</a>.<br/>
210
- Chaque propriété constitue un <strong>élément</strong> de configuration (qui est également un objet JSON).<br/>
211
  </p>
212
  <p>
213
- Les éléments possèdent tous une propriété <property>type</property>. Celle-ci permet de définir le type de l'élément :
214
  </p>
215
  <ul>
216
- <li><a href=""#type_method""><property>method</property> : méthode de livraison (par défaut si non spécifié)</a></li>
217
- <li><a href=""#type_data""><property>data</property> : données pouvant être utilisées dans une ou plusieurs méthodes de livraison</a></li>
218
- <li><a href=""#type_meta""><property>meta</property> : données informatives</a></li>
219
  </p>
220
  <!--
221
  <p>
222
- Chaque élément peut avoir une propriété <property>about</property>, celle-ci permet de placer un commentaire sur l'élément.
223
  </p>
224
 
225
  <p>
226
- Liste des propriétés d'un élément de type <property>method</property> :
227
  </p>
228
  <ul>
229
- <li><property>label</property> : nom (libellé)</li>
230
- <li><property>description</property> : description (visible seulement si le template l'affiche)</li>
231
- <li><property>enabled</property> : méthode de livraison activée ou non (ex: <c>true</c> ou <c>false</c>)</li>
232
- <li class=new><property>fees</property> : frais de port (ex: <string>""15.00""</string> ou <string>""{table {cart.weight} in 0.5:5.30, 1.0:6.50}""</string> ou <string>""100 * {cart.weight}""</string>)</li>
233
- <li class=new><property>conditions</property> : conditions d'activation (ex: <string>""{cart.weight}&gt;=1.0""</string> ou <string>""{cart.price-tax+discount}&lt;100.00""</string> ou <string>""range({cart.weight},1.0,3.0) and {cart.free_shipping}""</string> ou <string>""{count items where product.attribute.color=='Bleu'}&gt;1 or {count items where item.option.size=='2m'}&gt;2""</string>)</li>
234
- <li class=new><property><strike>destination</strike> shipto</property> : pays (régions, codes postaux) autorisés à la livraison (ex: <string>""FR,DE,US""</string> ou <string>""FR(2A,2B,25000)""</string> ou <string>""FR-(2A,2B)""</string> ou <string>""FR(01,02,39600),CH,DE""</string>)</li>
235
- <li class=new><property>billto</property> : pays (régions, codes postaux) autorisés à la facturation (ex: idem <property>shipto</property>)</li>
236
- <li><property>origin</property> : pays (régions, codes postaux) autorisés en origine (ex: idem <property>shipto</property>)</li>
237
- <li><property>customer_groups</property> : groupes de client autorisés (ex: <string>""NOT LOGGED IN,Retailer""</string> ou <string>""0,3""</string>)</li>
238
  </ul>
239
  -->
240
  "
241
- "{os2editor.help.unique_id}","
242
  <h4>L'identifiant unique</h4>
243
  <p>Chaque élément de configuration possède un identifiant unique. Cet identifiant unique permet ensuite de faire référence à l'élément.</p>
244
  <p>Exemple :</p>
@@ -249,7 +249,7 @@
249
 
250
  <p class=warning><strong><u>Attention</u> :</strong> pour éviter les conflicts, n'utiliser que les caractères <c>a-z</c>, <c>A-Z</c>, <c>0-9</c>, <c>-</c> et <c>_</c> pour former l'identifiant unique.<br/>Vous devez également éviter les identifiants qui correspondent déjà à des noms de variable (<c>cart</c>, <c>product</c>, <c>item</c>…).</p>
251
  "
252
- "{os2editor.help.type_method}","
253
  <h4>Élément de type <property>method</property></h4>
254
  <p>Un élément de type <property>method</property> permet de spécifier une méthode de livraison.</p>
255
  <p>Exemple minimal avec uniquement les propriétés obligatoires :</p>
@@ -261,7 +261,7 @@
261
  ""ex0"":{""about"":""Colissimo National"",""type"":""method"",""label"":""Colissimo"",""description"":""Livraison sous 24/48h"",""enabled"":true,""conditions"":""range({cart.weight},0.2,1.0)"",""shipto"":""FR(01,02,39600,/^25[0-9]{3}$/),CH,DE"",""billto"":""FR"",""origin"":""DE"",""customer_groups"":""NOT LOGGED IN,Retailer"",""fees"":""{table {cart.weight} in 0.5:5.30, 1.0:6.50}""}
262
  }{/code}
263
  "
264
- "{os2editor.help.type_data}","
265
  <h4>Élément de type <property>data</property></h4>
266
  <p>Un élément de type <property>data</property> permet de spécifier des données utilisables dans les méthodes de livraison.</p>
267
  <p>Exemple d'élément de type <property>data</property> :</p>
@@ -273,7 +273,7 @@
273
  ""ex0"":{""type"":""method"",""label"":""Colissimo"",""fees"":""{mydata.reference}*1.5""}
274
  }{/code}
275
  "
276
- "{os2editor.help.type_meta}","
277
  <h4>Élément de type <property>meta</property></h4>
278
  <p>Un élément de type <property>meta</property> permet d'ajouter des données informatives (auteur, date…).</p>
279
  <p>Exemple :</p>
@@ -281,13 +281,13 @@
281
  ""about"":{""type"":""meta"",""author"":""Owebia"",""date"":""16/11/2012"",""about"":""Tarifs 2012""}
282
  }{/code}
283
  "
284
- "{os2editor.help.property_type}","
285
  <h4><property>type</property> : le type de l'élément</h4>
286
  <p>Il permet de spécifier le type de l'élément :</p>
287
  <ul>
288
- <li><a href=""#type_method""><property>method</property> : méthode de livraison (par défaut si non spécifié)</a></li>
289
- <li><a href=""#type_data""><property>data</property> : données pouvant être utilisées dans une ou plusieurs méthodes de livraison</a></li>
290
- <li><a href=""#type_meta""><property>meta</property> : données informatives</a></li>
291
  </ul>
292
  {code=json}{
293
  ""about"":{""type"":""meta"",""author"":""Owebia"",""date"":""16/11/2012"",""about"":""Tarifs 2012""},
@@ -295,44 +295,44 @@
295
  ""ex0"":{""type"":""method"",""label"":""Colissimo"",""fees"":""{mydata.reference}*1.5""}
296
  }{/code}
297
  "
298
- "{os2editor.help.property_about}","
299
  <h4><property>about</property> : commentaire sur l'élément</h4>
300
  <p>Vous pouvez ajouter un commentaire à un élément de configuration.</p>
301
  {code=json}{""ex0"":{""about"":""Mon commentaire"",""label"":""Exemple avec commentaire"",""fees"":10}}{/code}
302
  "
303
- "{os2editor.help.property_label}","
304
  <h4><property>label</property> : le libellé</h4>
305
  <p>Il s'agit du nom qui sera donné à la méthode de livraison.</p>
306
  <p>On peut insérer certains éléments comme le poids des marchandises dans le libellé.<br/>
307
  Pour ce faire, utiliser les variables suivantes :</p>
308
  <ul>
309
- <li>L'adresse de livraison :
310
- <ul>
311
- <li class=new><c><strike>{destination.country.name}</strike> {shipto.country_name}</c> : le nom du pays</li>
312
- <li class=new><c><strike>{destination.country.code}</strike> {shipto.country_id}</c> : le code du pays</li>
313
- <li class=new><c><strike>{destination.region.code}</strike> {shipto.region_code}</c> : le code de la région</li>
314
- <li class=new><c><strike>{destination.postcode}</strike> {shipto.postcode}</c> : le code postal</li>
315
- </ul>
316
- </li>
317
- <li><c>{cart.weight}</c> : poids des marchandises</li>
318
- <li class=new><c><strike>{cart.weight.unit}</strike> {cart.weight_unit}</c> : l'unité de poids</li>
319
- <li><a href=""#more_vars"">Voir la liste complète des variables</a></li>
320
  </ul>
321
  {code=json}{
322
  ""ex0"":{""label"":""Colissimo ({cart.weight} / {shipto.country_name})"",""fees"":10}
323
  }{/code}
324
  <p>La ligne ci-dessus affichera par exemple <string>""Colissimo (3.0kg / France)""</string>.</p>
325
  "
326
- "{os2editor.help.property_description}","
327
  <h4><property>description</property> : la description</h4>
328
  <p>Il s'agit de la description de la méthode de livraison.</p>
329
  <p>Le fonctionnement est identique à la propriété <a href=""#property_label""><property>label</property></a>.</p>
330
  "
331
- "{os2editor.help.property_conditions}","
332
  <h4><property>conditions</property> : les conditions</h4>
333
  <p>
334
- La propriété <property>conditions</property> se spécifie sous la forme d'une <a href=""#more_formulas"">formule (voir l'initiation aux formules)</a>
335
- qui doit retourner une valeur booléenne (<c>true</c> ou <c>false</c>).
336
  </p>
337
 
338
  {code=json}{
@@ -348,24 +348,24 @@ Pour ce faire, utiliser les variables suivantes :</p>
348
  ""ex9"":{""label"":""Si tous les produits possèdent l'option 'size' supérieure ou égal à '1'"",""conditions"":""{count items where product.option.size>='1'}=={cart.qty}"",""fees"":10}
349
  }{/code}
350
  "
351
- "{os2editor.help.property_shipto}","
352
  <h4>Les adresses : <property>shipto</property>, <property>billto</property> et <property>origin</property></h4>
353
  <p>
354
- L'extension permet de filtrer plusieurs adresses :
355
  </p>
356
  <ul>
357
- <li class=new>L'adresse de livraison <strike><property>destination</property></strike> <property>shipto</property>.</li>
358
- <li class=new>L'adresse de facturation <property>billto</property></li>
359
- <li>L'adresse d'origine <property>origin</property></li>
360
  </ul>
361
  <p>
362
- Les codes pays utilisés sont ceux de Magento (à priori ils sont les mêmes que les <a href=""http://fr.wikipedia.org/wiki/ISO_3166-1"" target=_blank>codes ISO 3166-1 alpha-2</a>).<br/>
363
- Il est possible de spécifier les codes régions (uniquement avec <property>shipto</property>) ou les codes postaux que l'on veut filtrer ou exclure.
364
  </p>
365
  <p class=new>
366
- Vous pouvez utiliser le caractère jocker <c>*</c> ou les expressions régulières pour les codes postaux.<br/>
367
- Une expression régulière doit commencer et se terminer par le caractère <c>/</c>. Si vous souhaitez utiliser les caractères <c>(</c>, <c>)</c> ou <c>,</c>, vous devez les échapper avec le caractère <c>\</c> (ex: <string>""FR(/^25\([0-9]{3}\)$/)""</string>).<br/>
368
- Vous pouvez utiliser l'option d'insensibilité à la casse (ex: <string>""GB(/^PO.*$/i)""</string>).
369
  </p>
370
 
371
  {code=json}{
@@ -378,34 +378,34 @@ Pour ce faire, utiliser les variables suivantes :</p>
378
  }{/code}
379
 
380
  <div class=""tips"">
381
- <p><strong>Astuce</strong><br/>Pour raccourcir la saisie des pays, vous pouvez utiliser les variables suivantes :</p>
382
- <ul>
383
- <li><c>{address_filter.AF}</c> : pays d'Afrique</li>
384
- <li><c>{address_filter.AS}</c> : pays d'Asie</li>
385
- <li><c>{address_filter.EU}</c> : pays d'Europe</li>
386
- <li><c>{address_filter.NA}</c> : pays d'Amérique du Nord</li>
387
- <li><c>{address_filter.SA}</c> : pays d'Amérique du Sud</li>
388
- <li><c>{address_filter.OC}</c> : pays d'Océanie</li>
389
- <li><c>{address_filter.AN}</c> : pays d'Antartique</li>
390
- <li><c>{address_filter.EU-27}</c> : pays de l'Union Européenne</li>
391
- <li><c>{address_filter.DOM}</c> : codes pays des département d'Outre-Mer Français</li>
392
- <li><c>{address_filter.COM}</c> : codes pays des Collectivités d'Outre-Mer Françaises</li>
393
- </ul>
394
  </div>
395
 
396
  {code=json}{
397
  ""ex0"":{""label"":""Europe sauf la France"",""shipto"":""({address_filter.EU-27}) - (FR)"",""fees"":10}
398
  }{/code}
399
  "
400
- "{os2editor.help.property_billto}","
401
  <h4><property>billto</property> : l'adresse de facturation</h4>
402
  <p><a href=""#property_shipto"">Filtrage des adresses</a></p>
403
  "
404
- "{os2editor.help.property_origin}","
405
  <h4><property>origin</property> : l'adresse d'envoi</h4>
406
  <p><a href=""#property_shipto"">Filtrage des adresses</a></p>
407
  "
408
- "{os2editor.help.property_customer_groups}","
409
  <h4><property>customer_groups</property> : les groupes client</h4>
410
  <p>On peut utiliser le nom ou l'ID des groupes client.</p>
411
 
@@ -415,10 +415,10 @@ Pour ce faire, utiliser les variables suivantes :</p>
415
  ""ex2"":{""label"":""Groupe Retailer"",""customer_groups"":""Retailer"",""fees"":10}
416
  }{/code}
417
  "
418
- "{os2editor.help.property_fees}","
419
  <h4><property>fees</property> : les frais de port</h4>
420
  <p>
421
- La propriété <property>fees</property> se spécifie sous la forme d'une <a href=""#more_formulas"">formule (voir l'initiation aux formules)</a>.
422
  </p>
423
  {code=json}{
424
  ""ex0"":{""label"":""Frais fixes"",""fees"":10},
@@ -427,16 +427,16 @@ Pour ce faire, utiliser les variables suivantes :</p>
427
  ""ex3"":{""label"":""Combinaison"",""fees"":""0.1 * {cart.price-tax+discount} + {table {cart.weight} in 0.5:5.30, 1.0:6.50} + 10.00""}
428
  }{/code}
429
  "
430
- "{os2editor.help.property_tracking_url}","
431
  <h4><property>tracking_url</property> : l'URL de suivi</h4>
432
  <p class=warning>
433
- <strong>L'utilisation de la propriété <property>tracking_url</property> est réservée aux utilisateurs expérimentés. Si vous ne comprenez pas les indications ci-dessous, il est préférable que vous évitiez d'utiliser cette fonctionnalité.</strong>
434
  </p>
435
  <p>
436
- La propriété <property>tracking_url</property> permet de surcharger le champ ""URL de suivi"" d'un mode de livraison Owebia Shipping et ainsi de spécifier une URL de suivi <strong>par méthode de livraison</strong> plutôt qu'une pour tout le mode de livraison.
437
  </p>
438
  <p>
439
- Pour insérer automatiquement le numéro de colis dans l'URL de suivi, vous devez utiliser <c>{tracking_number}</c>.
440
  </p>
441
 
442
  {code=json}{
@@ -444,21 +444,21 @@ Pour ce faire, utiliser les variables suivantes :</p>
444
  }{/code}
445
 
446
  <p>
447
- Magento ne gère pas les liens de tracking mais un statut de tracking. L'extension Owebia Shipping 2 fournit un lien HTML à la place du statut, lien qui permet d'aller sur le site du transporteur et de suivre l'avancement de la livraison du colis.
448
  </p>
449
  <p>
450
- Lorsque l'URL de suivi est construite par l'extension, la seule information disponible est le numéro de colis et on n'a nul part accès à la méthode de livraison sélectionnée. Afin de pouvoir retrouver l'url de suivi dans la configuration, il faut spécifier la méthode de livraison dans le numéro de tracking, par exemple : <c>colissimo:8Lxxxxxxxxxxx</c> où <c>colissimo</c> est le code de la méthode de livraison sélectionnée.<br/>
451
- Si aucun code n'est spécifié (si vous saisissez uniquement le numéro de tracking), l'url utilisée sera celle globale au mode de livraison.
452
  </p>
453
  <p class=warning>
454
- Pour répondre à une question récurrente, Magento affiche le statut de livraison depuis le back office ou le front office. <strong>Si vous souhaitez insérer l'URL de suivi dans les mails d'expédition, vous devrez développer vous même la récupération de l'URL de suivi et son insertion dans le mail, en effet, l'extension Owebia Shipping 2 se contente de fournir des modes de livraison paramétrables sans apporter de grande modification au coeur de Magento afin de réduire les problèmes d'incompatibilité et de mise à jour.</strong>
455
  </p>
456
  <p class=warning>
457
- Si vous obtenez un popup vide lorsque vous cliquez sur le lien de suivi, votre problème est très certainement lié au fait que vous n'avez pas spécifié le code de la méthode de livraison dans le numéro de suivi (voir indications plus haut) et que votre champ global ""URL de suivi"" est vide.
458
  </p>
459
  <p class=warning>Il n'est actuellement pas prévu de modifier les fonctionnalitées de l'extension liées à l'URL de suivi.</p>
460
  "
461
- "{os2editor.help.property_enabled}","
462
  <h4><property>enabled</property> : l'activation/désactivation</h4>
463
  <p>Permet d'activer ou de désactiver la méthode de livraison.</p>
464
  <p>La valeur doit être booléenne.</p>
@@ -466,157 +466,157 @@ Pour ce faire, utiliser les variables suivantes :</p>
466
  ""ex0"":{""enabled"":true,""label"":""Exemple avec activation"",""fees"":10}
467
  }{/code}
468
  "
469
- "{os2editor.help.more_formulas}","
470
  <h4>Initiation aux formules</h4>
471
  <p>
472
- Les propriétés <property>fees</property> et <property>conditions</property> sont spécifiées sous la forme de formules.
473
  </p>
474
  <p>
475
- Signes mathématiques disponibles :
476
  </p>
477
  <ul>
478
- <li>opérateurs : <c>*</c>, <c>/</c>, <c>+</c> et <c>-</c></li>
479
- <li>modulo : <c>%</c></li>
480
- <li>parenthèses : <c>(</c> et <c>)</c></li>
481
- <li>les opérateurs booléens <c>&amp;&amp;</c>, <c>and</c>, <c>||</c>, <c>or</c>, <c>==</c>, <c>&lt;</c>, <c>&gt;</c>, <c>&lt;=</c>, <c>&gt;=</c></li>
482
- <li>les opérateurs binaires <c>&amp;</c> et <c>|</c></li>
483
- <li>le groupe d'opérateur <c>C ? X : Y</c> (ex: <c><span class=string>""{cart.price_exluding_tax}&gt;100 ? 15*{cart.weight} : 20*{cart.weight}""</span></c>)</li>
484
  </ul>
485
  <p>
486
- Variables disponibles :
487
  </p>
488
  <ul>
489
- <li><c>{cart.weight}</c> : poids des marchandises</li>
490
- <li><c class=new><strike>{cart.quantity}</strike> {cart.qty}</c> : nombre d'articles dans le panier</li>
491
- <li><c class=new><strike>{cart.price_excluding_tax}</strike> {cart.price-tax+discount}</c> : prix HT après remise</li>
492
- <li><c class=new><strike>{cart.price_including_tax}</strike> {cart.price+tax+discount}</c> : prix TTC après remise</li>
493
- <li><c>{cart.price-tax-discount}</c> : prix HT avant remise</li>
494
- <li><c>{cart.price+tax-discount}</c> : prix TTC avant remise</li>
495
- <li><a href=""#more_vars"">Voir la liste complète des variables</a></li>
496
  </ul>
497
  <p>
498
- Vous avez la possibilité de mettre des espaces et des retours à la ligne dans les formules (pour aérer).
499
  </p>
500
  <p>
501
- Fonctions disponibles :
502
  </p>
503
  <ul>
504
- <li>arrondis : <c>round(x)</c>, <c>floor(x)</c>, <c>ceil(x)</c></li>
505
- <li>valeur absolue : <c>abs(x)</c></li>
506
- <li>maximum : <c>max(x,y)</c></li>
507
- <li>minimum : <c>min(x,y)</c></li>
508
- <li>entier aléatoire : <c>rand(min,max)</c></li>
509
- <li>puissance : <c>pow(x,puissance)</c></li>
510
- <li>nombre PI : <c>pi()</c></li>
511
- <li>racine carrée : <c>sqrt(x)</c></li>
512
- <li>logarithme : <c>log(x)</c> pour le logarithme népérien ou <c>log(x,base)</c></li>
513
- <li>exponentiel : <c>exp(x)</c></li>
514
  </ul>
515
  <p>
516
- Possibilité d'utiliser les fonctionnalités avancées suivantes : casting en entier <c>(int)</c> ou en nombre flottant <c>(float)</c>,
517
- comparaison avec la valeur <c>null</c> ou les valeurs booléennes <c>true</c> et <c>false</c>.
518
  </p>
519
  <p class=new style=""font-weight: bold;"">
520
- 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,
521
- les fonctions spéciales, l'utilisation des attributs et des options des produits ou encore l'utilisation des variables personnalisées.
522
  </p>
523
  <p class=new style=""font-weight: bold;"">
524
- 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 <c>{{ }}</c>.
525
  </p>
526
  {code=json}{
527
  ""ex0"":{""label"":""Échappement avec des guillemets"",""conditions"":""'{cart.coupon_code}'=='test'"",""fees"":10},
528
  ""ex1"":{""about"":""Depuis la version 2.4.5, {{cart.coupon_code}} sera remplacé par 'moncoupon' ou par null en fonction de sa valeur"",""label"":""Auto-échappement"",""conditions"":""{{cart.coupon_code}}!='test'"",""fees"":10}
529
  }{/code}
530
  "
531
- "{os2editor.help.more_vars}","
532
  <h4>Les variables disponibles</h4>
533
  <p>
534
- Les variables suivantes peuvent être utilisées dans les différents propriétés des méthodes de livraison (en particulier les propriétés <property>conditions</property> et <property>fees</property>).
535
  </p>
536
  <ul>
537
- <li>Le panier :
538
- <ul>
539
- <li><c>{cart.weight}</c> : poids des marchandises</li>
540
- <li><c class=new><strike>{cart.quantity}</strike> {cart.qty}</c> : la quantité d'articles</li>
541
- <li class=new><c><strike>{cart.price_excluding_tax}</strike> {cart.price-tax+discount}</c> : prix HT avec remise</li>
542
- <li class=new><c><strike>{cart.price_including_tax}</strike> {cart.price+tax+discount}</c> : prix TTC avec remise</li>
543
- <li class=new><c>{cart.price-tax-discount}</c> : prix HT sans remise</li>
544
- <li class=new><c>{cart.price+tax-discount}</c> : prix TTC sans remise</li>
545
- <li class=new><c><strike>{cart.coupon}</strike> {cart.coupon_code}</c> : coupon de réduction</li>
546
- <li><c class=new><strike>{free_shipping}</strike> {cart.free_shipping}</c> : frais de port offert (par une règle dans Magento) [true/false]</li>
547
- <li><c class=new><strike>{cart.weight.unit}</strike> {cart.weight_unit}</c> : l'unité de poids</li>
548
- <li><c class=new><strike>{cart.weight.for-charge}</strike> {cart.weight_for_charge}</c> : poids des marchandises dont la livraison n'est pas offerte (par les règles de prix panier de Magento)</li>
549
- </ul>
550
- </li>
551
- <li class=new>Le group client :
552
- <ul>
553
- <li><c><strike>{customer.group.id}</strike> {customer_group.id}</c> : id du groupe client</li>
554
- <li><c><strike>{customer.group.code}</strike> {customer_group.code}</c> : nom du groupe client</li>
555
- <li><c>{customer_group.*}</c> : propriété du groupe client (ex: <c>{customer_group.tax_class_id}</c>)</li>
556
- </ul>
557
- </li>
558
- <li class=new>Le client :
559
- <ul>
560
- <li><c>{customer.id}</c> : id du client</li>
561
- <li><c>{customer.attribute.*}</c> : attribut du client (ex: lastname, firstname, group_id…)</li>
562
- <li class=new><c>{customer.attribute.*.value}</c> : dans le cas des attributs de type liste de sélection, <c>{customer.attribute.*}</c> retourne l'id, pour obtenir la valeur il faut utiliser <c>{customer.attribute.*.value}</c></li>
563
- <li><c>{customer.*}</c> : identique à <c>{customer.attribute.*}</c>, sauf si la variable est déjà définie (ex: <c>{customer.id}</c> est déjà définie)</li>
564
- </ul>
565
- </li>
566
- <li class=new>Les variables personnalisées ou `Custom Variables` (depuis la version 1.4.0.1 de Magento) :
567
- <ul>
568
- <li><c>{customvar.*}</c> : variable personnalisée de Magento (ex: <c>{customvar.my_var}</c>)</li>
569
- <li><c><strike>{{customVar code=*}}</strike></c> : utiliser la syntaxe ci-dessus</li>
570
- </ul>
571
- </li>
572
- <li>L'adresse de livraison :
573
- <ul>
574
- <li><c class=new><strike>{destination.country.name}</strike> {shipto.country_name}</c> : le nom du pays</li>
575
- <li><c class=new><strike>{destination.country.code}</strike> {shipto.country_id}</c> : le code du pays</li>
576
- <li class=new><c>{shipto.region_id}</c> : l'id de la région</li>
577
- <li><c class=new><strike>{destination.region.code}</strike> {shipto.region_code}</c> : le code de la région</li>
578
- <li class=new><c>{shipto.street}</c> : la rue</li>
579
- <li class=new><c>{shipto.city}</c> : la ville</li>
580
- <li><c class=new><strike>{destination.postcode}</strike> {shipto.postcode}</c> : le code postal</li>
581
- </ul>
582
- </li>
583
- <li class=new>L'adresse de facturation :
584
- <ul>
585
- <li><c>{billto.country_name}</c> : le nom du pays</li>
586
- <li><c>{billto.country_id}</c> : le code du pays</li>
587
- <li><c>{billto.postcode}</c> : le code postal</li>
588
- <li><c>{billto.*}</c> : propriété de l'adresse de facturation (ex: <c>{billto.city}</c>)</li>
589
- </ul>
590
- </li>
591
- <li>L'adresse d'envoi :
592
- <ul>
593
- <li><c class=new><strike>{origin.country.name}</strike> {origin.country_name}</c> : le nom du pays</li>
594
- <li><c class=new><strike>{origin.country.code}</strike> {origin.country_id}</c> : le code du pays</li>
595
- <li><c class=new><strike>{origin.region.code}</strike> {origin.region_id}</c> : l'id de la région</li>
596
- <li class=new><c>{origin.city}</c> : la ville</li>
597
- <li><c>{origin.postcode}</c> : le code postal</li>
598
- </ul>
599
- </li>
600
- <li>Le magasin :
601
- <ul>
602
- <li><c>{store.id}</c> <c>{store.code}</c> <c>{store.name}</c> <c>{store.address}</c> <c>{store.phone}</c> : id, code, nom, adresse et téléphone du magasin</li>
603
- </ul>
604
- </li>
605
- <li>La date courante :
606
- <ul>
607
- <li><c>{date.timestamp}</c> : timestamp UNIX de la date actuelle</li>
608
- <li><c>{date.year}</c> <c>{date.month}</c> <c>{date.day}</c> <c>{date.hour}</c> <c>{date.minute}</c> <c>{date.second}</c> : année, mois, jour, heure, minute et seconde de la date actuelle</li>
609
- <li><c>{date.weekday}</c> : jour de la semaine de la date actuelle de 0 (dimanche) à 6 (samedi)</li>
610
- </ul>
611
- </li>
612
- <li class=new>L'objet <c>request</c> :
613
- <ul>
614
- <li><c>{request.*}</c> : propriété de l'objet request (Mage_Shipping_Model_Rate_Request) passé en paramètre par Magento (ex: <c>{request.package_qty}</c>). Utiliser l'option ""Déboguage"" pour obtenir plus de détail sur les propriétés disponibles.</li>
615
- </ul>
616
- </li>
617
  </ul>
618
  "
619
- "{os2editor.help.more_special-functions}","
620
  <h4>Fonctions spéciales dans les formules</h4>
621
 
622
  <p>
@@ -626,13 +626,13 @@ Vous pouvez utiliser dans les formules des fonctions spéciales.
626
  Liste des fonctions spéciales :
627
  </p>
628
  <ul>
629
- <li><c>min(x, y, …)</c> : calcule le minimum entre plusieurs valeurs (éventuellement plus de deux valeurs). Si l'une des valeurs est nulle, elle est ignorée.</li>
630
- <li><c>max(x, y, …)</c> : calcule le maximum entre plusieurs valeurs (éventuellement plus de deux valeurs). Si l'une des valeurs est nulle, elle est ignorée.</li>
631
- <li class=new><c>range(value, min, max, include_min, include_max)</c> : retourne <c>true</c> si <c>value</c> est comprise entre <c>min</c> et <c>max</c>. Par défaut, <c>include_min</c> et <c>include_max</c> sont égales à <c>true</c>.</li>
632
- <li class=new><c>substr(string, start, length)</c> : retourne un segment de chaîne de caractères.</li>
633
- <li class=new><c>in_array(value, array(value1, value2, …))</c> : indique si une valeur appartient à un tableau.</li>
634
- <li class=new><c>array_match_any(array(value1, value2, …), array(value1, value2, …))</c> : indique si au moins une valeur est présente dans les deux tableaux.</li>
635
- <li class=new><c>array_match_all(array(value1, value2, …), array(value1, value2, …))</c> : indique si le contenu des tableaux est identique.</li>
636
  </ul>
637
 
638
  {code=json}{
@@ -646,10 +646,10 @@ Liste des fonctions spéciales :
646
  }{/code}
647
 
648
  <p class=new>
649
- * Concernant l'échappement des chaînes de caractères, se référer à l'<a href=""#more_formulas"">initiation aux formules</a>.
650
  </p>
651
  "
652
- "{os2editor.help.more_copy}","
653
  <h4>Faire une copie d'une propriété d'un autre élément</h4>
654
  <p>Il est possible de faire une copie d'une propriété dans un autre élément à l'aide de la syntaxe ci-dessous.</p>
655
  <p>Vous pouvez utiliser cette technique dans toutes les propriétés (<property>conditions</property>, <property>fees</property>, …).</p>
@@ -660,10 +660,10 @@ Liste des fonctions spéciales :
660
  ""ex2"":{""label"":""Copie des frais de port d'une autre méthode"",""fees"":""({colissimo.fees}) + 15.00""}
661
  }{/code}
662
  "
663
- "{os2editor.help.more_tables}","
664
  <h4>Utilisation des tables <c>table</c></h4>
665
  <p>
666
- Dans une <c>table</c>, on peut inclure ou exclure une valeur limite avec les caractères <c>[</c> et <c>]</c> :
667
  </p>
668
  {code=json}{
669
  ""f0"":{""label"":""Limite supérieure incluse"",""fees"":""{table {cart.weight} in 1.0]:5.00}""},
@@ -671,8 +671,8 @@ Liste des fonctions spéciales :
671
  }{/code}
672
 
673
  <p>
674
- Dans une <c>table</c>, on doit spécifier la valeur de référence. Pour cela, on peut utiliser une des <a href=""#more_vars"">variables disponibles</a>.<br/>
675
- Vous pouvez aussi utiliser une formule afin de définir une autre variable de référence.
676
  </p>
677
 
678
  {code=json}{
@@ -683,12 +683,12 @@ Liste des fonctions spéciales :
683
  ""ex4"":{""label"":""Table avec valeur personnalisée"",""fees"":""{table ceil({cart.weight}/10) in 1:5.30, 2:6.50}""}
684
  }{/code}
685
  "
686
- "{os2editor.help.more_switch}","
687
  <h4>Utilisation des tables de correspondance <c>switch</c></h4>
688
 
689
  <p>
690
- Dans un <c>switch</c>, on doit spécifier la valeur de référence. Pour cela, on peut utiliser une des <a href=""#more_vars"">variables disponibles</a>.<br/>
691
- Vous pouvez aussi utiliser une formule afin de définir une autre variable de référence.
692
  </p>
693
 
694
  {code=json}{
@@ -696,81 +696,81 @@ Liste des fonctions spéciales :
696
  ""ex1"":{""label"":""Table de correspondance avec le pays de livraison"",""fees"":""{switch {{shipto.country_id}} in 'FR':5.30, 'BE':6.50, 'DE':10.00, *:7.50}""}
697
  }{/code}
698
  "
699
- "{os2editor.help.more_attributes-options}","
700
  <h4>Utilisation des propriétés des produits</h4>
701
 
702
  <p class=new>
703
- Afin de mieux correspondre aux Models de Magento, la version 2.4.8 de l'extension introduit la séparation entre les objects <c>item</c> et <c>product</c>.
704
- Un <c>item</c> est une déclinaison d'un <c>product</c> auquel on a ajouté d'éventuelles options. Chaque <c>item</c> a une quantité.
705
  </p>
706
  <p>
707
- Liste des propriétés disponibles :
708
  </p>
709
  <ul>
710
- <li class=new>L'article (ou <c>item</c>) :
711
- <ul>
712
- <li><c>item.qty</c> : quantité dans le panier</li>
713
- <li><c>item.price-tax+discount</c> : le prix HT avec remise</li>
714
- <li><c>item.price-tax-discount</c> : le prix HT sans remise</li>
715
- <li><c>item.price+tax+discount</c> : le prix TTC avec remise</li>
716
- <li><c>item.price+tax-discount</c> : le prix TTC sans remise</li>
717
- <li><c>item.option.*</c> : option (la liste des options disponibles dépendra des produits)</li>
718
- </ul>
719
- </li>
720
- <li>Le produit (ou <c>product</c>) :
721
- <ul>
722
- <li><c><strike>product.quantity</strike></c> : utiliser <c class=new>item.qty</c></li>
723
- <li><c>product.attribute.*</c> : attribut<br/>Liste d'attributs intéressants :
724
- <ul>
725
- <li><c>sku</c> : la référence</li>
726
- <li><c>name</c> : le nom</li>
727
- <li><c>weight</c> : le poids</li>
728
- <li><c>price</c> : le prix (tel qu'il a été saisi sur la fiche du produit)</li>
729
- <li><c>special_price</c> : le prix promotionnel (tel qu'il a été saisi sur la fiche du produit)</li>
730
- <li><c><strike>price-tax+discount</strike></c> : utiliser <c class=new>item.price-tax+discount</c></li>
731
- <li><c><strike>price-tax-discount</strike></c> : utiliser <c class=new>item.price-tax-discount</c></li>
732
- <li><c><strike>price+tax+discount</strike></c> : utiliser <c class=new>item.price+tax+discount</c></li>
733
- <li><c><strike>price+tax-discount</strike></c> : utiliser <c class=new>item.price+tax-discount</c></li>
734
- </ul>
735
- </li>
736
- <li class=new><c>product.attribute.*.value</c> : valeur de l'attribut<br/>Dans le cas des attributs de type liste de sélection, <c>product.attribute.*</c> retourne l'id. Pour obtenir la valeur, il faut utiliser <c>product.attribute.*.value</c></li>
737
- <li class=new><c>product.*</c> : identique à <c>product.attribute.*</c> sauf si la variable est définie (ex: <c>product.category</c>)</li>
738
- <li><c><strike>product.option.*</strike></c> : utiliser les propriétés <c class=new>item.option.*</c></li>
739
- <li>Première catégorie du produit :
740
- <ul>
741
- <li><c>product.category</c> : nom de la catégorie</li>
742
- <li><c>product.category.id</c> : id de la catégorie</li>
743
- <li class=new><c>product.category.*</c> : attribut de la catégorie (ex: <c>product.category.is_active</c>)<br/>Liste d'attributs intéressants :
744
- <ul>
745
- <li><c>is_active</c> : catégorie activée ou non</li>
746
- <li><c>name</c> : nom</li>
747
- <li>…</li>
748
- </ul>
749
- </li>
750
- </ul>
751
- </li>
752
- <li>Toutes les catégories du produit (retourne un tableau, <a href=""#more_categories"">rubrique explicative</a>) :
753
- <ul>
754
- <li><c>product.categories</c> : tableau du nom des catégories</li>
755
- <li><c>product.categories.id</c> : tableau de l'id des catégories</li>
756
- </ul>
757
- </li>
758
- <li>Le jeu d'attributs du produit :
759
- <ul>
760
- <li><c>product.attribute_set</c> : nom du jeu d'attributs</li>
761
- <li><c>product.attribute_set.id</c> : id du jeu d'attributs</li>
762
- <li class=new><c>product.attribute_set.*</c> : attribut du jeu d'attributs (ex: <c>product.attribute_set.attribute_set_name</c>)</li>
763
- </ul>
764
- </li>
765
- <li class=new><c>product.stock.*</c> : attribut du stock du produit<br/>Liste d'attributs intéressants :
766
- <ul>
767
- <li><c>is_in_stock</c> : disponibilité du produit</li>
768
- <li><c>qty</c> : stock du produit</li>
769
- <li>…</li>
770
- </ul>
771
- </li>
772
- </ul>
773
- </li>
774
  </ul>
775
 
776
  {code=json}{
@@ -787,17 +787,17 @@ Liste des fonctions spéciales :
787
  Liste des préfixes possibles :
788
  </p>
789
  <ul>
790
- <li><c>count</c> : nombre (toujours suivi de <c>items</c>)</li>
791
- <li><c>count distinct</c> : nombre distinct (toujours suivi d'une propriété)</li>
792
- <li><c>sum</c> : somme (toujours suivi d'une propriété)</li>
793
- <li class=new><c>min</c> : minimum (toujours suivi d'une propriété)</li>
794
- <li class=new><c>max</c> : maximum (toujours suivi d'une propriété)</li>
795
  </ul>
796
  <p>
797
- Il est possible de spécifier des conditions que doivent remplir les produits pour être pris en compte. Pour cela, il suffit d'ajouter <c> where </c> suivi d'une formule.
798
  </p>
799
  <p>
800
- Si la propriété est de type <strong>Oui/Non</strong>, vous devez utiliser les valeurs <c>true</c>/<c>false</c> ou <c>1</c>/<c>0</c> sans les guillemets.
801
  </p>
802
  {code=json}{
803
  ""ex0"":{""label"":""Exemple propriété de type Oui/Non : 0"",""conditions"":""{count items where product.attribute.colissimo_allowed==0}"",""fees"":10},
@@ -805,7 +805,7 @@ Liste des préfixes possibles :
805
  }{/code}
806
 
807
  <p>
808
- Si la propriété est de type <strong>Liste de sélection</strong> et que vous souhaitez faire une comparaison avec <strike>l'id</strike> la valeur plutôt qu'avec <strike>la valeur</strike> l'id, vous devez utiliser la syntaxe suivante :</strike>
809
  </p>
810
  <strike>{code=json}{
811
  ""ex0"":{""label"":""Si l'attribut 'color' est égale à la valeur dont l'id différente de 1"",""conditions"":""{count items where product.color.id!=1}"",""fees"":10}
@@ -814,27 +814,27 @@ Liste des préfixes possibles :
814
  ""ex0"":{""label"":""Si la valeur de l'attribut 'color' est différente de 'Bleu'"",""conditions"":""{count items where product.color.value!='Bleu'}"",""fees"":10}
815
  }{/code}
816
  "
817
- "{os2editor.help.more_foreach}","
818
  <h4>Utilisation des boucles <c>foreach</c></h4>
819
 
820
  <p>
821
- Les boucles <c>foreach</c> permettent d'effectuer un calcul sur des groupes de produits plutôt que de tenir compte de tous les produits du panier.<br/>
822
- Le résultat global d'une boucle <c>foreach</c> est la somme des résultats de chaque passage dans la boucle.
823
  </p>
824
  <p>
825
- A l'intérieur d'une boucle <c>foreach</c>, il est possible d'utiliser de nouvelles variables :
826
  </p>
827
  <ul>
828
- <li><c>{selection.weight}</c> : poids de la sélection</li>
829
- <li><c class=new><strike>{selection.quantity}</strike> {selection.qty}</c> : nombre d'articles dans la sélection</li>
830
  </ul>
831
  <p>
832
- Lorsque la sélection se fait sur le sku, chaque sélection est composée d'un seul article. On peut donc utiliser d'autres variables :
833
  </p>
834
  <ul>
835
- <li><c>{item.*}</c> : propriété de l'article</li>
836
- <li><c>{product.*}</c> : propriété du produit</li>
837
- <li><a href=""#more_attributes-options"">Voir la liste complète des propriétés produit</a></li>
838
  </ul>
839
 
840
  {code=json}{
@@ -842,20 +842,20 @@ Liste des préfixes possibles :
842
  ""ex1"":{""label"":""Calcul des frais de port par produit"",""fees"":""{foreach product.attribute.sku}{product.attribute.shipping}*{item.qty}{/foreach}""}
843
  }{/code}
844
  "
845
- "{os2editor.help.more_categories}","
846
  <h4>Cas particulier : exemples d'utilisation des catégories de produits</h4>
847
 
848
  <p>
849
- Depuis la version 2.4.2, il est possible d'utiliser les catégories des produits dans les formules.
850
  </p>
851
  <p class=warning>
852
- <strong>Attention, il est à noter que dans Magento, un produit peut être dans plusieurs catégories.</strong> Faites donc particulièrement attention à la façon dont vous utilisez cette propriété.
853
  </p>
854
  <p>
855
- Pour filtrer les produits qui se trouvent dans plusieurs catégories spécifiques, vous pouvez utiliser la fonction <c>array_match_any()</c>.
856
  </p>
857
  <p>
858
- Voici quelques exemples d'utilisation :
859
  </p>
860
  {code=json}{
861
  ""ex0"":{""label"":""Boucle foreach dont l'itération se fait sur la catégorie"",""fees"":""{foreach product.categories}{selection.weight}{/foreach}""},
@@ -868,7 +868,7 @@ Liste des préfixes possibles :
868
  ""ex7"":{""label"":""Somme des poids des produits dont l'id de la première catégorie est 12"",""fees"":""{sum product.weight where product.category.id==12}""}
869
  }{/code}
870
  "
871
- "{os2editor.help.changelog}","
872
  <h4>Changelog</h4>
873
  <div class=changelog>{changelog}</div>
874
  "
1
  # fr-FR
2
 
3
  # app/code/community/Owebia/Shipping2/Block/Adminhtml/Os2/Editor.php
4
+ "New shipping method","Nouvelle méthode de livraison"
5
+ "Remove","Supprimer"
6
+ "[meta] %s","[meta] %s"
7
+ "[data] %s","[data] %s"
8
+ # Tools
9
+ "Insert","Insérer"
10
+ "Tools","Outils"
11
+ "Shipping country","Pays de livraison"
12
+ "Cart weight","Poids du panier"
13
+ "Products quantity","Quantité d'articles"
14
+ "Price incl. tax","Prix TTC"
15
+ "Price excl. tax","Prix HT"
16
+ "Weight","Poids"
17
+ "Tracking number","Numéro de suivi"
18
+ "Human readable version","Version lisible"
19
+ # Fields
20
+ "ID","ID"
21
+ "Type","Type"
22
+ "Shipping Method (default)","Méthode de livraison (par défaut)"
23
+ "Data","Données"
24
+ "Meta","Méta"
25
+ "About","À propos"
26
+ "Enabled","Activé"
27
+ "Enabled (default)","Activé (par défaut)"
28
+ "Disabled","Désactivé"
29
+ "Label","Libellé"
30
+ "Description","Description"
31
+ "Shipping address","Adresse de livraison"
32
+ "Billing address","Adresse de facturation"
33
+ "Origin address","Adresse d'envoi"
34
+ "Conditions","Conditions"
35
+ "Fees","Coûts"
36
+ "Customer groups","Groupes utilisateur"
37
+ "Tracking url","URL de suivi"
38
 
39
  # app/code/community/Owebia/Shipping2/Block/Adminhtml/Os2/Help.php
40
+ "Refresh","Rafraîchir"
41
+ "Previous page","Page précédente"
42
+ "Summary","Sommaire"
43
 
44
  # app/code/community/Owebia/Shipping2/Block/Adminhtml/System/Config/Form/Field/Config.php
45
+ "Help","Aide"
46
+ "Apply","Appliquer"
47
+ "Cancel","Annuler"
48
+ "Source &amp; Correction","Source &amp; Correction"
49
+ "Download configuration templates","Télécharger des modèles de configuration"
50
+ # JS
51
+ "Dissociate","Dissocier"
52
+ "Remove","Supprimer"
53
+ "Edit","Modifier"
54
+ "Enter the new value:","Veuillez saisir la nouvelle valeur :"
55
+ "[No label]","[Pas de libellé]"
56
+ "Loading...","En cours de chargement..."
57
 
58
  # app/code/community/Owebia/Shipping2/Block/Adminhtml/System/Config/Form/Field/Config.php
59
+ "Version: %s","Version : %s"
60
 
61
  # app/code/community/Owebia/Shipping2/Controller/Abstract.php
62
+ "Owebia Shipping 2 Editor","Éditeur Owebia Shipping 2"
63
+ "Source &amp; Correction","Source &amp; Correction"
64
+ "Help","Aide"
65
+ "Donate","Faire un don"
66
+ "Close","Fermer"
67
 
68
  # app/code/community/Owebia/Shipping2/controllers/Adminhtml/Os2/AjaxController.php
69
+ "Editor","Éditeur"
70
+ "Source","Source"
71
+ "Correction","Correction"
72
+ "Debug","Debug"
73
+ "Apply","Appliquer"
74
+ "Export","Exporter"
75
+ "Add a shipping method","Ajouter une méthode de livraison"
76
+ "New shipping method","Nouvelle méthode de livraison"
77
+ "You appreciate this extension and would like to help?","Vous appréciez cette extension et vous aimeriez apporter votre soutien ?"
78
+ "{os2editor.donate-page.content}","<p>L'extension Owebia Shipping 2 est développée bénévolement par l'entreprise Owebia (<a href=""http://www.owebia.com/"">http://www.owebia.com/</a>).<br/>Si vous souhaitez soutenir financièrement le développement de l'extension, vous pouvez faire un &laquo;&nbsp;don&nbsp;&raquo;.</p><p>En France, seules certaines associations peuvent recevoir des dons, c'est pourquoi nous ne pouvons recevoir une somme d'argent sans qu'elle soit déclarée.<br/>Pour cela, nous enverrons à chaque &laquo;&nbsp;donateur&nbsp;&raquo; une facture (acquitée) du montant du &laquo;&nbsp;don&nbsp;&raquo;.</p><p>Cela permettra à chacun de garder une trace de ces &laquo;&nbsp;dons&nbsp;&raquo;.</p><p><strong>Pour effectuer un &laquo;&nbsp;don&nbsp;&raquo;, merci d'envoyer un chèque à l'adresse suivante :</strong></p><p class=""owebia-address"">Owebia<br/>4, Rue du Collège<br/>25500 Morteau (France)</p><p><strong>N'oubliez pas de joindre à ce chèque les coordonnées qui doivent figurer sur la facture qui vous sera envoyée.</strong></p><p>Merci à tous les donateurs.</p>"
79
 
80
  # app/code/community/Owebia/Shipping2/etc/system.xml
81
+ "Configuration","Configuration"
82
+ "Tracking URL","URL de suivi"
83
+ "Debug","Debug"
84
+ "{debug_help}","Affichage du debug sur le panier lors d'une estimation de livraison"
85
+ "Compression","Compression"
86
+ "{compression_help}","Compression gz + base64 pour que la configuration prenne moins de place (utile avec certaines configurations). C'est l'éditeur qui effectue la compression/décompression."
87
+ "Auto-escaping","Auto-échappement"
88
+ "{auto_escaping_help}","Active l'auto-échappement systématique des variables"
89
+ "Auto-correction","Auto-correction"
90
+ "{auto_correction_help}","Cette option permet la compatibilité rétroactive mais elle consommme des ressources"
91
+ "Stop to first match","Arrêt à la première correspondance trouvée"
92
+ "General Configuration","Configuration générale"
93
+ "Weight unit","Unité de poids"
94
+ "Bundle Product Management","Gestion des produits packagés (Bundle Product)"
95
+ "Configurable Product Management","Gestion des produits configurables (Configurable Product)"
96
+ "If ""Self"" is selected, options bellow are ignored","Si ""Lui-même"" est sélectionné, les options ci-dessous sont ignorées"
97
+ "Item processing","Traitement d'un article"
98
+ "Item options on","Options de l'article sur"
99
+ "Item data on","Données de l'article sur"
100
+ "Product data on","Données du produit sur"
101
 
102
  # app/code/community/Owebia/Shipping2/includes/OwebiaShippingHelper.php
103
+ "Configuration disabled","Configuration désactivée"
104
+ "The cart doesn't match conditions","Le panier ne correspond pas aux conditions"
105
+ "Infinite loop %s","Boucle infinie %s"
106
+ "Error in table %s","Erreur dans la table %s"
107
+ "Usage of deprecated syntax %s","Utilisation d'une syntaxe obsolète %s"
108
+ "Usage of unknown properties %s","Utilisation de propriétés non reconnues %s"
109
+ "Usage of deprecated properties %s","Utilisation de propriétés obsolètes %s"
110
 
111
  # app/code/community/Owebia/Shipping2/Model/Carrier/Abstract.php
112
+ "track the package","suivre le colis"
113
 
114
  # app/code/community/Owebia/Shipping2/Model/Os2/Data/AddressFilter.php
115
+ "Africa","Afrique"
116
+ "Asia","Asie"
117
+ "Europa","Europe"
118
+ "North America","Amérique du Nord"
119
+ "South America","Amérique du Sud"
120
+ "Oceania","Océanie"
121
+ "Antartica","Antartique"
122
+ "European Union","Union Européenne"
123
 
124
  # app/code/community/Owebia/Shipping2/Model/System/Config/Source/LoadOnParent.php
125
+ "Self","Lui-même"
126
+ "Parent","Parent"
127
 
128
  # app/code/community/Owebia/Shipping2/Model/System/Config/Source/ProcessChildren.php
129
+ "Self","Lui-même"
130
+ "Children","Enfants"
131
 
132
  # Help
133
+ "{os2editor.help.summary}","
134
  <h4>Sommaire</h4>
135
  <div class=""table-of-contents"">
136
  <table><tr>
137
+ <td>
138
+ <ol class=level1>
139
+ <li class=new><a href=""#introduction"">Introduction : syntaxe JSON, éléments et propriétés</a></li>
140
+ <li><a href=""#unique_id"">L'identifiant unique</a></li>
141
+ <li class=new>Les types d'éléments :
142
+ <ul>
143
+ <li><a href=""#type_method""><property>method</property> : méthode de livraison</a></li>
144
+ <li><a href=""#type_data""><property>data</property> : données</a></li>
145
+ <li><a href=""#type_meta""><property>meta</property> : données méta</a></li>
146
+ </ul>
147
+ </li>
148
+ <li class=new>Les propriétés communes :
149
+ <ul>
150
+ <li><a href=""#property_type""><property>type</property> : le type de l'élément</a></li>
151
+ <li><a href=""#property_about""><property>about</property> : commentaire sur l'élément</a></li>
152
+ </ul>
153
+ </li>
154
+ <li>Les propriétés des éléments <property>method</property> :
155
+ <ul>
156
+ <li class=important><a href=""#property_label""><property>label</property> : le libellé</a></li>
157
+ <li><a href=""#property_description""><property>description</property> : la description</a></li>
158
+ <li class=important><a href=""#property_conditions""><property>conditions</property> : les conditions</a></li>
159
+ <li class=new><a href=""#property_shipto""><property>shipto</property> : l'adresse de livraison</a> (<property>destination</property> av. 2.4.8)</li>
160
+ <li class=new><a href=""#property_shipto""><property>billto</property> : l'adresse de facturation</a> (depuis 2.4.8)</li>
161
+ <li><a href=""#property_shipto""><property>origin</property> : l'adresse d'envoi</a></li>
162
+ <li><a href=""#property_customer_groups""><property>customer_groups</property> : les groupes client</a></li>
163
+ <li class=important><a href=""#property_fees""><property>fees</property> : les frais de port</a></li>
164
+ <li><a href=""#property_tracking_url""><property>tracking_url</property> : l'URL de suivi</a> (maj doc 2.4.0)</li>
165
+ <li><a href=""#property_enabled""><property>enabled</property> : l'activation/désactivation</a></li>
166
+ </ul>
167
+ </li>
168
+ </ol>
169
+ </td>
170
+ <td>
171
+ <ol class=level1 start=6>
172
+ <li><a href=""#more_formulas"">Initiation aux formules</a>
173
+ <ol>
174
+ <li class=new><a href=""#more_vars"">Les variables disponibles</a></li>
175
+ <li class=new><a href=""#more_special-functions"">Fonctions spéciales dans les formules</a> (maj 2.5)<br/>&nbsp; &nbsp; min, max, range, substr, in_array, array_match_any, array_match_all</li>
176
+ <li><a href=""#more_copy"">Faire une copie d'une propriété d'un autre élément</a></li>
177
+ <li><a href=""#more_tables"">Utilisation des tables <c>table</c></a></li>
178
+ <li><a href=""#more_switch"">Utilisation des tables de correspondance <c>switch</c></a> (maj 2.4.5)</li>
179
+ <li class=new><a href=""#more_attributes-options"">Utilisation des propriétés des produits (sum, count, min, max)</a> (maj 2.4.8)</li>
180
+ <li><a href=""#more_foreach"">Utilisation des boucles <c>foreach</c></a></li>
181
+ <li class=new><a href=""#more_categories"">Cas particulier : exemples d'utilisation des catégories de produits</a> (maj 2.5)</li>
182
+ </ol>
183
+ </li>
184
+ <li><a href=""#changelog"">Changelog</a></li>
185
+ </ol>
186
+ </td>
187
  </tr></table>
188
  </div>
189
  "
190
+ "{os2editor.help.introduction}","
191
  <h4>Introduction : syntaxe JSON, éléments et propriétés</h4>
192
  <p class=new>
193
+ Si vous souhaitez poser une question, utilisez le sujet suivant sur le forum Magento : <a href=""http://www.magentocommerce.com/boards/viewthread/38223/"" target=_blank>http://www.magentocommerce.com/boards/viewthread/38223/</a>
194
  </p>
195
 
196
  <p>
197
+ <strike>La syntaxe de configuration est une syntaxe proche de la syntaxe JSON.</strike><br/>
198
+ <span class=new>Depuis la version 2.5, la syntaxe de configuration est 100% <a href=""http://fr.wikipedia.org/wiki/JavaScript_Object_Notation"" target=_blank>JSON</a>.</span>
199
  </p>
200
  <p>
201
+ Exemple :
202
  </p>
203
  {code=json}{
204
  ""ex0"":{""about"":""National"",""label"":""National"",""shipto"":""AD,FR,MC"",""conditions"":""{cart.price-tax+discount}<1000.00"",""fees"":""1.30 + {table {cart.weight} in 0.5:5.30, 1.0:6.50, 2.0:7.40, 3.0:8.30, 5.0:10.10}""}
205
  }{/code}
206
 
207
  <p>
208
+ La configuration est un objet JSON contenant plusieurs <strong>propriétés</strong>.<br/>
209
+ Comme imposé par JSON, chaque propriété a un nom unique, qui servira d'<a href=""#unique_id"">identifiant unique</a>.<br/>
210
+ Chaque propriété constitue un <strong>élément</strong> de configuration (qui est également un objet JSON).<br/>
211
  </p>
212
  <p>
213
+ Les éléments possèdent tous une propriété <property>type</property>. Celle-ci permet de définir le type de l'élément :
214
  </p>
215
  <ul>
216
+ <li><a href=""#type_method""><property>method</property> : méthode de livraison (par défaut si non spécifié)</a></li>
217
+ <li><a href=""#type_data""><property>data</property> : données pouvant être utilisées dans une ou plusieurs méthodes de livraison</a></li>
218
+ <li><a href=""#type_meta""><property>meta</property> : données informatives</a></li>
219
  </p>
220
  <!--
221
  <p>
222
+ Chaque élément peut avoir une propriété <property>about</property>, celle-ci permet de placer un commentaire sur l'élément.
223
  </p>
224
 
225
  <p>
226
+ Liste des propriétés d'un élément de type <property>method</property> :
227
  </p>
228
  <ul>
229
+ <li><property>label</property> : nom (libellé)</li>
230
+ <li><property>description</property> : description (visible seulement si le template l'affiche)</li>
231
+ <li><property>enabled</property> : méthode de livraison activée ou non (ex: <c>true</c> ou <c>false</c>)</li>
232
+ <li class=new><property>fees</property> : frais de port (ex: <string>""15.00""</string> ou <string>""{table {cart.weight} in 0.5:5.30, 1.0:6.50}""</string> ou <string>""100 * {cart.weight}""</string>)</li>
233
+ <li class=new><property>conditions</property> : conditions d'activation (ex: <string>""{cart.weight}&gt;=1.0""</string> ou <string>""{cart.price-tax+discount}&lt;100.00""</string> ou <string>""range({cart.weight},1.0,3.0) and {cart.free_shipping}""</string> ou <string>""{count items where product.attribute.color=='Bleu'}&gt;1 or {count items where item.option.size=='2m'}&gt;2""</string>)</li>
234
+ <li class=new><property><strike>destination</strike> shipto</property> : pays (régions, codes postaux) autorisés à la livraison (ex: <string>""FR,DE,US""</string> ou <string>""FR(2A,2B,25000)""</string> ou <string>""FR-(2A,2B)""</string> ou <string>""FR(01,02,39600),CH,DE""</string>)</li>
235
+ <li class=new><property>billto</property> : pays (régions, codes postaux) autorisés à la facturation (ex: idem <property>shipto</property>)</li>
236
+ <li><property>origin</property> : pays (régions, codes postaux) autorisés en origine (ex: idem <property>shipto</property>)</li>
237
+ <li><property>customer_groups</property> : groupes de client autorisés (ex: <string>""NOT LOGGED IN,Retailer""</string> ou <string>""0,3""</string>)</li>
238
  </ul>
239
  -->
240
  "
241
+ "{os2editor.help.unique_id}","
242
  <h4>L'identifiant unique</h4>
243
  <p>Chaque élément de configuration possède un identifiant unique. Cet identifiant unique permet ensuite de faire référence à l'élément.</p>
244
  <p>Exemple :</p>
249
 
250
  <p class=warning><strong><u>Attention</u> :</strong> pour éviter les conflicts, n'utiliser que les caractères <c>a-z</c>, <c>A-Z</c>, <c>0-9</c>, <c>-</c> et <c>_</c> pour former l'identifiant unique.<br/>Vous devez également éviter les identifiants qui correspondent déjà à des noms de variable (<c>cart</c>, <c>product</c>, <c>item</c>…).</p>
251
  "
252
+ "{os2editor.help.type_method}","
253
  <h4>Élément de type <property>method</property></h4>
254
  <p>Un élément de type <property>method</property> permet de spécifier une méthode de livraison.</p>
255
  <p>Exemple minimal avec uniquement les propriétés obligatoires :</p>
261
  ""ex0"":{""about"":""Colissimo National"",""type"":""method"",""label"":""Colissimo"",""description"":""Livraison sous 24/48h"",""enabled"":true,""conditions"":""range({cart.weight},0.2,1.0)"",""shipto"":""FR(01,02,39600,/^25[0-9]{3}$/),CH,DE"",""billto"":""FR"",""origin"":""DE"",""customer_groups"":""NOT LOGGED IN,Retailer"",""fees"":""{table {cart.weight} in 0.5:5.30, 1.0:6.50}""}
262
  }{/code}
263
  "
264
+ "{os2editor.help.type_data}","
265
  <h4>Élément de type <property>data</property></h4>
266
  <p>Un élément de type <property>data</property> permet de spécifier des données utilisables dans les méthodes de livraison.</p>
267
  <p>Exemple d'élément de type <property>data</property> :</p>
273
  ""ex0"":{""type"":""method"",""label"":""Colissimo"",""fees"":""{mydata.reference}*1.5""}
274
  }{/code}
275
  "
276
+ "{os2editor.help.type_meta}","
277
  <h4>Élément de type <property>meta</property></h4>
278
  <p>Un élément de type <property>meta</property> permet d'ajouter des données informatives (auteur, date…).</p>
279
  <p>Exemple :</p>
281
  ""about"":{""type"":""meta"",""author"":""Owebia"",""date"":""16/11/2012"",""about"":""Tarifs 2012""}
282
  }{/code}
283
  "
284
+ "{os2editor.help.property_type}","
285
  <h4><property>type</property> : le type de l'élément</h4>
286
  <p>Il permet de spécifier le type de l'élément :</p>
287
  <ul>
288
+ <li><a href=""#type_method""><property>method</property> : méthode de livraison (par défaut si non spécifié)</a></li>
289
+ <li><a href=""#type_data""><property>data</property> : données pouvant être utilisées dans une ou plusieurs méthodes de livraison</a></li>
290
+ <li><a href=""#type_meta""><property>meta</property> : données informatives</a></li>
291
  </ul>
292
  {code=json}{
293
  ""about"":{""type"":""meta"",""author"":""Owebia"",""date"":""16/11/2012"",""about"":""Tarifs 2012""},
295
  ""ex0"":{""type"":""method"",""label"":""Colissimo"",""fees"":""{mydata.reference}*1.5""}
296
  }{/code}
297
  "
298
+ "{os2editor.help.property_about}","
299
  <h4><property>about</property> : commentaire sur l'élément</h4>
300
  <p>Vous pouvez ajouter un commentaire à un élément de configuration.</p>
301
  {code=json}{""ex0"":{""about"":""Mon commentaire"",""label"":""Exemple avec commentaire"",""fees"":10}}{/code}
302
  "
303
+ "{os2editor.help.property_label}","
304
  <h4><property>label</property> : le libellé</h4>
305
  <p>Il s'agit du nom qui sera donné à la méthode de livraison.</p>
306
  <p>On peut insérer certains éléments comme le poids des marchandises dans le libellé.<br/>
307
  Pour ce faire, utiliser les variables suivantes :</p>
308
  <ul>
309
+ <li>L'adresse de livraison :
310
+ <ul>
311
+ <li class=new><c><strike>{destination.country.name}</strike> {shipto.country_name}</c> : le nom du pays</li>
312
+ <li class=new><c><strike>{destination.country.code}</strike> {shipto.country_id}</c> : le code du pays</li>
313
+ <li class=new><c><strike>{destination.region.code}</strike> {shipto.region_code}</c> : le code de la région</li>
314
+ <li class=new><c><strike>{destination.postcode}</strike> {shipto.postcode}</c> : le code postal</li>
315
+ </ul>
316
+ </li>
317
+ <li><c>{cart.weight}</c> : poids des marchandises</li>
318
+ <li class=new><c><strike>{cart.weight.unit}</strike> {cart.weight_unit}</c> : l'unité de poids</li>
319
+ <li><a href=""#more_vars"">Voir la liste complète des variables</a></li>
320
  </ul>
321
  {code=json}{
322
  ""ex0"":{""label"":""Colissimo ({cart.weight} / {shipto.country_name})"",""fees"":10}
323
  }{/code}
324
  <p>La ligne ci-dessus affichera par exemple <string>""Colissimo (3.0kg / France)""</string>.</p>
325
  "
326
+ "{os2editor.help.property_description}","
327
  <h4><property>description</property> : la description</h4>
328
  <p>Il s'agit de la description de la méthode de livraison.</p>
329
  <p>Le fonctionnement est identique à la propriété <a href=""#property_label""><property>label</property></a>.</p>
330
  "
331
+ "{os2editor.help.property_conditions}","
332
  <h4><property>conditions</property> : les conditions</h4>
333
  <p>
334
+ La propriété <property>conditions</property> se spécifie sous la forme d'une <a href=""#more_formulas"">formule (voir l'initiation aux formules)</a>
335
+ qui doit retourner une valeur booléenne (<c>true</c> ou <c>false</c>).
336
  </p>
337
 
338
  {code=json}{
348
  ""ex9"":{""label"":""Si tous les produits possèdent l'option 'size' supérieure ou égal à '1'"",""conditions"":""{count items where product.option.size>='1'}=={cart.qty}"",""fees"":10}
349
  }{/code}
350
  "
351
+ "{os2editor.help.property_shipto}","
352
  <h4>Les adresses : <property>shipto</property>, <property>billto</property> et <property>origin</property></h4>
353
  <p>
354
+ L'extension permet de filtrer plusieurs adresses :
355
  </p>
356
  <ul>
357
+ <li class=new>L'adresse de livraison <strike><property>destination</property></strike> <property>shipto</property>.</li>
358
+ <li class=new>L'adresse de facturation <property>billto</property></li>
359
+ <li>L'adresse d'origine <property>origin</property></li>
360
  </ul>
361
  <p>
362
+ Les codes pays utilisés sont ceux de Magento (à priori ils sont les mêmes que les <a href=""http://fr.wikipedia.org/wiki/ISO_3166-1"" target=_blank>codes ISO 3166-1 alpha-2</a>).<br/>
363
+ Il est possible de spécifier les codes régions (uniquement avec <property>shipto</property>) ou les codes postaux que l'on veut filtrer ou exclure.
364
  </p>
365
  <p class=new>
366
+ Vous pouvez utiliser le caractère jocker <c>*</c> ou les expressions régulières pour les codes postaux.<br/>
367
+ Une expression régulière doit commencer et se terminer par le caractère <c>/</c>. Si vous souhaitez utiliser les caractères <c>(</c>, <c>)</c> ou <c>,</c>, vous devez les échapper avec le caractère <c>\</c> (ex: <string>""FR(/^25\([0-9]{3}\)$/)""</string>).<br/>
368
+ Vous pouvez utiliser l'option d'insensibilité à la casse (ex: <string>""GB(/^PO.*$/i)""</string>).
369
  </p>
370
 
371
  {code=json}{
378
  }{/code}
379
 
380
  <div class=""tips"">
381
+ <p><strong>Astuce</strong><br/>Pour raccourcir la saisie des pays, vous pouvez utiliser les variables suivantes :</p>
382
+ <ul>
383
+ <li><c>{address_filter.AF}</c> : pays d'Afrique</li>
384
+ <li><c>{address_filter.AS}</c> : pays d'Asie</li>
385
+ <li><c>{address_filter.EU}</c> : pays d'Europe</li>
386
+ <li><c>{address_filter.NA}</c> : pays d'Amérique du Nord</li>
387
+ <li><c>{address_filter.SA}</c> : pays d'Amérique du Sud</li>
388
+ <li><c>{address_filter.OC}</c> : pays d'Océanie</li>
389
+ <li><c>{address_filter.AN}</c> : pays d'Antartique</li>
390
+ <li><c>{address_filter.EU-27}</c> : pays de l'Union Européenne</li>
391
+ <li><c>{address_filter.DOM}</c> : codes pays des département d'Outre-Mer Français</li>
392
+ <li><c>{address_filter.COM}</c> : codes pays des Collectivités d'Outre-Mer Françaises</li>
393
+ </ul>
394
  </div>
395
 
396
  {code=json}{
397
  ""ex0"":{""label"":""Europe sauf la France"",""shipto"":""({address_filter.EU-27}) - (FR)"",""fees"":10}
398
  }{/code}
399
  "
400
+ "{os2editor.help.property_billto}","
401
  <h4><property>billto</property> : l'adresse de facturation</h4>
402
  <p><a href=""#property_shipto"">Filtrage des adresses</a></p>
403
  "
404
+ "{os2editor.help.property_origin}","
405
  <h4><property>origin</property> : l'adresse d'envoi</h4>
406
  <p><a href=""#property_shipto"">Filtrage des adresses</a></p>
407
  "
408
+ "{os2editor.help.property_customer_groups}","
409
  <h4><property>customer_groups</property> : les groupes client</h4>
410
  <p>On peut utiliser le nom ou l'ID des groupes client.</p>
411
 
415
  ""ex2"":{""label"":""Groupe Retailer"",""customer_groups"":""Retailer"",""fees"":10}
416
  }{/code}
417
  "
418
+ "{os2editor.help.property_fees}","
419
  <h4><property>fees</property> : les frais de port</h4>
420
  <p>
421
+ La propriété <property>fees</property> se spécifie sous la forme d'une <a href=""#more_formulas"">formule (voir l'initiation aux formules)</a>.
422
  </p>
423
  {code=json}{
424
  ""ex0"":{""label"":""Frais fixes"",""fees"":10},
427
  ""ex3"":{""label"":""Combinaison"",""fees"":""0.1 * {cart.price-tax+discount} + {table {cart.weight} in 0.5:5.30, 1.0:6.50} + 10.00""}
428
  }{/code}
429
  "
430
+ "{os2editor.help.property_tracking_url}","
431
  <h4><property>tracking_url</property> : l'URL de suivi</h4>
432
  <p class=warning>
433
+ <strong>L'utilisation de la propriété <property>tracking_url</property> est réservée aux utilisateurs expérimentés. Si vous ne comprenez pas les indications ci-dessous, il est préférable que vous évitiez d'utiliser cette fonctionnalité.</strong>
434
  </p>
435
  <p>
436
+ La propriété <property>tracking_url</property> permet de surcharger le champ ""URL de suivi"" d'un mode de livraison Owebia Shipping et ainsi de spécifier une URL de suivi <strong>par méthode de livraison</strong> plutôt qu'une pour tout le mode de livraison.
437
  </p>
438
  <p>
439
+ Pour insérer automatiquement le numéro de colis dans l'URL de suivi, vous devez utiliser <c>{tracking_number}</c>.
440
  </p>
441
 
442
  {code=json}{
444
  }{/code}
445
 
446
  <p>
447
+ Magento ne gère pas les liens de tracking mais un statut de tracking. L'extension Owebia Shipping 2 fournit un lien HTML à la place du statut, lien qui permet d'aller sur le site du transporteur et de suivre l'avancement de la livraison du colis.
448
  </p>
449
  <p>
450
+ Lorsque l'URL de suivi est construite par l'extension, la seule information disponible est le numéro de colis et on n'a nul part accès à la méthode de livraison sélectionnée. Afin de pouvoir retrouver l'url de suivi dans la configuration, il faut spécifier la méthode de livraison dans le numéro de tracking, par exemple : <c>colissimo:8Lxxxxxxxxxxx</c> où <c>colissimo</c> est le code de la méthode de livraison sélectionnée.<br/>
451
+ Si aucun code n'est spécifié (si vous saisissez uniquement le numéro de tracking), l'url utilisée sera celle globale au mode de livraison.
452
  </p>
453
  <p class=warning>
454
+ Pour répondre à une question récurrente, Magento affiche le statut de livraison depuis le back office ou le front office. <strong>Si vous souhaitez insérer l'URL de suivi dans les mails d'expédition, vous devrez développer vous même la récupération de l'URL de suivi et son insertion dans le mail, en effet, l'extension Owebia Shipping 2 se contente de fournir des modes de livraison paramétrables sans apporter de grande modification au coeur de Magento afin de réduire les problèmes d'incompatibilité et de mise à jour.</strong>
455
  </p>
456
  <p class=warning>
457
+ Si vous obtenez un popup vide lorsque vous cliquez sur le lien de suivi, votre problème est très certainement lié au fait que vous n'avez pas spécifié le code de la méthode de livraison dans le numéro de suivi (voir indications plus haut) et que votre champ global ""URL de suivi"" est vide.
458
  </p>
459
  <p class=warning>Il n'est actuellement pas prévu de modifier les fonctionnalitées de l'extension liées à l'URL de suivi.</p>
460
  "
461
+ "{os2editor.help.property_enabled}","
462
  <h4><property>enabled</property> : l'activation/désactivation</h4>
463
  <p>Permet d'activer ou de désactiver la méthode de livraison.</p>
464
  <p>La valeur doit être booléenne.</p>
466
  ""ex0"":{""enabled"":true,""label"":""Exemple avec activation"",""fees"":10}
467
  }{/code}
468
  "
469
+ "{os2editor.help.more_formulas}","
470
  <h4>Initiation aux formules</h4>
471
  <p>
472
+ Les propriétés <property>fees</property> et <property>conditions</property> sont spécifiées sous la forme de formules.
473
  </p>
474
  <p>
475
+ Signes mathématiques disponibles :
476
  </p>
477
  <ul>
478
+ <li>opérateurs : <c>*</c>, <c>/</c>, <c>+</c> et <c>-</c></li>
479
+ <li>modulo : <c>%</c></li>
480
+ <li>parenthèses : <c>(</c> et <c>)</c></li>
481
+ <li>les opérateurs booléens <c>&amp;&amp;</c>, <c>and</c>, <c>||</c>, <c>or</c>, <c>==</c>, <c>&lt;</c>, <c>&gt;</c>, <c>&lt;=</c>, <c>&gt;=</c></li>
482
+ <li>les opérateurs binaires <c>&amp;</c> et <c>|</c></li>
483
+ <li>le groupe d'opérateur <c>C ? X : Y</c> (ex: <c><span class=string>""{cart.price_exluding_tax}&gt;100 ? 15*{cart.weight} : 20*{cart.weight}""</span></c>)</li>
484
  </ul>
485
  <p>
486
+ Variables disponibles :
487
  </p>
488
  <ul>
489
+ <li><c>{cart.weight}</c> : poids des marchandises</li>
490
+ <li><c class=new><strike>{cart.quantity}</strike> {cart.qty}</c> : nombre d'articles dans le panier</li>
491
+ <li><c class=new><strike>{cart.price_excluding_tax}</strike> {cart.price-tax+discount}</c> : prix HT après remise</li>
492
+ <li><c class=new><strike>{cart.price_including_tax}</strike> {cart.price+tax+discount}</c> : prix TTC après remise</li>
493
+ <li><c>{cart.price-tax-discount}</c> : prix HT avant remise</li>
494
+ <li><c>{cart.price+tax-discount}</c> : prix TTC avant remise</li>
495
+ <li><a href=""#more_vars"">Voir la liste complète des variables</a></li>
496
  </ul>
497
  <p>
498
+ Vous avez la possibilité de mettre des espaces et des retours à la ligne dans les formules (pour aérer).
499
  </p>
500
  <p>
501
+ Fonctions disponibles :
502
  </p>
503
  <ul>
504
+ <li>arrondis : <c>round(x)</c>, <c>floor(x)</c>, <c>ceil(x)</c></li>
505
+ <li>valeur absolue : <c>abs(x)</c></li>
506
+ <li>maximum : <c>max(x,y)</c></li>
507
+ <li>minimum : <c>min(x,y)</c></li>
508
+ <li>entier aléatoire : <c>rand(min,max)</c></li>
509
+ <li>puissance : <c>pow(x,puissance)</c></li>
510
+ <li>nombre PI : <c>pi()</c></li>
511
+ <li>racine carrée : <c>sqrt(x)</c></li>
512
+ <li>logarithme : <c>log(x)</c> pour le logarithme népérien ou <c>log(x,base)</c></li>
513
+ <li>exponentiel : <c>exp(x)</c></li>
514
  </ul>
515
  <p>
516
+ Possibilité d'utiliser les fonctionnalités avancées suivantes : casting en entier <c>(int)</c> ou en nombre flottant <c>(float)</c>,
517
+ comparaison avec la valeur <c>null</c> ou les valeurs booléennes <c>true</c> et <c>false</c>.
518
  </p>
519
  <p class=new style=""font-weight: bold;"">
520
+ 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,
521
+ les fonctions spéciales, l'utilisation des attributs et des options des produits ou encore l'utilisation des variables personnalisées.
522
  </p>
523
  <p class=new style=""font-weight: bold;"">
524
+ 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 <c>{{ }}</c>.
525
  </p>
526
  {code=json}{
527
  ""ex0"":{""label"":""Échappement avec des guillemets"",""conditions"":""'{cart.coupon_code}'=='test'"",""fees"":10},
528
  ""ex1"":{""about"":""Depuis la version 2.4.5, {{cart.coupon_code}} sera remplacé par 'moncoupon' ou par null en fonction de sa valeur"",""label"":""Auto-échappement"",""conditions"":""{{cart.coupon_code}}!='test'"",""fees"":10}
529
  }{/code}
530
  "
531
+ "{os2editor.help.more_vars}","
532
  <h4>Les variables disponibles</h4>
533
  <p>
534
+ Les variables suivantes peuvent être utilisées dans les différents propriétés des méthodes de livraison (en particulier les propriétés <property>conditions</property> et <property>fees</property>).
535
  </p>
536
  <ul>
537
+ <li>Le panier :
538
+ <ul>
539
+ <li><c>{cart.weight}</c> : poids des marchandises</li>
540
+ <li><c class=new><strike>{cart.quantity}</strike> {cart.qty}</c> : la quantité d'articles</li>
541
+ <li class=new><c><strike>{cart.price_excluding_tax}</strike> {cart.price-tax+discount}</c> : prix HT avec remise</li>
542
+ <li class=new><c><strike>{cart.price_including_tax}</strike> {cart.price+tax+discount}</c> : prix TTC avec remise</li>
543
+ <li class=new><c>{cart.price-tax-discount}</c> : prix HT sans remise</li>
544
+ <li class=new><c>{cart.price+tax-discount}</c> : prix TTC sans remise</li>
545
+ <li class=new><c><strike>{cart.coupon}</strike> {cart.coupon_code}</c> : coupon de réduction</li>
546
+ <li><c class=new><strike>{free_shipping}</strike> {cart.free_shipping}</c> : frais de port offert (par une règle dans Magento) [true/false]</li>
547
+ <li><c class=new><strike>{cart.weight.unit}</strike> {cart.weight_unit}</c> : l'unité de poids</li>
548
+ <li><c class=new><strike>{cart.weight.for-charge}</strike> {cart.weight_for_charge}</c> : poids des marchandises dont la livraison n'est pas offerte (par les règles de prix panier de Magento)</li>
549
+ </ul>
550
+ </li>
551
+ <li class=new>Le group client :
552
+ <ul>
553
+ <li><c><strike>{customer.group.id}</strike> {customer_group.id}</c> : id du groupe client</li>
554
+ <li><c><strike>{customer.group.code}</strike> {customer_group.code}</c> : nom du groupe client</li>
555
+ <li><c>{customer_group.*}</c> : propriété du groupe client (ex: <c>{customer_group.tax_class_id}</c>)</li>
556
+ </ul>
557
+ </li>
558
+ <li class=new>Le client :
559
+ <ul>
560
+ <li><c>{customer.id}</c> : id du client</li>
561
+ <li><c>{customer.attribute.*}</c> : attribut du client (ex: lastname, firstname, group_id…)</li>
562
+ <li class=new><c>{customer.attribute.*.value}</c> : dans le cas des attributs de type liste de sélection, <c>{customer.attribute.*}</c> retourne l'id, pour obtenir la valeur il faut utiliser <c>{customer.attribute.*.value}</c></li>
563
+ <li><c>{customer.*}</c> : identique à <c>{customer.attribute.*}</c>, sauf si la variable est déjà définie (ex: <c>{customer.id}</c> est déjà définie)</li>
564
+ </ul>
565
+ </li>
566
+ <li class=new>Les variables personnalisées ou `Custom Variables` (depuis la version 1.4.0.1 de Magento) :
567
+ <ul>
568
+ <li><c>{customvar.*}</c> : variable personnalisée de Magento (ex: <c>{customvar.my_var}</c>)</li>
569
+ <li><c><strike>{{customVar code=*}}</strike></c> : utiliser la syntaxe ci-dessus</li>
570
+ </ul>
571
+ </li>
572
+ <li>L'adresse de livraison :
573
+ <ul>
574
+ <li><c class=new><strike>{destination.country.name}</strike> {shipto.country_name}</c> : le nom du pays</li>
575
+ <li><c class=new><strike>{destination.country.code}</strike> {shipto.country_id}</c> : le code du pays</li>
576
+ <li class=new><c>{shipto.region_id}</c> : l'id de la région</li>
577
+ <li><c class=new><strike>{destination.region.code}</strike> {shipto.region_code}</c> : le code de la région</li>
578
+ <li class=new><c>{shipto.street}</c> : la rue</li>
579
+ <li class=new><c>{shipto.city}</c> : la ville</li>
580
+ <li><c class=new><strike>{destination.postcode}</strike> {shipto.postcode}</c> : le code postal</li>
581
+ </ul>
582
+ </li>
583
+ <li class=new>L'adresse de facturation :
584
+ <ul>
585
+ <li><c>{billto.country_name}</c> : le nom du pays</li>
586
+ <li><c>{billto.country_id}</c> : le code du pays</li>
587
+ <li><c>{billto.postcode}</c> : le code postal</li>
588
+ <li><c>{billto.*}</c> : propriété de l'adresse de facturation (ex: <c>{billto.city}</c>)</li>
589
+ </ul>
590
+ </li>
591
+ <li>L'adresse d'envoi :
592
+ <ul>
593
+ <li><c class=new><strike>{origin.country.name}</strike> {origin.country_name}</c> : le nom du pays</li>
594
+ <li><c class=new><strike>{origin.country.code}</strike> {origin.country_id}</c> : le code du pays</li>
595
+ <li><c class=new><strike>{origin.region.code}</strike> {origin.region_id}</c> : l'id de la région</li>
596
+ <li class=new><c>{origin.city}</c> : la ville</li>
597
+ <li><c>{origin.postcode}</c> : le code postal</li>
598
+ </ul>
599
+ </li>
600
+ <li>Le magasin :
601
+ <ul>
602
+ <li><c>{store.id}</c> <c>{store.code}</c> <c>{store.name}</c> <c>{store.address}</c> <c>{store.phone}</c> : id, code, nom, adresse et téléphone du magasin</li>
603
+ </ul>
604
+ </li>
605
+ <li>La date courante :
606
+ <ul>
607
+ <li><c>{date.timestamp}</c> : timestamp UNIX de la date actuelle</li>
608
+ <li><c>{date.year}</c> <c>{date.month}</c> <c>{date.day}</c> <c>{date.hour}</c> <c>{date.minute}</c> <c>{date.second}</c> : année, mois, jour, heure, minute et seconde de la date actuelle</li>
609
+ <li><c>{date.weekday}</c> : jour de la semaine de la date actuelle de 0 (dimanche) à 6 (samedi)</li>
610
+ </ul>
611
+ </li>
612
+ <li class=new>L'objet <c>request</c> :
613
+ <ul>
614
+ <li><c>{request.*}</c> : propriété de l'objet request (Mage_Shipping_Model_Rate_Request) passé en paramètre par Magento (ex: <c>{request.package_qty}</c>). Utiliser l'option ""Déboguage"" pour obtenir plus de détail sur les propriétés disponibles.</li>
615
+ </ul>
616
+ </li>
617
  </ul>
618
  "
619
+ "{os2editor.help.more_special-functions}","
620
  <h4>Fonctions spéciales dans les formules</h4>
621
 
622
  <p>
626
  Liste des fonctions spéciales :
627
  </p>
628
  <ul>
629
+ <li><c>min(x, y, …)</c> : calcule le minimum entre plusieurs valeurs (éventuellement plus de deux valeurs). Si l'une des valeurs est nulle, elle est ignorée.</li>
630
+ <li><c>max(x, y, …)</c> : calcule le maximum entre plusieurs valeurs (éventuellement plus de deux valeurs). Si l'une des valeurs est nulle, elle est ignorée.</li>
631
+ <li class=new><c>range(value, min, max, include_min, include_max)</c> : retourne <c>true</c> si <c>value</c> est comprise entre <c>min</c> et <c>max</c>. Par défaut, <c>include_min</c> et <c>include_max</c> sont égales à <c>true</c>.</li>
632
+ <li class=new><c>substr(string, start, length)</c> : retourne un segment de chaîne de caractères.</li>
633
+ <li class=new><c>in_array(value, array(value1, value2, …))</c> : indique si une valeur appartient à un tableau.</li>
634
+ <li class=new><c>array_match_any(array(value1, value2, …), array(value1, value2, …))</c> : indique si au moins une valeur est présente dans les deux tableaux.</li>
635
+ <li class=new><c>array_match_all(array(value1, value2, …), array(value1, value2, …))</c> : indique si le contenu des tableaux est identique.</li>
636
  </ul>
637
 
638
  {code=json}{
646
  }{/code}
647
 
648
  <p class=new>
649
+ * Concernant l'échappement des chaînes de caractères, se référer à l'<a href=""#more_formulas"">initiation aux formules</a>.
650
  </p>
651
  "
652
+ "{os2editor.help.more_copy}","
653
  <h4>Faire une copie d'une propriété d'un autre élément</h4>
654
  <p>Il est possible de faire une copie d'une propriété dans un autre élément à l'aide de la syntaxe ci-dessous.</p>
655
  <p>Vous pouvez utiliser cette technique dans toutes les propriétés (<property>conditions</property>, <property>fees</property>, …).</p>
660
  ""ex2"":{""label"":""Copie des frais de port d'une autre méthode"",""fees"":""({colissimo.fees}) + 15.00""}
661
  }{/code}
662
  "
663
+ "{os2editor.help.more_tables}","
664
  <h4>Utilisation des tables <c>table</c></h4>
665
  <p>
666
+ Dans une <c>table</c>, on peut inclure ou exclure une valeur limite avec les caractères <c>[</c> et <c>]</c> :
667
  </p>
668
  {code=json}{
669
  ""f0"":{""label"":""Limite supérieure incluse"",""fees"":""{table {cart.weight} in 1.0]:5.00}""},
671
  }{/code}
672
 
673
  <p>
674
+ Dans une <c>table</c>, on doit spécifier la valeur de référence. Pour cela, on peut utiliser une des <a href=""#more_vars"">variables disponibles</a>.<br/>
675
+ Vous pouvez aussi utiliser une formule afin de définir une autre variable de référence.
676
  </p>
677
 
678
  {code=json}{
683
  ""ex4"":{""label"":""Table avec valeur personnalisée"",""fees"":""{table ceil({cart.weight}/10) in 1:5.30, 2:6.50}""}
684
  }{/code}
685
  "
686
+ "{os2editor.help.more_switch}","
687
  <h4>Utilisation des tables de correspondance <c>switch</c></h4>
688
 
689
  <p>
690
+ Dans un <c>switch</c>, on doit spécifier la valeur de référence. Pour cela, on peut utiliser une des <a href=""#more_vars"">variables disponibles</a>.<br/>
691
+ Vous pouvez aussi utiliser une formule afin de définir une autre variable de référence.
692
  </p>
693
 
694
  {code=json}{
696
  ""ex1"":{""label"":""Table de correspondance avec le pays de livraison"",""fees"":""{switch {{shipto.country_id}} in 'FR':5.30, 'BE':6.50, 'DE':10.00, *:7.50}""}
697
  }{/code}
698
  "
699
+ "{os2editor.help.more_attributes-options}","
700
  <h4>Utilisation des propriétés des produits</h4>
701
 
702
  <p class=new>
703
+ Afin de mieux correspondre aux Models de Magento, la version 2.4.8 de l'extension introduit la séparation entre les objects <c>item</c> et <c>product</c>.
704
+ Un <c>item</c> est une déclinaison d'un <c>product</c> auquel on a ajouté d'éventuelles options. Chaque <c>item</c> a une quantité.
705
  </p>
706
  <p>
707
+ Liste des propriétés disponibles :
708
  </p>
709
  <ul>
710
+ <li class=new>L'article (ou <c>item</c>) :
711
+ <ul>
712
+ <li><c>item.qty</c> : quantité dans le panier</li>
713
+ <li><c>item.price-tax+discount</c> : le prix HT avec remise</li>
714
+ <li><c>item.price-tax-discount</c> : le prix HT sans remise</li>
715
+ <li><c>item.price+tax+discount</c> : le prix TTC avec remise</li>
716
+ <li><c>item.price+tax-discount</c> : le prix TTC sans remise</li>
717
+ <li><c>item.option.*</c> : option (la liste des options disponibles dépendra des produits)</li>
718
+ </ul>
719
+ </li>
720
+ <li>Le produit (ou <c>product</c>) :
721
+ <ul>
722
+ <li><c><strike>product.quantity</strike></c> : utiliser <c class=new>item.qty</c></li>
723
+ <li><c>product.attribute.*</c> : attribut<br/>Liste d'attributs intéressants :
724
+ <ul>
725
+ <li><c>sku</c> : la référence</li>
726
+ <li><c>name</c> : le nom</li>
727
+ <li><c>weight</c> : le poids</li>
728
+ <li><c>price</c> : le prix (tel qu'il a été saisi sur la fiche du produit)</li>
729
+ <li><c>special_price</c> : le prix promotionnel (tel qu'il a été saisi sur la fiche du produit)</li>
730
+ <li><c><strike>price-tax+discount</strike></c> : utiliser <c class=new>item.price-tax+discount</c></li>
731
+ <li><c><strike>price-tax-discount</strike></c> : utiliser <c class=new>item.price-tax-discount</c></li>
732
+ <li><c><strike>price+tax+discount</strike></c> : utiliser <c class=new>item.price+tax+discount</c></li>
733
+ <li><c><strike>price+tax-discount</strike></c> : utiliser <c class=new>item.price+tax-discount</c></li>
734
+ </ul>
735
+ </li>
736
+ <li class=new><c>product.attribute.*.value</c> : valeur de l'attribut<br/>Dans le cas des attributs de type liste de sélection, <c>product.attribute.*</c> retourne l'id. Pour obtenir la valeur, il faut utiliser <c>product.attribute.*.value</c></li>
737
+ <li class=new><c>product.*</c> : identique à <c>product.attribute.*</c> sauf si la variable est définie (ex: <c>product.category</c>)</li>
738
+ <li><c><strike>product.option.*</strike></c> : utiliser les propriétés <c class=new>item.option.*</c></li>
739
+ <li>Première catégorie du produit :
740
+ <ul>
741
+ <li><c>product.category</c> : nom de la catégorie</li>
742
+ <li><c>product.category.id</c> : id de la catégorie</li>
743
+ <li class=new><c>product.category.*</c> : attribut de la catégorie (ex: <c>product.category.is_active</c>)<br/>Liste d'attributs intéressants :
744
+ <ul>
745
+ <li><c>is_active</c> : catégorie activée ou non</li>
746
+ <li><c>name</c> : nom</li>
747
+ <li>…</li>
748
+ </ul>
749
+ </li>
750
+ </ul>
751
+ </li>
752
+ <li>Toutes les catégories du produit (retourne un tableau, <a href=""#more_categories"">rubrique explicative</a>) :
753
+ <ul>
754
+ <li><c>product.categories</c> : tableau du nom des catégories</li>
755
+ <li><c>product.categories.id</c> : tableau de l'id des catégories</li>
756
+ </ul>
757
+ </li>
758
+ <li>Le jeu d'attributs du produit :
759
+ <ul>
760
+ <li><c>product.attribute_set</c> : nom du jeu d'attributs</li>
761
+ <li><c>product.attribute_set.id</c> : id du jeu d'attributs</li>
762
+ <li class=new><c>product.attribute_set.*</c> : attribut du jeu d'attributs (ex: <c>product.attribute_set.attribute_set_name</c>)</li>
763
+ </ul>
764
+ </li>
765
+ <li class=new><c>product.stock.*</c> : attribut du stock du produit<br/>Liste d'attributs intéressants :
766
+ <ul>
767
+ <li><c>is_in_stock</c> : disponibilité du produit</li>
768
+ <li><c>qty</c> : stock du produit</li>
769
+ <li>…</li>
770
+ </ul>
771
+ </li>
772
+ </ul>
773
+ </li>
774
  </ul>
775
 
776
  {code=json}{
787
  Liste des préfixes possibles :
788
  </p>
789
  <ul>
790
+ <li><c>count</c> : nombre (toujours suivi de <c>items</c>)</li>
791
+ <li><c>count distinct</c> : nombre distinct (toujours suivi d'une propriété)</li>
792
+ <li><c>sum</c> : somme (toujours suivi d'une propriété)</li>
793
+ <li class=new><c>min</c> : minimum (toujours suivi d'une propriété)</li>
794
+ <li class=new><c>max</c> : maximum (toujours suivi d'une propriété)</li>
795
  </ul>
796
  <p>
797
+ Il est possible de spécifier des conditions que doivent remplir les produits pour être pris en compte. Pour cela, il suffit d'ajouter <c> where </c> suivi d'une formule.
798
  </p>
799
  <p>
800
+ Si la propriété est de type <strong>Oui/Non</strong>, vous devez utiliser les valeurs <c>true</c>/<c>false</c> ou <c>1</c>/<c>0</c> sans les guillemets.
801
  </p>
802
  {code=json}{
803
  ""ex0"":{""label"":""Exemple propriété de type Oui/Non : 0"",""conditions"":""{count items where product.attribute.colissimo_allowed==0}"",""fees"":10},
805
  }{/code}
806
 
807
  <p>
808
+ Si la propriété est de type <strong>Liste de sélection</strong> et que vous souhaitez faire une comparaison avec <strike>l'id</strike> la valeur plutôt qu'avec <strike>la valeur</strike> l'id, vous devez utiliser la syntaxe suivante :</strike>
809
  </p>
810
  <strike>{code=json}{
811
  ""ex0"":{""label"":""Si l'attribut 'color' est égale à la valeur dont l'id différente de 1"",""conditions"":""{count items where product.color.id!=1}"",""fees"":10}
814
  ""ex0"":{""label"":""Si la valeur de l'attribut 'color' est différente de 'Bleu'"",""conditions"":""{count items where product.color.value!='Bleu'}"",""fees"":10}
815
  }{/code}
816
  "
817
+ "{os2editor.help.more_foreach}","
818
  <h4>Utilisation des boucles <c>foreach</c></h4>
819
 
820
  <p>
821
+ Les boucles <c>foreach</c> permettent d'effectuer un calcul sur des groupes de produits plutôt que de tenir compte de tous les produits du panier.<br/>
822
+ Le résultat global d'une boucle <c>foreach</c> est la somme des résultats de chaque passage dans la boucle.
823
  </p>
824
  <p>
825
+ A l'intérieur d'une boucle <c>foreach</c>, il est possible d'utiliser de nouvelles variables :
826
  </p>
827
  <ul>
828
+ <li><c>{selection.weight}</c> : poids de la sélection</li>
829
+ <li><c class=new><strike>{selection.quantity}</strike> {selection.qty}</c> : nombre d'articles dans la sélection</li>
830
  </ul>
831
  <p>
832
+ Lorsque la sélection se fait sur le sku, chaque sélection est composée d'un seul article. On peut donc utiliser d'autres variables :
833
  </p>
834
  <ul>
835
+ <li><c>{item.*}</c> : propriété de l'article</li>
836
+ <li><c>{product.*}</c> : propriété du produit</li>
837
+ <li><a href=""#more_attributes-options"">Voir la liste complète des propriétés produit</a></li>
838
  </ul>
839
 
840
  {code=json}{
842
  ""ex1"":{""label"":""Calcul des frais de port par produit"",""fees"":""{foreach product.attribute.sku}{product.attribute.shipping}*{item.qty}{/foreach}""}
843
  }{/code}
844
  "
845
+ "{os2editor.help.more_categories}","
846
  <h4>Cas particulier : exemples d'utilisation des catégories de produits</h4>
847
 
848
  <p>
849
+ Depuis la version 2.4.2, il est possible d'utiliser les catégories des produits dans les formules.
850
  </p>
851
  <p class=warning>
852
+ <strong>Attention, il est à noter que dans Magento, un produit peut être dans plusieurs catégories.</strong> Faites donc particulièrement attention à la façon dont vous utilisez cette propriété.
853
  </p>
854
  <p>
855
+ Pour filtrer les produits qui se trouvent dans plusieurs catégories spécifiques, vous pouvez utiliser la fonction <c>array_match_any()</c>.
856
  </p>
857
  <p>
858
+ Voici quelques exemples d'utilisation :
859
  </p>
860
  {code=json}{
861
  ""ex0"":{""label"":""Boucle foreach dont l'itération se fait sur la catégorie"",""fees"":""{foreach product.categories}{selection.weight}{/foreach}""},
868
  ""ex7"":{""label"":""Somme des poids des produits dont l'id de la première catégorie est 12"",""fees"":""{sum product.weight where product.category.id==12}""}
869
  }{/code}
870
  "
871
+ "{os2editor.help.changelog}","
872
  <h4>Changelog</h4>
873
  <div class=changelog>{changelog}</div>
874
  "
package.xml CHANGED
@@ -1,7 +1,7 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Owebia_Shipping_2</name>
4
- <version>2.5.19</version>
5
  <stability>stable</stability>
6
  <license uri="http://www.opensource.org/licenses/MIT">The MIT License (MIT)</license>
7
  <channel>community</channel>
@@ -10,7 +10,18 @@
10
  <description>[EN] This module provides 3 shipping modes configurable with a very flexible syntax.&#xD;
11
  &#xD;
12
  [FR] Ce module met &#xE0; disposition 3 modes de livraison configurables avec une syntaxe tr&#xE8;s souple.</description>
13
- <notes>[2.5.19 - 09 novembre 2015]&#xD;
 
 
 
 
 
 
 
 
 
 
 
14
  Note: the extension is not affected by the patch SUPEE-6788 since it uses the new admin url routing syntax for 3 years (version 2.4.8.0)&#xD;
15
  Fix bug: deactivation of auto-escaping by default since it can cause some bugs (ex: impossible to use {address_filter.EU-27} in shipto)&#xD;
16
  Fix bug: fix auto-escaping of properties like {{shipto.country_name}}&#xD;
@@ -22,9 +33,9 @@ Fix bug: usage of regular expressions inside {count ...}, {sum ...}, {min ...} a
22
  Allow usage of php functions date and strtotime (ex: "label": "'Your package will be delivered between ' . date('d/m', strtotime('+5 days')) . ' and ' . date('d/m Y', strtotime('+7 days'))",&#xD;
23
  </notes>
24
  <authors><author><name>owebia</name><user>owebia</user><email>antoine.lemoine@owebia.com</email></author></authors>
25
- <date>2015-11-09</date>
26
- <time>18:48:22</time>
27
- <contents><target name="magecommunity"><dir name="Owebia"><dir name="Shipping2"><dir name="Block"><dir name="Adminhtml"><dir name="Os2"><dir name="Editor"><dir name="Property"><file name="Input.php" hash="da443c90f3dda730300654569b55d46c"/></dir></dir><file name="Editor.php" hash="571ff0d5da00f96a49aa9c0504d07a50"/><file name="Help.php" hash="d2f3fd818f9d5034365e0c57cd01448e"/></dir><dir name="System"><dir name="Config"><dir name="Form"><dir name="Field"><file name="Config.php" hash="66487da1f208546729207661de30e378"/><file name="Informations.php" hash="34eda44f2b4646f2acfe07be52440058"/></dir></dir></dir></dir></dir></dir><dir name="Controller"><file name="Abstract.php" hash="f1ad9781bcc1fe1382a714958fdaf388"/></dir><dir name="Helper"><file name="Data.php" hash="3f4ed53a2255cc3a7220f134b0dd4f12"/></dir><dir name="Model"><dir name="Carrier"><file name="Abstract.php" hash="fdf75d41b08704a92d5d64c73af1fd4d"/><file name="OwebiaShipping1.php" hash="6e4aa3ba4b3ec09a344a0f6a666645d1"/><file name="OwebiaShipping2.php" hash="e6a5d90fcf89910c119dad51a226a5ab"/><file name="OwebiaShipping3.php" hash="1a556c06950805f4d0b709e5f6b35743"/><file name="OwebiaShipping4.php" hash="ef18ccb1f5ed3e14ac93f40f69871a6e"/></dir><dir name="Mysql4"><file name="Setup.php" hash="79dd512a2278429c69ec92d0064e6bf3"/></dir><dir name="Os2"><dir name="Data"><file name="Abstract.php" hash="6d1aa6bf9270e0af4f349f2279760a80"/><file name="AbstractWithAttributes.php" hash="f51eedef920565ef5acbbb570af47805"/><file name="Address.php" hash="924940393fdf382b41d469e448be1e2d"/><file name="AddressFilter.php" hash="1ebed8610ace2b0f319c90ab6661b856"/><file name="AttributeSet.php" hash="8530ba04c22811a0014a39f03b389c75"/><file name="Billto.php" hash="fa430451c5d8cc01120e790607182546"/><file name="Cart.php" hash="9c3954c84a4470a3b95edc21b264f8a7"/><file name="CartItem.php" hash="42077e6f3055ec2a06c71b6fda08ef7c"/><file name="Category.php" hash="947a56f34136065e9ed5d5f8b775d408"/><file name="Customer.php" hash="98d521002435cb0997f3bf44fdc88fd8"/><file name="CustomerGroup.php" hash="dec898287825c0afab6f96b01fcc2b3c"/><file name="Customvar.php" hash="e9b59523ba14d23d1aeeaa4a8e432bec"/><file name="Date.php" hash="8e2120bb4b5c2c840f1fcbaf4f630f24"/><file name="Info.php" hash="922a1b57d0cb72e59335851e1a92cacc"/><file name="Product.php" hash="687b819acf9524bea522ed0c56e16249"/><file name="Quote.php" hash="4ef2d9152d8d536f1901b6fc16dc4182"/><file name="Selection.php" hash="8a055d68edfc5210cec7611f2d43448b"/><file name="StockItem.php" hash="b0345ea37ad9826a2822a911752cf06f"/><file name="Store.php" hash="f5e2f014a372e83787928e7f0218b12f"/></dir></dir><dir name="System"><dir name="Config"><dir name="Source"><file name="LoadOnParent.php" hash="31d5c899a174dc5ee046be9ec4080f5e"/><file name="ProcessChildren.php" hash="f7a1c4fd61bc52cfd29c3079c64a01fb"/></dir></dir></dir></dir><file name="changelog" hash="0526180765a45d21f45017965c261006"/><dir name="controllers"><dir name="Adminhtml"><dir name="Os2"><file name="AjaxController.php" hash="b954504ea1ba4fcebee59df9036efc9c"/></dir></dir><dir name="Checkout"><file name="CartController.php" hash="8c6ee136298e0e2dd0052143887282ce"/></dir></dir><file name="doc_en_US.html" hash="92fecf9fc34fd4611c47b529b5acb305"/><file name="doc_fr_FR.html" hash="bf99aa1758e17fca3f84981326ff0c32"/><dir name="etc"><file name="adminhtml.xml" hash="553cc9ec895436e0da108020de260885"/><file name="config.xml" hash="0dfb8a5818a8842f69a7a3bc7070ea32"/><file name="system.xml" hash="e549ba889f6d9b05e154ca49ab455ae0"/></dir><dir name="includes"><file name="OS2_AddressFilterParser.php" hash="867b63a23ee99b6cafb51e91759a9d00"/><file name="OwebiaShippingHelper.php" hash="a4800b33ac41ce1fcd2783db12cc6868"/></dir><dir name="sql"><dir name="owebia_shipping2_setup"><file name="mysql4-install-2.5.13.php" hash="807dad21a089045946ab1cf2b433f954"/></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Owebia_Shipping2.xml" hash="046e4a5822bd9a6c2e781bfbb33f7ebd"/></dir></target><target name="magelocale"><dir name="fr_FR"><file name="Owebia_Shipping2.csv" hash="a8c41b1a205a92de71b9e4621532c97d"/></dir><dir name="en_US"><file name="Owebia_Shipping2.csv" hash="e9d54947d5b38eb975fc0de4145ffe23"/></dir></target><target name="mageweb"><dir name="js"><dir name="owebia"><dir name="shipping2"><dir name="colorbox"><file name="colorbox.css" hash="1a7dd23f5d2962260d5bb26a57046db1"/><dir name="images"><file name="border.png" hash="439d585a4e35279cf1eddec5729f7144"/><file name="border.png-" hash="7ca8a1d2eb0763b35c266cd54bee2fa5"/><file name="controls.png" hash="4cbe54bbf6c352ea181a5739842215e2"/><file name="controls.png-" hash="b68b9ecaae424de4862ba0d055b7a560"/><dir name="ie6"><file name="borderBottomCenter.png" hash="1936585831e8bcf4eb5ef1081c8e2574"/><file name="borderBottomLeft.png" hash="7ceeb01563f030dc47837fd8bad29488"/><file name="borderBottomRight.png" hash="297fb77440870d91f519bcecdb312725"/><file name="borderMiddleLeft.png" hash="64df0244eeaade27764d2cf33606527b"/><file name="borderMiddleRight.png" hash="9fa458eaaa35b80b2452f35a1d6b4d0c"/><file name="borderTopCenter.png" hash="01ecb01841270f3a765aadf4900929f3"/><file name="borderTopLeft.png" hash="bf4949b95b09d255edd9bcb8358a3557"/><file name="borderTopRight.png" hash="51315fa19507a33d5f1b5411598593e7"/></dir><file name="loading.gif" hash="e6611f867d63754b7a2a974fb0a0e7dc"/><file name="loading_background.png" hash="acf427e932fb9413700a4b8b58b41eec"/><file name="overlay.png" hash="790376e15a036959e358a19d4a7ea437"/></dir><file name="jquery.colorbox-min.js" hash="afa27e7333f494cf87e4c07297c2160b"/></dir><dir name="img"><file name="btn-edit.png" hash="abc9f604977fc6dc75547a2e04c9748f"/><file name="btn-help.png" hash="b743486f26c3b69871490049147ef14b"/><file name="btn-remove.png" hash="42492684e24356a4081134894eabeb9e"/><dir name="famfamsilk"><file name="help.png" hash="c3812c74bc524179f4ccf5d2db7b3cbf"/><file name="pencil.png" hash="a34e71ab08a6d1162b948d26321dea50"/></dir></dir><file name="jquery-1.8.2.min.js" hash="cfa9051cc0b05eb519f1e16b2a6645d7"/><dir name="jquery-ui-1.8.23.custom"><dir name="css"><dir name="ui-lightness"><dir name="images"><file name="ui-bg_diagonals-thick_18_b81900_40x40.png" hash="95f9cceeb9d742dd3e917ec16ed754f8"/><file name="ui-bg_diagonals-thick_20_666666_40x40.png" hash="f040b255ca13e693da34ab33c7d6b554"/><file name="ui-bg_flat_10_000000_40x100.png" hash="c18cd01623c7fed23c80d53e2f5e7c78"/><file name="ui-bg_glass_100_f6f6f6_1x400.png" hash="5f1847175ba18c41322cb9cb0581e0fb"/><file name="ui-bg_glass_100_fdf5ce_1x400.png" hash="d26e8f463195a7b86f86b7d550cfc114"/><file name="ui-bg_glass_65_ffffff_1x400.png" hash="e5a8f32e28fd5c27bf0fed33c8a8b9b5"/><file name="ui-bg_gloss-wave_35_f6a828_500x100.png" hash="58d2cd501e01573cf537089c694ba899"/><file name="ui-bg_highlight-soft_100_eeeeee_1x100.png" hash="384c3f17709ba0f809b023b6e7b10b84"/><file name="ui-bg_highlight-soft_75_ffe45c_1x100.png" hash="b806658954cb4d16ade8977af737f486"/><file name="ui-icons_222222_256x240.png" hash="ebe6b6902a408fbf9cac6379a1477525"/><file name="ui-icons_228ef1_256x240.png" hash="79f41c0765e9ec18562b20b0801d748b"/><file name="ui-icons_ef8c08_256x240.png" hash="ef9a6ccfe3b14041928ddc708665b226"/><file name="ui-icons_ffd27a_256x240.png" hash="ab8c30acc0e3608fb79e01fccf832c70"/><file name="ui-icons_ffffff_256x240.png" hash="342bc03f6264c75d3f1d7f99e34295b9"/></dir><file name="jquery-ui-1.8.23.custom.css" hash="d4a4e04116e9bed6a2b00c5e8c260914"/></dir></dir><dir name="js"><file name="jquery-1.8.0.min.js" hash="cd8b0bffc85bb5614385ee4ce3596d07"/><file name="jquery-ui-1.8.23.custom.min.js" hash="c406c4654466fbeee1cf9173b69ec55c"/></dir></dir><file name="jquery.caret.1.02.min.js" hash="ee130de5e6b9ae2be7579a5fd77f7b23"/><file name="jquery.layout-1.3.0-rc30.6.min.js" hash="745e5e2084b6330c3f837a0169a96320"/><file name="jquery.layout.min.js" hash="d91b61c69554cd02f4cf3bbbf97b95a8"/><file name="jquery.noconflict.js" hash="3179f2255b046d5f2e9a71e365287bef"/><file name="os2editor.css" hash="96805f469cf7d6f2a7269d5d372fa46b"/><file name="os2editor.js" hash="107807e905cb39f178c1e349c7d89cb8"/></dir></dir></dir></target></contents>
28
  <compatible/>
29
  <dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php></required></dependencies>
30
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Owebia_Shipping_2</name>
4
+ <version>2.5.22</version>
5
  <stability>stable</stability>
6
  <license uri="http://www.opensource.org/licenses/MIT">The MIT License (MIT)</license>
7
  <channel>community</channel>
10
  <description>[EN] This module provides 3 shipping modes configurable with a very flexible syntax.&#xD;
11
  &#xD;
12
  [FR] Ce module met &#xE0; disposition 3 modes de livraison configurables avec une syntaxe tr&#xE8;s souple.</description>
13
+ <notes>[2.5.22 - July 18, 2016]&#xD;
14
+ Add composer.json and modman files&#xD;
15
+ &#xD;
16
+ [2.5.21 - May 9, 2016]&#xD;
17
+ Fix replacement of special functions, thanks to S&#xE9;bastien L.&#xD;
18
+ &#xD;
19
+ [2.5.20 - 25 avril 2016]&#xD;
20
+ Fix code indentation&#xD;
21
+ Fix version number&#xD;
22
+ Add readme file in package&#xD;
23
+ &#xD;
24
+ [2.5.19 - 09 novembre 2015]&#xD;
25
  Note: the extension is not affected by the patch SUPEE-6788 since it uses the new admin url routing syntax for 3 years (version 2.4.8.0)&#xD;
26
  Fix bug: deactivation of auto-escaping by default since it can cause some bugs (ex: impossible to use {address_filter.EU-27} in shipto)&#xD;
27
  Fix bug: fix auto-escaping of properties like {{shipto.country_name}}&#xD;
33
  Allow usage of php functions date and strtotime (ex: "label": "'Your package will be delivered between ' . date('d/m', strtotime('+5 days')) . ' and ' . date('d/m Y', strtotime('+7 days'))",&#xD;
34
  </notes>
35
  <authors><author><name>owebia</name><user>owebia</user><email>antoine.lemoine@owebia.com</email></author></authors>
36
+ <date>2016-07-26</date>
37
+ <time>18:30:15</time>
38
+ <contents><target name="magecommunity"><dir name="Owebia"><dir name="Shipping2"><dir name="Block"><dir name="Adminhtml"><dir name="Os2"><dir name="Editor"><dir name="Property"><file name="Input.php" hash="1f005c722d2a1aed36392b35b15a5ff8"/></dir></dir><file name="Editor.php" hash="3c9023bbd9599746eb59c03a1f880bb4"/><file name="Help.php" hash="8717b49c17a27648608f8f9bdab38a6a"/></dir><dir name="System"><dir name="Config"><dir name="Form"><dir name="Field"><file name="Config.php" hash="5a477abaf6e1a424a8b3c356bd7dbe1a"/><file name="Informations.php" hash="62e5bb722fdcdcab685bf61ac0074f9a"/></dir></dir></dir></dir></dir></dir><dir name="Controller"><file name="Abstract.php" hash="efcaf634de41e1a4077178ea6312639a"/></dir><dir name="Helper"><file name="Data.php" hash="bd60dce3af42acadc34981e9ac69f786"/></dir><dir name="Model"><dir name="Carrier"><file name="Abstract.php" hash="b24045dbbb2b1b94387b906cda15dba9"/><file name="OwebiaShipping1.php" hash="ff3b8bdbe01b9301ee742cecf9226477"/><file name="OwebiaShipping2.php" hash="2dc52a08f61991c4d09ba3cf217a32df"/><file name="OwebiaShipping3.php" hash="37ac69f726b7ad13f59902dbefd8a700"/></dir><dir name="Mysql4"><file name="Setup.php" hash="e09d64ce594327962d6b1b7d6c3ed40b"/></dir><dir name="Os2"><dir name="Data"><file name="Abstract.php" hash="aef3cc68958a3cf83bca10f429934b77"/><file name="AbstractWithAttributes.php" hash="6d18a42d3a0d79b55a7ddd4114a6fb9e"/><file name="Address.php" hash="7f26ec3694d31d50a4d005ca0751b808"/><file name="AddressFilter.php" hash="28acce2d71dba78c181d429cadaab40f"/><file name="AttributeSet.php" hash="8bf97bd54b0a8e0dd4187544dc3d7fc8"/><file name="Billto.php" hash="0a8a43a84f9d3c06f7ea55d8f1990642"/><file name="Cart.php" hash="efea6a0bd6ef8b1bc2cdaea5dcace2b3"/><file name="CartItem.php" hash="4edb6009ea6aa6656818ef1b1ce26c82"/><file name="Category.php" hash="3003514d1e8dac8805ec8dd26d4eb3f6"/><file name="Customer.php" hash="3afdc4f40f91f7c1ee1678037af0b9ce"/><file name="CustomerGroup.php" hash="c736f20d6e896a8129d623ff1ce77eaa"/><file name="Customvar.php" hash="92dbfd486307d080c142cd0d35675cd3"/><file name="Date.php" hash="2b3fa47f2fc916237e6ba3dd42a62c89"/><file name="Info.php" hash="7fd36af64125336c0d20aac799e638f0"/><file name="Product.php" hash="1c60fca3aff8d45e7f1aeb2241b9b09c"/><file name="Quote.php" hash="da284da608d12947da48e7fafa7e5d81"/><file name="Selection.php" hash="89691512c0e9757a4555c35ced8334d5"/><file name="StockItem.php" hash="fbcc58d7681b69e496c5794d4bcf4b55"/><file name="Store.php" hash="a9d1dc040da92aeb9786e52f31749668"/></dir></dir><dir name="System"><dir name="Config"><dir name="Source"><file name="LoadOnParent.php" hash="79591634a7c58ad32daf800cbd66b2c9"/><file name="ProcessChildren.php" hash="8d59e235c55d1c5eef4dbeafbfc045eb"/></dir></dir></dir></dir><file name="changelog" hash="9f52498229508227159bf3c8caa5dde8"/><dir name="controllers"><dir name="Adminhtml"><dir name="Os2"><file name="AjaxController.php" hash="534f70706d1e3987e72c0fa5fd3cdaf1"/></dir></dir><dir name="Checkout"><file name="CartController.php" hash="71fbc28d6d6aea32bc8594c4c52e2f50"/></dir></dir><file name="doc_en_US.html" hash="ab7c8ac33706fb983a715d34e127c3f6"/><file name="doc_fr_FR.html" hash="9f3cb179b4dadfce6725b2c28130766c"/><dir name="etc"><file name="adminhtml.xml" hash="676a879b29e5aa7da838823ae809712e"/><file name="config.xml" hash="102be286c1b3fbf2d65e71ba30e15398"/><file name="system.xml" hash="b2475166887331725c844f5c3369c578"/></dir><dir name="includes"><file name="OS2_AddressFilterParser.php" hash="18c3c0c0c7bc397b8ac0a26219752bf8"/><file name="OwebiaShippingHelper.php" hash="bdb75ff9d3937bed1eeb6e2dbd79cf61"/></dir><dir name="sql"><dir name="owebia_shipping2_setup"><file name="mysql4-install-2.5.13.php" hash="ac3e7a144feee98c135478970f5a39a2"/></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Owebia_Shipping2.xml" hash="83124ea7b75f38d07ee381f02a8bf038"/></dir></target><target name="magelocale"><dir name="fr_FR"><file name="Owebia_Shipping2.csv" hash="f0acbd884002e91c169cd01f0b95a9c7"/></dir><dir name="en_US"><file name="Owebia_Shipping2.csv" hash="b287f5594199379e78a3b88f8f279899"/></dir></target><target name="mageweb"><dir name="js"><dir name="owebia"><dir name="shipping2"><dir name="colorbox"><file name="colorbox.css" hash="1a7dd23f5d2962260d5bb26a57046db1"/><dir name="images"><file name="border.png" hash="439d585a4e35279cf1eddec5729f7144"/><file name="border.png-" hash="7ca8a1d2eb0763b35c266cd54bee2fa5"/><file name="controls.png" hash="4cbe54bbf6c352ea181a5739842215e2"/><file name="controls.png-" hash="b68b9ecaae424de4862ba0d055b7a560"/><dir name="ie6"><file name="borderBottomCenter.png" hash="1936585831e8bcf4eb5ef1081c8e2574"/><file name="borderBottomLeft.png" hash="7ceeb01563f030dc47837fd8bad29488"/><file name="borderBottomRight.png" hash="297fb77440870d91f519bcecdb312725"/><file name="borderMiddleLeft.png" hash="64df0244eeaade27764d2cf33606527b"/><file name="borderMiddleRight.png" hash="9fa458eaaa35b80b2452f35a1d6b4d0c"/><file name="borderTopCenter.png" hash="01ecb01841270f3a765aadf4900929f3"/><file name="borderTopLeft.png" hash="bf4949b95b09d255edd9bcb8358a3557"/><file name="borderTopRight.png" hash="51315fa19507a33d5f1b5411598593e7"/></dir><file name="loading.gif" hash="e6611f867d63754b7a2a974fb0a0e7dc"/><file name="loading_background.png" hash="acf427e932fb9413700a4b8b58b41eec"/><file name="overlay.png" hash="790376e15a036959e358a19d4a7ea437"/></dir><file name="jquery.colorbox-min.js" hash="afa27e7333f494cf87e4c07297c2160b"/></dir><dir name="img"><file name="btn-edit.png" hash="abc9f604977fc6dc75547a2e04c9748f"/><file name="btn-help.png" hash="b743486f26c3b69871490049147ef14b"/><file name="btn-remove.png" hash="42492684e24356a4081134894eabeb9e"/><dir name="famfamsilk"><file name="help.png" hash="c3812c74bc524179f4ccf5d2db7b3cbf"/><file name="pencil.png" hash="a34e71ab08a6d1162b948d26321dea50"/></dir></dir><file name="jquery-1.8.2.min.js" hash="cfa9051cc0b05eb519f1e16b2a6645d7"/><dir name="jquery-ui-1.8.23.custom"><dir name="css"><dir name="ui-lightness"><dir name="images"><file name="ui-bg_diagonals-thick_18_b81900_40x40.png" hash="95f9cceeb9d742dd3e917ec16ed754f8"/><file name="ui-bg_diagonals-thick_20_666666_40x40.png" hash="f040b255ca13e693da34ab33c7d6b554"/><file name="ui-bg_flat_10_000000_40x100.png" hash="c18cd01623c7fed23c80d53e2f5e7c78"/><file name="ui-bg_glass_100_f6f6f6_1x400.png" hash="5f1847175ba18c41322cb9cb0581e0fb"/><file name="ui-bg_glass_100_fdf5ce_1x400.png" hash="d26e8f463195a7b86f86b7d550cfc114"/><file name="ui-bg_glass_65_ffffff_1x400.png" hash="e5a8f32e28fd5c27bf0fed33c8a8b9b5"/><file name="ui-bg_gloss-wave_35_f6a828_500x100.png" hash="58d2cd501e01573cf537089c694ba899"/><file name="ui-bg_highlight-soft_100_eeeeee_1x100.png" hash="384c3f17709ba0f809b023b6e7b10b84"/><file name="ui-bg_highlight-soft_75_ffe45c_1x100.png" hash="b806658954cb4d16ade8977af737f486"/><file name="ui-icons_222222_256x240.png" hash="ebe6b6902a408fbf9cac6379a1477525"/><file name="ui-icons_228ef1_256x240.png" hash="79f41c0765e9ec18562b20b0801d748b"/><file name="ui-icons_ef8c08_256x240.png" hash="ef9a6ccfe3b14041928ddc708665b226"/><file name="ui-icons_ffd27a_256x240.png" hash="ab8c30acc0e3608fb79e01fccf832c70"/><file name="ui-icons_ffffff_256x240.png" hash="342bc03f6264c75d3f1d7f99e34295b9"/></dir><file name="jquery-ui-1.8.23.custom.css" hash="d4a4e04116e9bed6a2b00c5e8c260914"/></dir></dir><dir name="js"><file name="jquery-1.8.0.min.js" hash="cd8b0bffc85bb5614385ee4ce3596d07"/><file name="jquery-ui-1.8.23.custom.min.js" hash="c406c4654466fbeee1cf9173b69ec55c"/></dir></dir><file name="jquery.caret.1.02.min.js" hash="ee130de5e6b9ae2be7579a5fd77f7b23"/><file name="jquery.layout-1.3.0-rc30.6.min.js" hash="745e5e2084b6330c3f837a0169a96320"/><file name="jquery.layout.min.js" hash="d91b61c69554cd02f4cf3bbbf97b95a8"/><file name="jquery.noconflict.js" hash="3179f2255b046d5f2e9a71e365287bef"/><file name="os2editor.css" hash="96805f469cf7d6f2a7269d5d372fa46b"/><file name="os2editor.js" hash="107807e905cb39f178c1e349c7d89cb8"/></dir></dir></dir></target><target name="mage"><dir name="."><file name="README.md" hash="9efbb43e081442a1fbeefa9cfdc26b62"/></dir></target></contents>
39
  <compatible/>
40
  <dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php></required></dependencies>
41
  </package>