You are here:  » Filter commission junction multi-level category fields


Filter commission junction multi-level category fields

Submitted by johan_norlund on Thu, 2006-07-13 09:18 in

Hello (again) David!

I read a forum thread similar to this one where you described how to add a "Split before" filter to filters.php, but it didn't help me in this case.

I have started using Commission Junction's datafeed service (which by the way works great) for my site and came across this little problem. You see, a few of my merchants have specified multi-level categories in the category field. Like this:

Electronics, Car Electronics, Mobile Video, LCD Monitors, Visor Monitors

Is it possible to make a filter that returns everything BETWEEN two specified characters? In this case I want to return everything between the third and fourth comma, thus giving me the category name of the fouth category level.

Thanks heaps!
Johan

Submitted by support on Thu, 2006-07-13 10:50

Hi Johan,

If you add both the Split Before and Split After filters to your includes/filter.php file, you should be able to do it by using 3 "Split After" filters (on commma), followed by a final "Split Before" filter to return the 3rd category....

<?php
  
/*************************************************/
  /* splitBefore */
  /*************************************************/
  
$filter_names["splitBefore"] = "Split Before";
  function 
filter_splitBeforeConfigure($filter_data)
  {
    print 
"Split Character or String:<br />";
    print 
"<input type='text' size='40' name='text' value='".widget_safe($filter_data["text"])."' />";
    
widget_errorGet("text");
  }
  function 
filter_splitBeforeValidate($filter_data)
  {
    if (!
$filter_data["text"])
    {
      
widget_errorSet("text","required field");
    }
  }
  function 
filter_splitBeforeExec($filter_data,$text)
  {
    
$pos strpos($text,$filter_data["text"]);
    if (
$pos !== false)
    {
      return 
trim(substr($text,0,strpos($text,$filter_data["text"])));
    }
    else
    {
      return 
$text;
    }
  }
  
/*************************************************/
  /* splitAfter                                    */
  /*************************************************/
  
$filter_names["splitAfter"] = "Split After";
  function 
filter_splitAfterConfigure($filter_data)
  {
    print 
"Split Character or String:<br />";
    print 
"<input type='text' size='40' name='text' value='".widget_safe($filter_data["text"])."' />";
    
widget_errorGet("text");
  }
  function 
filter_splitAfterValidate($filter_data)
  {
    if (!
$filter_data["text"])
    {
      
widget_errorSet("text","required field");
    }
  }
  function 
filter_splitAfterExec($filter_data,$text)
  {
    return 
trim(substr($text,strpos($text,$filter_data["text"])));
  }
?>

Submitted by timhammond on Fri, 2006-09-29 09:45

Can you help direct me to where to get a datafeed for my merchants on Commission Junction - I can;t find it on their site anywhere
thanks
Tim

Submitted by support on Fri, 2006-09-29 10:27

Hi Tim,

I'm not familiar with Commission Junction but a number of users here are so hopefully somebody will be able to point you in the right direction.

I am aware that they are subject to a subscription so perhaps you have to signup to them somewhere...

Cheers,
David.

Submitted by wdekreij on Mon, 2007-01-22 08:10

Hi David :-)

The Splitbefore and splitafter work great!

But.. When a field look likes this : a/b/c/d/e (for example), how can I let PT know that I want (for example) the d, and not the rest?

In other words, how can I let the script know at which "/" he must split?

Submitted by support on Mon, 2007-01-22 08:49

Hi,

This would be easier with a new filter that uses PHP's explode() function to split the value up into an array, and then returns the one that you want. Here's the filter code:

  /*************************************************/
  /* explode */
  /*************************************************/
  $filter_names["explode"] = "Explode";
  function filter_explodeConfigure($filter_data)
  {
    print "Explode Character or String:<br />";
    print "<input type='text' size='40' name='text' value='".widget_safe($filter_data["text"])."' />";
    widget_errorGet("text");
    print "<br />";
    print "Return Index: (zero based)<br />";
    print "<input type='text' size='3' name='index' value='".widget_safe($filter_data["index"])."' />";
    widget_errorGet("index");
  }
  function filter_explodeValidate($filter_data)
  {
    if (!$filter_data["text"])
    {
      widget_errorSet("text","required field");
    }
  }
  function filter_explodeExec($filter_data,$text)
  {
    $parts = explode($filter_data["text"],$text);
    $index = intval($filter_data["index"]);
    return trim($parts[$index]);
  }

To use it; based on your example string; enter "/" (without the quotes) as the Explode Character or String, and then enter "3" as the return index. This will return "d" which would be the 3rd element of the zero based array created by the explode() function in the filter.

Hope this helps!
Regards,
David.

Submitted by wdekreij on Mon, 2007-01-22 15:18

Wow, works just great!

The only problem is, that (when a field is "a/b/c/d/e/f") and I want to have the brand as the "b" and the category as the "c" (in other words, category & brand have to be extracted from the same field in the feed), it's not going to work... And it's exactly what I need.

Why isn't it going to work? Because, in the filter screen, the "Category" field is gone when I have registered the same field from the feed to "Category" and "Brand"..

Submitted by support on Mon, 2007-01-22 15:47

Hi,

Aside from the missing option in the drop-down, the problem you've got here is that the filters apply directly to the contents of the record; and so your category filter would prevent the brand filter from having anything to work on...

The solution is to register a blank field as one of the items (category or brand); and then before using the explode filter use a "Text After" filter to copy in the contents of the combined field. For example, if the field is called "DATA" (as per the sample record on the registration step 2) then your text after filter would contain:

%DATA%

That would give you 2 copies of the combined field to work with, and you can then register your explode filters on both the category and brand fields.

If you don't have a blank field to use; you can actually make one blank by registering an unused field (hopefully you will have one available); then using the explode filter with something like "," in the split string and 100 in the index - that will return nothing and wipe out the contents of the field...

Hope this helps,
Cheers,
David.

Submitted by wdekreij on Mon, 2007-01-22 18:10

Damn.. You are my new best friend :-)

Works exactly how it should be!!

PS. For everyone who's reading this and didn't buy this package yet: BUY IT!!

If it's not for the script itself, then you must still buy it because David deserves that money for the GREAT service he offers!

Submitted by jimpoo on Fri, 2007-01-26 03:19

Hi David,
I just download the latest version of PT, it simply remove all the special character inside the multi-level liked categories strings, for example, the datafeed category field like this:

Electronics > Car Electronics > Mobile Video

The above categories strings are simply converted to like this finally:

Electronics Car Electronics Mobile Video

Is this a new bug? I didn't add any filter.

Thank you,
Jimpoo

Submitted by support on Fri, 2007-01-26 06:24

Hi,

The change is probably because the category fields are now normalised during import, so the ">" character is stripped. This is done on line 170 of includes/admin.php in the current distribution:

$record[$admin_importFeed["field_category"]] = tapestry_normalise($record[$admin_importFeed["field_category"]]);

To allow all characters through as per the older version, simply comment out or delete this line. Alternatively, to permit the ">" make the following modification:

$record[$admin_importFeed["field_category"]] = tapestry_normalise($record[$admin_importFeed["field_category"]],">");

You can add other characters to the allow list; but certain characters must be escaped with the "\" character - see the examples in the following thread for more information:

http://www.pricetapestry.com/node/825

Cheers,
David.

Submitted by transparencia on Fri, 2010-10-15 16:19

Imagine I have a category like the one above:

Electronics Car Electronics Mobile Video

What filter could be aplied to remove duplicate words?

Submitted by support on Fri, 2010-10-15 20:14

Hi,

Here's the code to implement a Remove Duplicates filter:

  /*************************************************/
  /* removeDuplicates */
  /*************************************************/
  $filter_names["removeDuplicates"] = "Remove Duplicates";
  function filter_removeDuplicatesConfigure($filter_data)
  {
    print "<p>There are no additional configuration parameters for this filter.</p>";
  }
  function filter_removeDuplicatesValidate($filter_data)
  {
  }
  function filter_removeDuplicatesExec($filter_data,$text)
  {
    $words = explode(" ",$text);
    $existingWords = array();
    $retvals = array();
    foreach($words as $word)
    {
      if (isset($existingWords[$word])) continue;
      $retvals[] = $word;
      $existingWords[$word] = 1;
    }
    return implode(" ",$retvals);
  }

Paste the above code into your includes/filter.php at the end, immediately BEFORE the closing PHP tag, and then you can add a new "Remove Duplicates" filter to the Category field in your feed to make the example value:

Electronics Car Electronics Mobile Video

...become:

Electronics Car Mobile Video

Hope this helps!

Cheers,
David.
--
PriceTapestry.com

Submitted by enjoymarcus on Mon, 2013-03-04 18:26

Hi David,

I've been playing around with the Explode filter a bit recently and I've come up against a large issue.

One of the fields in my feed is back to front, i.e. last name, first name - I have managed to swap this around using a combination of explode (,) and text after filters - however, it doesn't seem 100% full proof.

Additionally, I would like to add this field to the Product Name and again I have figured this out using the explode and text after filters - but, any product with a ',' already in it is being affected heavily.

Do you have any tips as to how to achieve a cleaner solution?

Many thanks,
Marc.

Submitted by support on Mon, 2013-03-04 19:23

Hi Marc,

It sounds like the filter sequence may be the cause of product names containing commas affecting the operation - filters are applied in the order they appear on the Filters page (for per-feed filters).

So it sounds like the filter sequence that you have worked out to swap the Last Name,First Name would be OK as long as those filters are applied before the field is appended or pre-pended to the Product Name using Text After / Text before filters.

If that's not the case, perhaps if you could post example fields where the filter sequence is not working, and a list of each of the filters applied to the feed (indicating their order) and how they are configured, I'll check it out, or should be able to suggest a custom filter / custom import handling code to work it out for you...

Cheers,
David.
--
PriceTapestry.com

Submitted by enjoymarcus on Mon, 2013-03-04 19:53

Hi David,

The field is for the Author and here is the sequence of filters;

Text Before - Short Product Description (AUTHOR) - Input: %AUTHOR%
Explode - Short Product Description (AUTHOR) - Input: ',' and '1'.
Text After - Product Name (NAME) - Input: by %AUTHOR% %AUTHOR%
Explode - Product Name (NAME) - Input: ',' and '1'.
Text Before - Product Name (NAME) - Input: %NAME% by

I know it seems like quite a set of Filters, but it was the only way I could get close to the results; {link saved} - Largely OK, except for this one which is missing the Surname: {link saved}

Additionally, any Product Name's with a comma in them are affected by the explode filter.

Cheers,
Marc.

Submitted by support on Mon, 2013-03-04 21:08

Hi Marc,

This is probably is best handled with a custom filter, "Reverse" - similar to Explode, but rather than specifying a return index; this filter will return the same string but with each item separated by the Explode Character or String in reverse order.

  /*************************************************/
  /* Reverse */
  /*************************************************/
  $filter_names["reverse"] = "Reverse";
  function filter_reverseConfigure($filter_data)
  {
    print "Explode Character or String:<br />";
    print "<input type='text' size='40' name='text' value='".widget_safe($filter_data["text"])."' />";
    widget_errorGet("text");
  }
  function filter_reverseValidate($filter_data)
  {
    if (!$filter_data["text"])
    {
      widget_errorSet("text","required field");
    }
  }
  function filter_reverseExec($filter_data,$text)
  {
    $parts = explode($filter_data["text"],$text);
    foreach($parts as $k => $v)
    {
      $parts[$k] = trim($v);
    }
    return implode($filter_data["text"]." ",array_reverse($parts));
  }

Add the code to the end of your includes/filter.php (just before the closing PHP tag) and with that in place, have a go with the filter sequence:

Reverse - Short Product Description (AUTHOR) - Input: ','
Text After - Product Name (NAME) - Input: by %AUTHOR%

Hope this helps!

Cheers,
David.
--
PriceTapestry.com

Submitted by enjoymarcus on Mon, 2013-03-04 22:35

Thanks David,

This seems like the perfect solution but it doesn't seem to be happening for me;

{link saved}

I've checked and re-checked the filters, but they are correct as far as I can see...

Cheers,
Marc.

Submitted by support on Mon, 2013-03-04 22:48

Hi Marc,

I had assumed from the previous filter sequence that you already had a modification in place to "back fill" the copy of the record used when %FIELD% placeholders are used, but it looks like this may not be the case. Please could you email me your latest includes/admin.php and includes/filter.php and I'll check that all out for you...

Cheers,
David.
--
PriceTapestry.com