You are here:  » Voucher Inclusion


Voucher Inclusion

Submitted by kend on Fri, 2016-02-19 01:49 in

Hi David,

I have used the script modification here to allow exclusion criteria: http://www.pricetapestry.com/node/5081. This modification looks for specified term and flags voucher as false when found. FYI, I also modified the modification to search the name string using a stristr because the brand field is not provided in most feeds. I search the name field for several terms. This seems to work fine, so no concerns here.

But I also want to allow inclusion criteria because some vouchers exclude brands, others include brands.

The problem is in using the inclusion modification here: http://www.pricetapestry.com/node/4976#comment-20429, is that when there is more than one criteria for the same field, the mod doesn't work for me. I tried to reverse the logic and set $isValid to TRUE, but I think there's a gotcha in there somewhere.

So because I'm a bit brain fried at the moment, I was wondering if you have the answer for what I am trying to do?

EXAMPLE: Voucher valid for [name = Sony & name = Panasonic & name = Pioneer]

Regards,
Ken.

Submitted by support on Fri, 2016-02-19 12:28

Hello Ken,

I have been considering an "Advanced" match option covering multiple fields so I have just worked through the code for this. First edit admin/voucher_codes_edit.php and look for the following code at line 368:

  $match_types = array("exact"=>"Exact Match","keyword"=>"Keyword Match");

...and REPLACE with:

  $match_types = array("exact"=>"Exact Match","keyword"=>"Keyword Match","advanced"=>"Advanced Match");

Next, edit includes/tapestry.php and look for the following code at line 184:

  case "exact":

...and REPLACE with:

  case "advanced":
    $advancedMatched = TRUE;
    $expressions = explode("&",$voucher["match_value"]);
    foreach($expressions as $expression)
    {
      preg_match("/([^!=~]*)(=|~|!=|!~)(.*)/",$expression,$matches);
      foreach($matches as $k1 => $v) $matches[$k1] = trim($v);
      $field = $matches[1];
      $operator = $matches[2];
      $value = strtolower($matches[3]);
      $test = strtolower($product[$field]);
      switch($operator)
      {
        case "=":
          $advancedMatched = ($test==$value);
          break;
        case "~":
          $advancedMatched = (strpos($test,$value)!==FALSE);
          break;
        case "!=":
          $advancedMatched = ($test!=$value);
          break;
        case "!~":
          $advancedMatched = (strpos($test,$value)===FALSE);
          break;
      }
      if (!$advancedMatched) break;
    }
    $matched = $advancedMatched;
    break;
  case "exact":

This will add an "Advanced" match type option. Leave Match Field as "Product Name" but this is ignored for the Advanced option.

Construct the value field as a sequence of expressions separated by "&", where each expression comprises <field name> <operator> <value>. For <operator>, use:

= Equals (exact match)

~ Equals (keyword match)

!= Not Equals (exact match)

!~ Not Equals (keyword match)

All expressions in the sequence must evaluate to TRUE for the voucher to be applied.

For example:

category = Televisions & brand != Sony & brand != Panasonic

...will apply the voucher code to all products in the Televisions category, but NOT if the brand is Sony or Panasonic.

Hope this helps!

Cheers,
David.
--
PriceTapestry.com

Submitted by kend on Fri, 2016-02-19 16:26

Hi David,

Interesting solution!

I'm wondering if something is broken in the preg_match because when using name=product1 I print_r() a result like follows:

Array
(
[0] => name~Product1
[1] => nam
[2] => e~
[3] => Product1
)

Actually, the first problem I had was that when using name!=Product1, expressions were evaluating correctly to 1 or nothing but voucher was not being applied. I'm still working on that...

Thanks!
Ken.

Submitted by support on Fri, 2016-02-19 16:35

Hi Ken,

The regular expression i'd derived for preg_match() was dependent upon the spaces either side of the operator - a function of the default "greedy" behaviour of regular expression matching.

I've reworked the expression instead using a "match anything but" as the first bracketed part so this will now work either with or without the white space:

    preg_match("/([^!=~]*)(=|~|!=|!~)(.*)/",$expression,$matches);

(corrected above also)

Cheers,
David.
--
PriceTapestry.com

Submitted by kend on Mon, 2016-02-22 01:07

Hi David,

Thank you for supplying code and methods, especially late on a Friday afternoon your time. I do appreciate it.

I used above code, though further modified, to complete what I want.

Regards,
Ken.

Submitted by philstone on Sun, 2016-07-24 19:26

Hi David

Using this modification and it's great

I have two feeds and the merchants supply voucher codes against ean's

so wanting to use:

ean = 0000000000001,0000000000002,0000000000003
the problem is the field can only contain 255 max characters, if i change this to text as opposed to varchar will it stop working? what would you advise?

regards

Phil Stone

Submitted by support on Mon, 2016-07-25 11:29

Hi Phil,

No problem at all - you can change `match_value` to TEXT on `pt_vouchers` as required...

Cheers,
David.
--
PriceTapestry.com

Submitted by sirmanu on Fri, 2018-05-18 13:24

Hi David.

Awesome mod.
However, I don't know if I can use it, or this mod needs another small modification.
The thing is that I have a merchant where the coupon can be applied to categories clothing and accesories, but some brands are excluded (like Samsung and Garmin).

Could be feasible to implement OR operator?
Somesthing like this

(category ~ clothing | category ~ accessories) & brand !~ Garmin & brand !~ Samsung

Regards

Submitted by support on Sat, 2018-05-19 08:38

Hi,

As that could get pretty complicated to code up what would be more straight forward I think would be to add an additional match type "Function", with the name of a custom function added to config.advanced.php to be called for the $product being tested which returns TRUE or FALSE as required.

To do this, first apply the above modifications if not in place already (I made one correction to the line numbering), and then edit admin/voucher_codes_edit.php and look for the following code at line 368:

  $match_types = array("exact"=>"Exact Match","keyword"=>"Keyword Match","advanced"=>"Advanced Match");

...and REPLACE with:

  $match_types = array("exact"=>"Exact Match","keyword"=>"Keyword Match","advanced"=>"Advanced Match","function"=>"Function Match");

And then edit includes/tapestry.php and look for the following code at line 214:

  case "exact":

...and REPLACE with:

  case "function":
    $fn = "config_".$match_value;
    $matched = $fn($product);
    break;
  case "exact":

With that in place, for your example criteria, add the following new code to config.advanced.php:

  function config_voucherCodeMatch1($product)
  {
    return (
      (($product["category"]=="Clothing") || ($product["category"]=="Accessories"))
      &&
      ($product["brand"]!="Garmin")
      &&
      ($product["brand"]!="Samsung")
    );
  }

(values for comparison will be case sensitive)

Now add your Voucher Code, for Match Type choose "Function", and enter the value:

voucherCodeMatch1

Hope this helps!

Cheers,
David.
--
PriceTapestry.com

Submitted by support on Mon, 2018-05-21 08:46

Hi sirmanu,

Sorry for the late reply I had some database issues with the forum but the code you posted looks fine if that is sufficiently flexible for your criteria...

Cheers,
David.
--
PriceTapestry.com