Login
Register

VirtueMart

WooCommerce

Others

Docs

Support

Blog

About

Shipping by Rules for VirtueMart

IMPORTANT ANNOUNCEMENT: Plugin development ceased, all plugins made available freely (GPL)

With great sadness we have to announce that we are ceasing development of all our VirtueMart, WooCommerce and Joomla plugins. Effective immediately, all our plugins -- even those that were paid downloads -- are made available for free from our homepage (GPL license still applies), but we cannot and will not provide any support anymore.

It has been a great pleasure to be part of the thriving development communities of VirtueMart as well as WooCommerce. However, during the last year it became painstakingly clear that in addition to a full-time job, a young family and several other time-consuming hobbies at professional level (like being a professional singer) the plugin development and the support that it requires is not sustainable and is taking its toll. It has been an honor, but it is now time to say good bye!

×

Notice

The forum is in read only mode.
Welcome, Guest
Username: Password: Remember me
  • Page:
  • 1

TOPIC:

Help! Ship based on String Custom Field 31 May 2015 07:01 #1

  • bigchief
  • bigchief's Avatar Topic Author
Hello! I purchased advanced shipping rules and I need to know how to ship based on a string custom field value. How can I set up a rule to ship if the string is equal to a certain value?

Help! Ship based on String Custom Field 01 Jun 2015 02:45 #2

  • bigchief
  • bigchief's Avatar Topic Author
I am trying to create a plugin to detect if my product has a string type custom field named "framed"
My code is below. Please help! I need to be able to detect if the product has the attribute "framed" or not.
<?php

defined ('_JEXEC') or die('Restricted access');

if (!class_exists ('VmPlugin')) {
	require(JPATH_VM_PLUGINS . DS . 'vmplugin.php');
}

// An example callback function to provide a custom function for shipping rules:
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);
}

function onVmShippingRulesGetCartValues(&$cartvals, $cart, $products, $method, $cart_prices) {
  $cartvals['framed'] = false;
  foreach ($products as $p) {
    foreach ($p->customProductData as $cf) {
      if ($cf->custom_title=="framed" and $cf->custom_value==1) {
        $cartvals['framed'] = true;
      }
    }
  }
}

function onVmShippingRulesRegisterCustomFunctions() {
		return array(
			// An example of a custom function that calls a member of this plugin class:
			'customTestFunctionMember' => array($this, 'custom_test_function_member'),
			// An example of a custom function that calls an ordinary top-level php function:
			'customTestFunction' => 'custom_test_function',
		);
	}
	
	function custom_test_function_member($args, $rule) {
		return 'CustomTestFunction called with '.count($args).' arguments.';
	}
}

I've used the template from this URL: www.open-tools.net/virtuemart/advanced-s...ipping-by-rules.html and changed the plugin name in the xml and php files. My products each have a custom field that is either "framed" or "unframed" and I need different shipping prices depending on what the user selects.

Any help is much appreciated. Thank you!

Help! Ship based on String Custom Field 02 Jun 2015 00:49 #3

Dear BigChief,
I hope you are aware that the shipping plugin is not really designed to calculate shipping costs on a per-product basis (apparently you want to have different shipping costs per product depending on that custom field).

Second, your code seems to be missing the class object: all those functions should be members of a class, which needs to be named appropriately. Please take another look at the plugin template and adjust the last part of the class name to the name of your plugin.

I suppose you have taken the code to detect the custom field from open-tools.net/forum/shipping-by-rules-p...te-custom-field.html, so there is no need pointing you there.

Best regards,
Reinhold

Help! Ship based on String Custom Field 02 Jun 2015 08:14 #4

  • bigchief
  • bigchief's Avatar Topic Author
Thank you for your time. I did follow the template and I named the class correctly.
<?php

defined ('_JEXEC') or die('Restricted access');

/**
 * Plugin providing Custom variables for VM Shipping by Rules
 *
 * @subpackage Plugins - VmShipmentRules
 * @copyright Copyright (C) 2014 Reinhold Kainhofer, office@open-tools.net
 * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.php
 * VirtueMart is free software. This version may have been modified pursuant
 * to the GNU General Public License, and as distributed it includes or
 * is derivative of works licensed under the GNU General Public License or
 * other free or open source software licenses.
 * See administrator/components/com_virtuemart/COPYRIGHT.php for copyright notices and details.
 *
 * http://open-tools.net/
 *
 */
if (!class_exists ('VmPlugin')) {
	require(JPATH_VM_PLUGINS . DS . 'vmplugin.php');
}

// An example callback function to provide a custom function for shipping rules:
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);
}

/** Extension plugin for the "Shipping by Rules" shipping plugin for VirtueMart
 */
class plgVmShipmentRulesshipping_custom extends VmPlugin {
	/**  Trigger to add variables to the cart values
	  *  You can add new variables to the $cartvals array or modify existing ones. They will be directly 
	  *  available in all rules.
	  *  This trigger will be first called right before any rule is evaluated. In that case, $products 
	  *  will contain all products in the cart and $cart_prices will be an arrow containing the calculated
	  *  prices of the order.
	  *  Please notice that this function might also be called for only a subset of products of the cart
	  *  when the plugin evaluates a scoping function like evaluate_for_categories(...).
	  *  In that case, $cart_prices will be NULL and the $products array will hold only those products that 
	  *  actually match the filter, and only those should be used to calculate your custom variables.
	  *  So you can not in general rely on the cart_prices argument to hold the properly summed prices.
	  
	function onVmShippingRulesGetCartValues(&$cartvals, $cart, $products, $method, $cart_prices) {
		if ($cart_prices) {
			// Called for the whole cart...
		} else {
			// Called when any of the scoping operators need the cart values for only a subset of products
		}
		$cartvals['template_example'] = 123456789;
		
	}*/
		function onVmShippingRulesGetCartValues(&$cartvals, $cart, $products, $method, $cart_prices) {
  $cartvals['framed'] = false;
  foreach ($products as $p) {
    foreach ($p->customProductData as $cf) {
      if ($cf->customfield_value=="Framed") {
        $cartvals['framed'] = true;
      }
    }
  }
}
	/** Trigger to register custom functions for the Shipping by Rules plugin 
	 *  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 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.
	 */
	function onVmShippingRulesRegisterCustomFunctions() {
		return array(
			// An example of a custom function that calls a member of this plugin class:
			'customTestFunctionMember' => array($this, 'custom_test_function_member'),
			// An example of a custom function that calls an ordinary top-level php function:
			'customTestFunction' => 'custom_test_function',
		);
	}
	
	function custom_test_function_member($args, $rule) {
		return 'CustomTestFunction called with '.count($args).' arguments.';
	}
}

// No closing tag

Help! Ship based on String Custom Field 02 Jun 2015 08:15 #5

  • bigchief
  • bigchief's Avatar Topic Author
Is there any way to have a rule based on if a custom field is chosen?

Help! Ship based on String Custom Field 09 Jun 2015 02:42 #6

Dear BigChief,
Your plugin code looks fine (I suppose you renamed the plugin directory to plugins/vmshippingrules/shipping_custom/, also renamed the plugin files properly and correspondingly adjusted the .xml file; Also don't forget to enable the plugin in joomla!).
To test whether your plugin is loaded at all, simply add
JFactory::getApplication()->enqueueMessage("Plugin file is loaded", 'error');
before your class definition. Now whenever to go to the cart page, the "error" message "Plugin file is loaded" should be printed. You need to have at least one shipping method set up that uses the shipping by rules plugin.

If that works, you can add a similar call to the onVmShippingRulesGetCartValues function to check whether the function is called properly.

If that is the case, you can access the "framed" variable in all your rules just like all the built-in variables. E.g.
Name=Shipping for framed products; Condition=framed; Shipping=500
Name=Shipping for unframed products; Shipping=0
Please notice the "Condition=", because otherwise the plugin might not properly identify that rule part as a condition.

Best regards,
Reinhold
  • Page:
  • 1