You are here:  » Map a product to a different category


Map a product to a different category

Submitted by alchemist on Wed, 2011-06-01 14:52 in

Just wondered if there is a way to map a product to a different category than given in the feed? I have a number of products that are ending up in the wrong category because they are wrong in the feed.

Submitted by support on Wed, 2011-06-01 14:59

Hi,

[updated for 15/09A]

Sure - there is an easy mod to Category Mapping to make exact match alternatives apply to the product name also. In includes/admin,php look for this section beginning at line 383:

    if (isset($admin_importCategoryMappings["=".$importRecord["category"]]))
    {
      $importRecord["category"] = $admin_importCategoryMappings["=".$importRecord["category"]];
    }

...and REPLACE with:

    if (isset($admin_importCategoryMappings["=".$importRecord["category"]]))
    {
      $importRecord["category"] = $admin_importCategoryMappings["=".$importRecord["category"]];
    }
    elseif (isset($admin_importCategoryMappings["=".$importRecord["name"]]))
    {
      $importRecord["category"] = $admin_importCategoryMappings["=".$importRecord["name"]];
    }

Then from your /admin/ page, go to Category Mapping and create a new mapping for the category name that you want the product(s) to be in, and in the alternatives box on the configuration page for the mapping enter

=Product Name 1
=Product Name 2
etc.

To find the exact names to use as they are imported I find the easiest way is to open Product Finder (admin menu) in a new window and use that to locate the products, and then copy and paste the names into the Category Mapping page...

Hope this helps!

Cheers,
David.
--
PriceTapestry.com

Submitted by alchemist on Wed, 2011-06-01 15:07

OMG David your amazing, that works a treat. Going to make my site a lot neater especially given it is a niche site.

Thanks so much, gold star support as usual.

Submitted by fstore on Fri, 2011-07-22 11:18

Hi David

I tried this, I noticed It does map the product into right category but at the same time product still remain in the wrong category.
is that the expected behavior?

Submitted by support on Fri, 2011-07-22 11:30

Hello Hassan,

That would indicate that not all feeds (e.g. merchants) carrying that product have been re-imported since applying the changes; that should be all it is...

Cheers,
David.
--
PriceTapestry.com

Submitted by Bakalinge on Wed, 2013-03-13 13:04

Hi David,

As you know, I'm using a lot this trick to map products in different categories. It was working fine until now, but it seems that I can't map more than a few hundreds products (around 800 I think). Over this limit, the Category Mapping function doesn't save alternatives. Do you think it's due to the server memory limit (16 GB) ?

Thanks
Bak

Submitted by support on Wed, 2013-03-13 13:35

Hello Bak,

Rather than server memory, it is more likely to be a PHP memory limit being reached. First of all, try adding the following line of PHP code to the end of your config.php - on the line before the closing PHP tag:

  ini_set('memory_limit', '128M');

(a typical default in php.ini is 16M)

If that doesn't help, let me know and I'll investigate further with you...

Cheers,
David.
--
PriceTapestry.com

Submitted by Bakalinge on Wed, 2013-03-13 13:52

Thanks David,

Unfortunately, the problem remains the same. Did a test with 1000 products, the treatment is taking a long time, but I don't get any error message or whatever (Under Chrome, you can even see in the bottom bar the uploading going from 0 to 100% without any problem). Then, coming back to the category mapping, the alternatives list is empty....

Bak

Submitted by support on Wed, 2013-03-13 14:24

Hello Bak,

Please could you run a Database Tool backup of Category Mapping only, save the backup file to your local computer and if possible, if you could zip and then email me the file, I'll try and recreate the problem on my test server for you... (and if you could also let me know which your mappings - Master Category Name - has the most Alternatives...

Thanks,
David.
--
PriceTapestry.com

Submitted by Bakalinge on Thu, 2013-05-23 14:40

Hi David,

Using the above idea to map products straight into categories, do you think it's possible to use wild cards in product names ?
I have a number of products with almost the same name, many products in & out each week and it would be easier to :

= Productname *

than

= Productname ref ABC
= Productname ref EDC
= Productname ref RTY
....

Thanks !

Bak

Submitted by support on Thu, 2013-05-23 14:45

Hello Bak,

Sure - the above only covers exact matching but keyword matching can also be applied to product name. Your includes/admin.php has probably been modified somewhat but if you look for the following code around line 252:

  if (strpos($importRecord["category"],$word) !== FALSE) $found++;

...and REPLACE with:

  if (
     (strpos($importRecord["category"],$word) !== FALSE)
     ||
     (strpos($importRecord["name"],$word) !== FALSE)
     )
     $found++;

...then keyword matching (e.g. no "=" sign at the beginning of an Alternative entry) will apply to product name field also...

Hope this helps!

Cheers,
David.
--
PriceTapestry.com

Submitted by Bakalinge on Thu, 2013-05-23 15:43

Hi David,

Thank you, it's working very well...I have a last question : is this mod compatible with node 4592 ? In other words, can I map products using both wild cards and negative keywords ?

Thanks

Bak

Submitted by support on Thu, 2013-05-23 16:05

Hi Bak,

Very similar (almost identical) code, but Product Mapping and Category Mapping are applied separately, so it would just be a case of making the same mod to category mapping, combined with the above.

In your modified includes/admin.php, you should now have, around where the above modification was made, the following code:

      foreach($admin_importCategoryMappings as $k => $v)
      {
        if (substr($k,0,1) !== "=")
        {
          $found = 0;
          $words = explode(" ",$k);
          foreach($words as $word)
          {
            if ($word)
            {
              if (
                 (strpos($importRecord["category"],$word) !== FALSE)
                 ||
                 (strpos($importRecord["name"],$word) !== FALSE)
                 )
                 $found++;
            }
          }
          if ($found == count($words))
          {
            $importRecord["category"] = $v;
            break;
          }
        }
      }

...REPLACE with:

      foreach($admin_importCategoryMappings as $k => $v)
      {
        if (substr($k,0,1) !== "=")
        {
          $found = 0;
          $words = explode(" ",$k);
          foreach($words as $word)
          {
            if (substr($word,0,1)=="!")
            {
              if (
                 (strpos($importRecord["category"],substr($word,1)) !== FALSE)
                 ||
                 (strpos($importRecord["name"],substr($word,1)) !== FALSE)
                 )
              {
                $found = 0;
                break;
              }
              else
              {
                unset($words[$k]);
              }
            }
            elseif ($word)
            {
              if (
                 (strpos($importRecord["category"],$word) !== FALSE)
                 ||
                 (strpos($importRecord["name"],$word) !== FALSE)
                 )
                 $found++;
            }
          }
          if ($found == count($words))
          {
            $importRecord["category"] = $v;
            break;
          }
        }
      }

I've tried to work back through all the above to derive your current code but if that hasn't worked out (!!) please email me your latest includes/admin.php and I merge the changes for you..

Cheers,
David.
--
PriceTapestry.com

Submitted by support on Sat, 2013-09-07 08:27

Hi everyone,

Just combining the above exact match and keyword match Category Mapping modifications so that as well as checking the Category Field the Product Name field is also considered, for 13/03A:

Look for the Category Mapping code which begins at line 235 of includes/admin.php:

    /* apply category mappings */
    if (isset($admin_importCategoryMappings["=".$importRecord["category"]]))
    {
      $importRecord["category"] = $admin_importCategoryMappings["=".$importRecord["category"]];
    }
    else
    {
      foreach($admin_importCategoryMappings as $k => $v)
      {
        if (substr($k,0,1) !== "=")
        {
          $found = 0;
          $words = explode(" ",$k);
          foreach($words as $word)
          {
            if ($word)
            {
              if (strpos($importRecord["category"],$word) !== FALSE) $found++;
            }
          }
          if ($found == count($words))
          {
            $importRecord["category"] = $v;
            break;
          }
        }
      }
    }

...and REPLACE with:

    /* apply category mappings */
    if (isset($admin_importCategoryMappings["=".$importRecord["category"]]))
    {
      $importRecord["category"] = $admin_importCategoryMappings["=".$importRecord["category"]];
    }
    elseif(isset($admin_importCategoryMappings["=".$importRecord["name"]]))
    {
      $importRecord["category"] = $admin_importCategoryMappings["=".$importRecord["name"]];
    }
    else
    {
      foreach($admin_importCategoryMappings as $k => $v)
      {
        if (substr($k,0,1) !== "=")
        {
          $found = 0;
          $words = explode(" ",$k);
          foreach($words as $word)
          {
            if ($word)
            {
                if (
                   (strpos($importRecord["category"],$word) !== FALSE)
                   ||
                   (strpos($importRecord["name"],$word) !== FALSE)
                   )
                $found++;
            }
          }
          if ($found == count($words))
          {
            $importRecord["category"] = $v;
            break;
          }
        }
      }
    }

With this in place, let's say you have a product with name "Blue Widget", and you want this to be imported with category "Widgets", create a new Category Mapping with the required category name e.g. "Widgets", and then in the Alternatives box on the configuration page for the new mapping, you can either use:

=Blue Widget

...as an exact match against the product "Blue Widget", or more generically, just:

Widget

...as a keyword match, so any product with the keyword "Widget" in the name will be imported with category "Widgets".

Cheers,
David.
--
PriceTapestry.com

Submitted by falmeida on Thu, 2013-12-05 15:08

is it possible to have a "brand Mapping" that works exactly like category mapping but for brands

because most of the the products on my website comes from crawlers and they dont have any field data for brand so i need to set it thru mapping

Submitted by support on Thu, 2013-12-05 15:35

Hello falmeida and welcome to the forum!

Since there should be no overlap, it's straight forward to apply Category Mapping to brands also, and if you don't have a brand field to work with it sounds like you would want to scan the product name (and also the description?) for the brand name.

To do this, edit includes/admin.php and look for the following comment at line 235:

    /* apply category mappings */

...and REPLACE with:

    if (isset($admin_importCategoryMappings["=".$importRecord["brand"]]))
    {
      $importRecord["brand"] = $admin_importCategoryMappings["=".$importRecord["brand"]];
    }
    elseif (isset($admin_importCategoryMappings["=".$importRecord["name"]]))
    {
      $importRecord["brand"] = $admin_importCategoryMappings["=".$importRecord["name"]];
    }
    else
    {
      foreach($admin_importCategoryMappings as $k => $v)
      {
        if (substr($k,0,1) !== "=")
        {
          $found = 0;
          $words = explode(" ",$k);
          foreach($words as $word)
          {
            if ($word)
            {
              if (
                 (strpos($importRecord["brand"],$word) !== FALSE)
                 ||
                 (strpos($importRecord["name"],$word) !== FALSE)
                 ||
                 (strpos($importRecord["description"],$word) !== FALSE)
                 )
                 $found++;
            }
          }
          if ($found == count($words))
          {
            $importRecord["brand"] = $v;
            break;
          }
        }
      }
    }
    /* apply category mappings */

With this in place, you can create a new Category Mapping for "Nike" and then in the Alternatives box on the configuration page for the mapping, simply enter

Nike

...and then any product containing "Nike" in the product name or description will be assigned to the brand "Nike".

The above mod also supportes exact match product name alternatives, so if you have a product on your site that you know is Nike but doesn't trigger matching by keyword enter the product name as an exact match alternative e.g.

=Running Shoes 1234

If you're not sure about the code modifications of course just let me know and I'll forward the modifications for you.

Cheers,
David.
--
PriceTapestry.com

Submitted by falmeida on Fri, 2013-12-06 00:24

Hi david

that didnt work has i wanted since now i have the same thing on brand and category.

if i change:
categories.php
categories_configure.php
categories_delete.php
categories_helper.php

to
brands.php
brands_configure.php
brands_delete.php
brands_helper.php

and replace in all lines of the php files from category to brand and add to the admin menu do you think it will work or is there more files that i need to change

my idea is to have an exact admin menu for brands mapping like we have now for category mapping

Submitted by support on Fri, 2013-12-06 09:57

Hello falmeida,

Sure - in fact, I have very close to a brand mapping utility "ready to go" - I just need to port it to 13/03A which I will do this morning and email you the patch shortly...

Cheers,
David.
--
PriceTapestry.com

Submitted by falmeida on Fri, 2013-12-06 11:02

thank you David

not only a great a script but also an amazing support

Submitted by Bakalinge on Fri, 2016-11-25 12:23

Hi David,

Is this mod compatible with 15/09A ?

Thank you

Submitted by support on Fri, 2016-11-25 12:32

Hi,

Sure - I've updated the line numbers in the first reply above.

Note that Product Mapping now has the Custom Category field which could be used to obtain the same result however that would require a Product Mapping entry per-product; this method will let you create a Category Mapping entry and then map any number of products into it within a single mapping.

Cheers,
David.
--
PriceTapestry.com

Submitted by Bakalinge on Fri, 2016-11-25 13:33

Thanks David !