You are here:  » Is it possible to use Regular Expressions on the Search & Replace Filter?


Is it possible to use Regular Expressions on the Search & Replace Filter?

Submitted by finc3 on Sat, 2011-12-17 16:42 in

Hi,

is it possible to use regular expressions on the Search & Replace filter?

I'm currently trying to extract information from the general product name of a given feed and write the result into a separate data field.

Imagine the Product name field would sound like "Call of Duty 3 Xbox Game" but the platform would not be given in the feed.

With my current understanding I would do the following thing (maybe not the best approach?)

1) I would copy the content of the product name field into the field "platform"
2) I would run a search & replace filter with a regular expression on the platform field searching for Xbox
3) If it comes up with a game title that includes Xbox, it would replace the whole title with the platform information

I'm not sure if that is really the best approach - so my question is: what is the easiest way to extract certain data for separate fields from text fields and properly write them to other indexed fields in the database?

P.S: This assumens that a separate field "platform is already added to the database, based on the forum discussions on indexed fields

Submitted by support on Sat, 2011-12-17 17:57

Hi,

This can be quite easily achieved using some code added to the import record handler function in includes/admin.php

First, add the new field "platform" as per the instructions.

With that in place; you can of course register a field as the platform but for feeds that don't contain this, to derive the field from the product name, look for the following code around line 342:

    if (!$importRecord["merchant"]) return;

...and REPLACE with:

    $platforms = array();
    $platforms["XBox 360"] = array("XBox","X-Box");
    $platforms["PS3"] = array("PS3","Playstation 3","Playstation3");
    if (!$importRecord["platform"])
    {
      foreach($platforms as $platform => $keywords)
      {
        foreach($keywords as $keyword)
        {
          if (stripos($importRecord["name"],$keyword)!==FALSE)
          {
            $importRecord["name"] = $platform;
            break;
          }
        }
        if ($importRecord["name"]) break;
      }
    }
    if (!$importRecord["merchant"]) return;

That should do the trick - simply add to the $platforms array with additional platforms and search keywords for each one as required...

Cheers,
David.
--
PriceTapestry.com

Submitted by enjoymarcus on Tue, 2012-07-17 10:46

Hi David - me again !

I've just tried the above trick but changing using operating systems as the platform rather than consoles. However, I'm not having any luck.

I have an index field named 'platform' and am selecting the product title when registering the feed - however, nothing seems to be appearing on site.

Also, on another note - would it be possible to set a default value if none exist? Here is the code in product.php;

<?php if ($mainProduct["platform"]): ?>
          <br><b>Platform: </b><?php print $mainProduct["platform"]; ?>
          <?php endif; ?>

and here is the code I modified from above;

    $platforms = array();
    $platforms["Windows"] = array("Windows","Win");
    $platforms["Mac OSX"] = array("Mac","Macintosh");
    $platforms["Linux"] = array("Linux");
    if (!$importRecord["platform"])
    {
      foreach($platforms as $platform => $keywords)
      {
        foreach($keywords as $keyword)
        {
          if (stripos($importRecord["name"],$keyword)!==FALSE)
          {
            $importRecord["name"] = $platform;
            break;
          }
        }
        if ($importRecord["name"]) break;
      }
    }
    if (!$importRecord["merchant"]) return;

Thanks in advance.

Marc.

Submitted by support on Tue, 2012-07-17 11:02

Hi Marc,

There was actualy a mistake in the original code above; it's setting $importRecord["name"] rather than $importRecord["platform"]. Corrected version as below; together with setting a default value if not set (second to last line)...

    $platforms = array();
    $platforms["Windows"] = array("Windows","Win");
    $platforms["Mac OSX"] = array("Mac","Macintosh");
    $platforms["Linux"] = array("Linux");
    if (!$importRecord["platform"])
    {
      foreach($platforms as $platform => $keywords)
      {
        foreach($keywords as $keyword)
        {
          if (stripos($importRecord["name"],$keyword)!==FALSE)
          {
            $importRecord["platform"] = $platform;
            break;
          }
        }
        if ($importRecord["platform"]) break;
      }
    }
    if (!$importRecord["platform"]) $importRecord["platform"]="Default Value";
    if (!$importRecord["merchant"]) return;

Alternatively, if you didn't want to default the value in the database (for example if using filtes) then instead, a default value can be shown in the html as follows:

          <?php if ($mainProduct["platform"]): ?>
          <br><b>Platform: </b><?php print $mainProduct["platform"]; ?>
          <?php else: ?>
          <br>Default HTML Here
          <?php endif; ?>

Cheers,
David.
--
PriceTapestry.com

Submitted by enjoymarcus on Tue, 2012-07-17 15:00

Thanks David - that worked perfectly.

I've also tried doing the same when the platform is in the description, but it doesn't seem to work, do I need to amend the code (apart from the index field)?

Also, if I wanted to do this for another keyword, could I just use the same code? or will this conflict?

Thanks,
Marc.

Submitted by support on Tue, 2012-07-17 15:05

Hi Marc,

To scan description as well as name, in place of:

if (stripos($importRecord["name"],$keyword)!==FALSE)

...use:

if (stripos($importRecord["name"]." ".$importRecord["description"],$keyword)!==FALSE)

It's fine to copy the code for other fields, there won't be any conflicts, simply change the array name for code clarity if you wish (although not necessary), and replace the 2 instances of $importRecord["platform"] with $importRecord["otherfield"] that's all...

Cheers,
David.
--
PriceTapestry.com

Submitted by enjoymarcus on Tue, 2012-07-17 15:56

Hi David, the description scanning worked perfectly.

However, I'm struggling with the other field. My code is below, however there seemed to be more than 2 instances of $importRecord["platform"] - so I replaced all - apologies if I missed something here;

$platforms = array();
    $platforms["Download"] = array("Download");
    $platforms["Boxed"] = array("Boxed","Physical","physical","box");
    if (!$importRecord["downloadboxed"])
    {
      foreach($platforms as $platform => $keywords)
      {
        foreach($keywords as $keyword)
        {
          if (stripos($importRecord["name"],$keyword)!==FALSE)
          {
            $importRecord["downloadboxed"] = $platform;
            break;
          }
        }
        if ($importRecord["downloadboxed"]) break;
      }
    }
    if (!$importRecord["downloadboxed"]) $importRecord["downloadboxed"]="Download";

Submitted by support on Tue, 2012-07-17 16:17

Hi Marc,

At first glance that looks fine - did you mean to include scanning the description also? For clarity, rather than using $platform in the code; here's a generic version which scans both name and description:

    $setField = "downloadboxed";
    $setIfContains = array();
    $setIfContains["Download"] = array("Download");
    $setIfContains["Boxed"] = array("Boxed","Physical","physical","box");
    $setFieldDefault = "Default Value";
    if (!$importRecord[$setField])
    {
      foreach($setIfContains as $k => $keywords)
      {
        foreach($keywords as $keyword)
        {
          if (stripos($importRecord["name"]." ".$importRecord["description"],$keyword)!==FALSE)
          {
            $importRecord[$setField] = $k;
            break;
          }
        }
        if ($importRecord[$setField]) break;
      }
    }
    if (!$importRecord[$setField]) $importRecord[$setField]=$setFieldDefault;

For each field, edit / modify as required the initial section as required:

    $setField = "downloadboxed";
    $setIfContains = array();
    $setIfContains["Download"] = array("Download");
    $setIfContains["Boxed"] = array("Boxed","Physical","physical","box");
    $setFieldDefault = "Default Value";

So in this case, downloadboxed is the custom field to process; the $setIfContains array is the array of values to set if $setField contains any of the keyword(s) in the array; and $setFielDefault is the default value if no match is found.

Hope this helps!

Cheers,
David.
--
PriceTapestry.com

Submitted by enjoymarcus on Tue, 2012-07-17 21:34

Hi David, thanks for helping with this.

I tried the above code, and at first got a syntax error - I think there was an issue with this line "if (stripos($importRecord["name"]." ".stripos($importRecord["description"],$keyword)!==FALSE)" which I just substituted with the previous version and the error disappeared.

However, the above code just doesn't seem to be working for me and I think it's because I have mapped the products to a specific name (which removes the relevant keywords I am looking for) however, the products that have been mapped do contain said keywords.

Any ideas for a work around?

Many thanks for your help.
Marc.

Submitted by support on Wed, 2012-07-18 08:49

Hi Marc,

Sure - the pre-mapped name is loaded into the $importRecord["original_name"] before mapping is applied, so you can search this field as well as name and description. On the line that you identified as containing the syntax error (corrected above) REPLACE with:

if (stripos($importRecord["name"]." ".$importRecord["original_name"]." ".$importRecord["description"],$keyword)!==FALSE)

Cheers,
David.
--
PriceTapestry.com

Submitted by enjoymarcus on Wed, 2012-07-18 14:06

Fantastic - thanks David.