Magmi overwriting position of products in category

2.6k Views Asked by At

I'm using Magmi to import products into my Magento store. Categories are created on the fly and products are imported. All is working well.

Except for one thing: each time I run a Magmi import, the position of the product in the Magento category is set to 0. This way I cannot sort my products on position.

I have searched the Magmi wiki and github for someone who has run into the same problem, but didn't find anything.

Anyone familiar with this issue and is there a way to avoid it?

5

There are 5 best solutions below

0
On

Only a comment but since I'm a long-time reader but never setup an account and can't leave a comment directly with no rep. I know this is an old post, but I just found it and used AlexVegas's code above (thank you!). Worked almost fine for me, but in my case I still wanted the categories to fully reset to only what was in my Magmi import but I wanted the positions to remain intact. As-is above, the categories only append to the existing unless you use the category_reset column in your import, and if you do that it also resets the position.

If you're like me and want only the position to remain intact, but allow Magmi to overwrite the categories each time, use Alex's code above but tweak it a little

Where he says to change

if (!isset($item["category_reset"]) || $item["category_reset"] == 1) {...}

to

if (isset($item["category_reset"]) && $item["category_reset"] == 1)
{
    $sql = "DELETE $ccpt.*
    FROM $ccpt
    JOIN $cce ON $cce.entity_id=$ccpt.category_id
    WHERE product_id=?";
    $this->delete($sql, $pid);
    $currentPositions = array();
}

Don't change it. It's that simple. In his code it prevents the category reset unless the column is specified, which is why the if statement gets changed. If the column exists, it also wipes out the currentPositions array that stores the current positions within the categories so those get reset as well.

If you want to append to the categories unless category_reset is in your import, but don't want to overwrite the positioning, use Alex's code as it is above in his answer but leave out

$currentPositions = array();

That way it won't overwrite the array that is storing the positions within the categories

0
On

I wait too long an answer and do it myself, here is a fix:

my fix works other way - category positions clear only if you add $item["category_reset"] == 1; param to product params.

:1280 sting(in current magmi version) or find the public function assignCategories($pid, $item) in magmi_productimportengine.php. ater

$cce = $this->tablename("catalog_category_entity");

$ccpt = $this->tablename("catalog_category_product");

add next code:

  $sql = "SELECT $ccpt.*
            FROM $ccpt
            JOIN $cce ON $cce.entity_id=$ccpt.category_id
            WHERE product_id=?";
  $currentPositions = $this->selectAll($sql,$pid);

then change category reset:

 if (!isset($item["category_reset"]) || $item["category_reset"] == 1)
{...}

to

    if (isset($item["category_reset"]) && $item["category_reset"] == 1)
    {
        $sql = "DELETE $ccpt.*
        FROM $ccpt
        JOIN $cce ON $cce.entity_id=$ccpt.category_id
        WHERE product_id=?";
        $this->delete($sql, $pid);
        $currentPositions = array();
    }

after this change block with positioning

foreach ($catids as $catdef)
        {...}

to:

    // find positive category assignments

    if (is_array($currentPositions) && count($currentPositions)) {
        foreach ($currentPositions as $currentPosition) {
            $catPos[$currentPosition['category_id']] = $currentPosition['position'];
        }
    }

    foreach ($catids as $catdef)
    {
        $a = explode("::", $catdef);
        $catid = $a[0];
        if (count($a) > 1 && $a[1] != 0) {
            $catpos = $a[1];
        }
        else {
            if (isset($catPos[$catid]) && $catPos[$catid] != 0) {
                $catpos = $catPos[$catid];
            }
            else {
                $catpos = "0";
            }
        }
        $rel = getRelative($catid);
        if ($rel == "-")
        {
            $ddata[] = $catid;
        }
        else
        {
            $cdata[$catid] = $catpos;
        }
    }

if you dont import position, your current position will save. If it 0, it stay 0.

for clear actual position - add param to product item:

$item["category_reset"] == 1;

or change string back:

if ($item["category_reset"] == 1)
        { ....}

to:

 if (!isset($item["category_reset"]) || $item["category_reset"] == 1)
{...}
2
On

The Magmi wiki specifically mentions item positioning functionality here See quoted text below. This seems to describe exactly the functionality you are looking for? I have not tested it myself.

Quote:

Item positioning

From magmi 0.7.18 , category_ids column has been enhanced with item positioning. This feature is also supported in category importer from version 0.2+ (since category importer plugin is roughly a category_ids generator)

Sample

store,sku,....,categories
admin,00001,.....,cat name with \/ in the name and positioning::3 

<= here we "escaped" the tree separator with a backslash , the category will be created as "catname with / in the name and positioning"

sku 00001 will be set with position 3 in the category

End quote

0
On
0
On

You can ignore UPDATE position if exist

category creator/importer v0.2.5 at line 1248 replace with

  if (count($inserts) > 0) {
     $sql = "INSERT IGNORE INTO $ccpt (`category_id`,`product_id`,`position`) VALUES ";
     $sql .= implode(",", $inserts);
     // $sql .= " ON DUPLICATE KEY IGNORE";
     $this->insert($sql, $data);
     unset($data);
   }