2014-07-03 16 views
6

Ich bin ein Neuling in Magento. Grundsätzlich möchte ich mehrere Produkte mehreren Kategorien zuordnen. Ich habe this post gefolgt, und ich habe den folgenden Code durchgeführt, die fein arbeitet:Wie Sie Kategorien für Produkte in Magento programmatisch zuweisen

$collection = Mage::getModel('catalog/product')->getCollection();//my coustom collection 
     $categorys_ids = array(1,2,3,4,5);//Array of ids etc 
     if ($categorys_ids != NULL && $collection->getData()!= NULL) 
      { 
       foreach ($collection as $product) 
       { 
         $categories_pd = $product->getCategoryIds();        
         $product->setCategoryIds(array_merge($product->getCategoryIds(),array($categorys_ids))); 
         $product->save(); 
       } 
      } 

Nun, das Hauptproblem ist, dass, wenn ich Kategorie-ID für die Produkte festgelegt assign es viel Zeit in Anspruch nimmt. Ich habe 200 Produkte und das dauert bis zu zwei Minuten, das ist eine Menge Zeit.

Ich frage mich, ob es eine Möglichkeit gibt, dass ich einem Produkt-Array Kategorien zuweisen kann, anstatt Produkte Kategorien oder etwas zuzuteilen, das optimiert werden kann und weniger Zeit benötigt.

Antwort

8

So können Sie einer Kategorie mehrere Produkte zuweisen und sie mit den vorhandenen Produkten zusammenführen.
Das Beispiel ist für eine Kategorie, aber Sie können es in eine Schleife verwandeln, um es für mehr arbeiten zu lassen.

$categoryId = 6; 
$category = Mage::getModel('catalog/category')->setStoreId(Mage_Core_Model_App::ADMIN_STORE_ID)->load($categoryId); 
//get the current products 
$products = $category->getProductsPosition(); 
//now attach the other products. 
$newProductIds = array(1,2,3,4,5); 
foreach ($newProductIds as $id){ 
    $products[$id] = 1;//you can put any other position number instead of 1. 
} 
//attach all the products to the category 
$category->setPostedProducts($products); 
//save the category. 
$category->save(); 

Wenn Sie eine noch schnellere Art und Weise wollen, es zu tun Sie catalog_category_product direkte Einsätze in der Tabelle tun.
Stellen Sie sicher, dass Sie neu indizieren, wenn Sie fertig sind.

+0

dank marius. Ich habe die Idee, :) –

0

Hier ist, wie ich es getan hätte, von neueren PHP-Versionen einiger schnellen Array-Management-Funktionen mit:

<?php 
require_once '../../app/Mage.php'; 
Mage::app(); 
Mage::app()->setCurrentStore(Mage::getModel('core/store')->load(Mage_Core_Model_App::ADMIN_STORE_ID)); 
$storeCode = Mage::app()->getStore()->getStoreId(); 

function addProductsToCategoryId($mergeProductIds, $categoryId, $storeCode) { 
    // load the $category by $categoryId 
    $category = Mage::getModel('catalog/category')->setStoreId($storeCode)->load($categoryId); 
    // build a flipped array of two merged arrays (1) array keys from flipped $mergeProductIds, (2) array keys from product_id keyed array in $category 
    $categoryProductIds = array_flip(array_merge(array_keys(array_flip($mergeProductIds)),array_keys($category->getProductsPosition()))); 
    // combine array_keys from resulting merge with a matched index array filled with '0' 
    // THIS resets position of product within category, change this logic if desired 
    $categoryProductIds = array_combine(array_keys($categoryProductIds), array_fill(0, count($categoryProductIds), '0')); 

    $category->setPostedProducts($categoryProductIds); 
    $category->save(); 

    // optional 
    // return $categoryProductIds; 
} 

// optional array of category IDs to test against for nin (not in) or in a find_in_set array test 
// in the optional example line below, nin (not in) is used 
$categoryIds = array(5,8,9,10,11,12,45,46); 

$collectionIds = Mage::getModel('catalog/product')->getCollection() 
    ->setStoreId($storeCode) 
    // optional inclusion of join for category_id 
    ->joinField('category_id', 'catalog/category_product', 'category_id', 'product_id = entity_id', null, 'left') 
    // optional logic to only gather ids that are, or are not in a given categoryIds array, nin (not in) is shown in example 
    // ->addAttributeToFilter('category_id', array('nin' => array('finset' => $categoryIds))) 
    // optional line to test whether product is associated to ANY category 
    ->addAttributeToFilter('category_id', array('null' => true)) 
    // example qualifiers to affect gathered IDs 
    ->addAttributeToFilter('sku', array('like' => 'M-H%')) 
    ->addAttributeToFilter('sku', array('nlike' => '%E')) 
    ->addAttributeToFilter('sku', array('nlike' => '%E#')) 
    ->addAttributeToFilter('sku', array('nlike' => '%Euro')) 
    ->addAttributeToFilter('sku', array('nlike' => '%Euro#')) 
    ->getAllIds() 
    ; 

// if using a return value, you can set the results of this to a variable 
// to perform further operations against the resulting data 
addProductsToCategoryId($collectionIds, 8, $storeCode); 

Bitte beachten Sie, dass standardmäßig meine Methode, bleibt nicht alle Position für die Produkte innerhalb von Ihnen individuell festgelegt hatten. IT setzt alle Positionen auf den Standardwert '0' zurück.

Funktioniert wunderbar. Erfordert danach eine Neuindizierung, schnelle Massenaddition. Der Code ist ein wenig komplex, daher machte es mir in diesem Fall mehr Sinn, den Code in direkten Kontextkommentaren zu erklären.

Ich habe eine Menge optionaler Extras hier aufgenommen, aber sie sind alle als solche gekennzeichnet und vollständig erklärt.

0

Der folgende Code für mich gearbeitet:

include '../../app/Mage.php'; 
Mage::app('admin'); 
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID); 

$product_id = Mage::getModel("catalog/product")->getIdBySku($sku); 
$product = Mage::getModel('catalog/product')->load($product_id); 
$product->setCategoryIds($category_id); 
$product->save();