diff --git a/releases/plg_opentools_vm2_rules_shipping_advanced_v4.0.1.zip b/releases/plg_opentools_vm2_rules_shipping_advanced_v4.0.1.zip new file mode 100644 index 0000000000000000000000000000000000000000..3ab1d1deb1247354811c8eadb99377332443c98c Binary files /dev/null and b/releases/plg_opentools_vm2_rules_shipping_advanced_v4.0.1.zip differ diff --git a/releases/plg_opentools_vm2_rules_shipping_v4.0.1.zip b/releases/plg_opentools_vm2_rules_shipping_v4.0.1.zip index d8da980f9b156c98814620346662c7565b9d67c2..e16f0939064c8f2a09ce577d4bc78c6d6a9368f3 100644 Binary files a/releases/plg_opentools_vm2_rules_shipping_v4.0.1.zip and b/releases/plg_opentools_vm2_rules_shipping_v4.0.1.zip differ diff --git a/rules_shipping_advanced.php b/rules_shipping_advanced.php index e6c845c9a16ecaffa16d5f389da457218a9e5e6b..f4e18fbb265121385334164129e967d27731964c 100644 --- a/rules_shipping_advanced.php +++ b/rules_shipping_advanced.php @@ -113,7 +113,7 @@ class ShippingRule_Advanced extends ShippingRule { // (OR, AND, in; but make sure we don't capture parts of words, so we need to // use lookbehind/lookahead patterns to exclude OR following another letter // or followed by another letter) and then all arithmetic operators - $re = '/\s*("[^"]*"|\'[^\']*\'|(?<![A-Za-z0-9])(?:OR|AND|IN)(?![A-Za-z0-9])|&&|<=|=>|>=|=>|<>|!=|==|<|=|>|~|\+|-|\*|\/|%|\(|\)|\^|,)\s*/i'; + $re = '/\s*("[^"]*"|\'[^\']*\'|(?<![A-Za-z0-9])(?:OR|AND|IN)(?![A-Za-z0-9])|&&|<=|=>|>=|=<|<>|!=|==|<|=|>|~|\+|-|\*|\/|%|\(|\)|\^|,)\s*/i'; $atoms = preg_split($re, $expression, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY); // JFactory::getApplication()->enqueueMessage("TOKENIZING '$expression' returns: <pre>".print_r($atoms,1)."</pre>", 'error'); return $atoms; diff --git a/rules_shipping_advanced.xml b/rules_shipping_advanced.xml index 5cf2a7cc971ec8bcc687f870055779992e3f548d..6d31caabbe281bd64db1af1ec94665464f509094 100644 --- a/rules_shipping_advanced.xml +++ b/rules_shipping_advanced.xml @@ -1,12 +1,12 @@ <?xml version="1.0" encoding="UTF-8" ?> <install version="1.5" type="plugin" group="vmshipment" method="upgrade"> <name>VMSHIPMENT_RULES_ADV</name> - <creationDate>2014-01-12</creationDate> + <creationDate>2014-01-14</creationDate> <author>Reinhold Kainhofer</author> <authorUrl>http://www.open-tools.net</authorUrl> <copyright>Copyright (C) 2013, Reinhold Kainhofer</copyright> <license>GPL v3+</license> - <version>4.0</version> + <version>4.0.1</version> <description>VMSHIPMENT_RULES_ADV_DESC</description> <files> <filename plugin="rules_shipping_advanced">rules_shipping_advanced.php</filename> diff --git a/rules_shipping_base.php b/rules_shipping_base.php index 7a8c3ec38b0acd72b93269324cb5dbf15c6d696d..cbaed53f3fd38222a345a47df8e8c539526e5eb2 100644 --- a/rules_shipping_base.php +++ b/rules_shipping_base.php @@ -787,15 +787,36 @@ class ShippingRule { } + function tokenize_expression ($expression) { + // First, extract all strings, delimited by quotes, then all text operators + // (OR, AND, in; but make sure we don't capture parts of words, so we need to + // use lookbehind/lookahead patterns to exclude OR following another letter + // or followed by another letter) and then all arithmetic operators + $re = '/\s*("[^"]*"|\'[^\']*\'|<=|=>|>=|=<|<>|!=|==|<|=|>)\s*/i'; + $atoms = preg_split($re, $expression, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY); + // JFactory::getApplication()->enqueueMessage("TOKENIZING '$expression' returns: <pre>".print_r($atoms,1)."</pre>", 'error'); + return $atoms; + } + function parseRulePart($rulepart) { /* In the basic version, we only split at the comparison operators and assume each term on the LHS and RHS is one variable or constant */ /* In the advanced version, all conditions and costs can be given as a full mathematical expression */ /* Both versions create an expression tree, which can be easily evaluated in evaluateTerm */ - $operators = array('<', '<=', '=', '>', '>=', '=>', '=<', '<>', '!=', '=='); - $op_re='/\s*(<=|=>|>=|=>|<>|!=|==|<|=|>)\s*/'; $rulepart = trim($rulepart); if (empty($rulepart)) return; - $atoms = preg_split ($op_re, $rulepart, -1, PREG_SPLIT_DELIM_CAPTURE); + + + // Special-case the name assignment, where we don't want to interpret the value as an arithmetic expression! + if (preg_match('/^\s*(name|variable|definition)\s*=\s*(["\']?)(.*)\2\s*$/i', $rulepart, $matches)) { + $this->handleAssignment ($matches[1], $matches[3], $rulepart); + return; + } + + // Split at all operators: + $atoms = $this->tokenize_expression ($rulepart); + + /* TODO: Starting from here, the advanced plugin is different! */ + $operators = array('<', '<=', '=', '>', '>=', '=>', '=<', '<>', '!=', '=='); if (count($atoms)==1) { $this->shipping = $this->parseShippingTerm($atoms[0]); } elseif ($atoms[1]=='=') {