From b7b6ac6ffa9236d84348864147f85ede7769f4f1 Mon Sep 17 00:00:00 2001
From: Reinhold Kainhofer <reinhold@kainhofer.com>
Date: Sat, 22 Nov 2014 22:14:09 +0100
Subject: [PATCH] Pass the rule to custom functions in plugins; Fix NoShipping;
 fix plugins with no matching rule

---
 plugins/template/YOUR_PLUGIN_NAME.php | 13 ++++++++-----
 plugins/template/YOUR_PLUGIN_NAME.xml |  2 +-
 rules_shipping_base.php               |  8 +++++---
 3 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/plugins/template/YOUR_PLUGIN_NAME.php b/plugins/template/YOUR_PLUGIN_NAME.php
index d9099ec..5dcf82c 100644
--- a/plugins/template/YOUR_PLUGIN_NAME.php
+++ b/plugins/template/YOUR_PLUGIN_NAME.php
@@ -22,7 +22,8 @@ if (!class_exists ('VmPlugin')) {
 }
 
 // An example callback function to provide a custom function for shipping rules:
-function custom_test_function($args) {
+function custom_test_function($args, $rule) {
+	JFactory::getApplication()->enqueueMessage(JText::sprintf("Evaluating function custom_test_function in rule '%s'", htmlentities($rule->rulestring)), 'warning');
 	return count($args);
 }
 
@@ -54,10 +55,12 @@ class plgVmShipmentRulesYOUR_PLUGIN_NAME extends VmPlugin {
 	 *  The onVmShippingRulesRegisterCustomFunctions() trigger is expected to return an array of the form:
 	 *   array ('functionname1' => 'function_to_be_called',
 	 *          'functionname2' => array($classobject, 'memberfunc')),
+	 *          'functionname3' => array('classname', 'staticmemberfunc')),
 	 *          ...);
-	 *  The callback functions referenced here are called with exactly one array argument that holds 
-	 *  all function arguments, i.e. the function signature should be
-	 *     function function_to_be_called($args) {....}
+	 *  The callback functions referenced here are called with an array argument that holds 
+	 *  all function arguments and the rule itself, so that error messages can display the offending rule.
+	 *  I.e. the function signature should be
+	 *     function function_to_be_called($args, $rule) {....}
 	 *
 	 *  All arguments passed to the function will already be properly evaluated before the function is called.
 	 */
@@ -70,7 +73,7 @@ class plgVmShipmentRulesYOUR_PLUGIN_NAME extends VmPlugin {
 		);
 	}
 	
-	function custom_test_function_member($args) {
+	function custom_test_function_member($args, $rule) {
 		return 'CustomTestFunction called with '.count($args).' arguments.';
 	}
 }
diff --git a/plugins/template/YOUR_PLUGIN_NAME.xml b/plugins/template/YOUR_PLUGIN_NAME.xml
index 0ffdfa5..231d9aa 100644
--- a/plugins/template/YOUR_PLUGIN_NAME.xml
+++ b/plugins/template/YOUR_PLUGIN_NAME.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" ?>
-<extension version="1.5" type="plugin" group="vmshipmentrules" method="upgrade">
+<extension version="2.5" type="plugin" group="vmshipmentrules" method="upgrade">
     <name>VMSHIPMENTRULES_TEMPLATE</name>
     <creationDate>2014-11-10</creationDate>
     <author>Reinhold Kainhofer, Open Tools</author>
diff --git a/rules_shipping_base.php b/rules_shipping_base.php
index 20f8427..fdf680b 100644
--- a/rules_shipping_base.php
+++ b/rules_shipping_base.php
@@ -324,7 +324,7 @@ class plgVmShipmentRules_Shipping_Base extends vmPSPlugin {
 		if (!isset($this->rules[$method->virtuemart_shipmentmethod_id])) 
 			$this->parseMethodRules($method);
 		$match = $this->evaluateMethodRules ($cart, $method, $cart_prices);
-		if ($match) {
+		if ($match && !is_null ($match['rule'])) {
 			$method->rule_name = $match["rule_name"];
 			// If NoShipping is set, this method should NOT offer any shipping at all, so return FALSE, otherwise TRUE
 			// If the rule has a name, print it as warning (otherwise don't print anything)
@@ -405,7 +405,7 @@ class plgVmShipmentRules_Shipping_Base extends vmPSPlugin {
 
 		$cart_prices[$this->_psType . 'Value'] = $calculator->roundInternal ($this->getCosts ($cart, $method, $cart_prices), 'salesPrice');
 		// BEGIN_RK_CHANGES
-		$includes_tax = $method->includes_tax;
+		$includes_tax = isset($method->includes_tax) && $method->includes_tax;
 		if ($includes_tax) {
 			$cart_prices['salesPrice' . $_psType] = $cart_prices[$this->_psType . 'Value'];
 		}
@@ -1222,7 +1222,7 @@ class ShippingRule {
 		// This is done first to allow plugins to override even built-in functions!
 		if (isset($this->plugin->custom_functions[$func])) {
 			vmDebug("Evaluating custom function $function, defined by a plugin");
-			return call_user_func($this->plugin->custom_functions[$func], $args);
+			return call_user_func($this->plugin->custom_functions[$func], $args, $this);
 		}
 
 		// Functions with no argument:
@@ -1300,6 +1300,8 @@ class ShippingRule {
 		$varname = strtolower($expr);
 		if (array_key_exists(strtolower($expr), $vals)) {
 			return $vals[strtolower($expr)];
+		} elseif ($varname=='noshipping') {
+			return $varname;
 		} elseif ($varname=='values') {
 			return $vals;
 		} elseif ($varname=='values_debug') {
-- 
GitLab