2009-05-22 7 views
10

У меня есть клиентская база данных с большим ассортиментом товаров, которые загружаются в Magento как простые продукты.Magento API: Назначение существующих ранее продуктов для настраиваемых продуктов

Теперь мне нужно сгруппировать их и назначить им настраиваемые продукты с их размером и цветом, являющимися их настраиваемыми атрибутами.

API Magento имеет класс Product_Link с многообещающим перспективным методом: catalog-product-link.assign (link), но я не могу за всю жизнь выяснить, какие аргументы мне нужно, чтобы он работал с настраиваемых продуктов, при условии, что это означает, что назначение предназначено для использования.

+14

Документация Magento - это мусор, не так ли. – Dan

+0

О, я тебя слышу! Я получаю от них спам время от времени, чтобы фактически купить пользовательскую документацию. Пфф! – keith

+0

Да, я получил свое «предложение», через Twitter. Фактически, я уже купил официальное руководство пользователя, которое не подходит разработчику. Также купил книгу php | architect, которая хорошо читается, но должна быть в 10 раз толще. –

ответ

5

Ну, здесь заметки помогли мне добиться этого. Поэтому я решил поделиться с вами кодом, чтобы добавить простой продукт к существующему настраиваемому продукту.

Этот код предполагает, что простой продукт является допустимым для добавления, я не уверен, что произойдет, если это не так.

private function _attachProductToConfigurable($_childProduct, $_configurableProduct) { 
    $loader = Mage::getResourceModel('catalog/product_type_configurable')->load($_configurableProduct); 

    $ids = $_configurableProduct->getTypeInstance()->getUsedProductIds(); 
    $newids = array(); 
    foreach ($ids as $id) { 
     $newids[$id] = 1; 
    } 

    $newids[$_childProduct->getId()] = 1; 

    $loader->saveProducts($_configurableProduct->getId(), array_keys($newids));     
} 
+0

Я пытаюсь сделать это из сценария командной строки, и я не могу здесь: $ loader = Mage :: getResourceModel ('catalog/product_type_configurable') -> load ($ _configurableProduct); (первая строка) Любые идеи? В настоящее время я расследую его и сообщаю в случае результата. –

+0

Я обновил код от Scimon, чтобы снова работать в последних версиях magento: [см. Ниже] (http://stackoverflow.com/a/14461333/219467) – aeno

1

Я это неосознанное предположение, но я думаю, что ваш запрос не может быть выполнен с использованием существующего API. Вам нужно будет написать свой собственный или просто получить непосредственно в БД.

+1

С помощью схемы EAV db они используют «просто», когда напрямую обращаются к БД. Боль!!! –

2

Я работаю над этим прямо сейчас.

До сих пор я нашел эти вещи полезны в качестве ссылок:

Я отправлю мой код до сих пор, и, надеюсь, обновить как только он будет работать.

// Set 'item_size' as the super attribute # choose your own attribute! 
// this is the 'choose-able' field that differenciates products 
$super_attributes=array(Mage::getModel('eav/entity_attribute') 
    ->loadByCode('catalog_product','item_size') 
    ->getData('attribute_id') 
); 
$product_collection=Mage::getModel('catalog/product')->getCollection(); 

// Fetch configurable orders 
$product_collection->addFieldToFilter('type_id',Array('eq'=>"configurable")); 
#$product_collection->addFieldToFilter('sku',Array('eq'=>"ASMCL000002")); 

$product_collection->addAttributeToSelect('*'); 

$count=0; 
foreach($product_collection as $product) { 
    $sku = $product->getSku(); 
    echo "SKU: $sku\n"; 

    $simple_children_collection = Mage::getModel('catalog/product')->getCollection(); 
    $simple_children_collection->addAttributeToSelect('*'); 
    $simple_children_collection->addFieldToFilter('sku',Array('like'=>$sku . "-%")); 
    echo "children: "; 
    foreach($simple_children_collection as $child) { 
     $child_sku = $child->getSku(); 
     echo "$child_sku "; 
     #visiblity should be 'nowhere' 
    } 
    echo "\n"; 

if (!$product->getTypeInstance()->getUsedProductAttributeIds()) { 
    # This is a new product without the Configurable Attribue Ids set 
    $product->getTypeInstance() 
    ->setUsedProductAttributeIds($super_attributes); 

    //$product->setConfigurableAttributesData(array($_attributeData)); 
    $product->setCanSaveConfigurableAttributes(true); # Not sure if this is needed. 

    $product->setConfigurableProductsData(''); # Use this to add child products. 

} 


    $count++; 

    try { 
     $product->save(); 
     $productId = $product->getId(); 
     echo $product->getId() . ", $sku updated\n"; 
    } 
    catch (Exception $e){ 
     echo "$sku not added\n"; 
     echo "exception:$e"; 
    } 

} 
echo "\nCount is $count\n"; 

Хорошо, это использует «item_size» как атрибут, который отличает «простые» продукты. Кроме того, это предполагает, что «настраиваемый» родительский SKU является корнем дочернего SKU. Например, ABC001 является родительским, а ABC001-SMALL и ABC001-LARGE - это простые дети.

Надежды, которые помогают кому-то.

+0

Я не знаю, продолжаете ли вы работать над этим, но я думаю, что я его взломал. – Scimon

1

Вот хак-й способ, которым я это сделал прямо с PHP. Существует три связанные таблицы. Я использовал цвет и размер в качестве моих атрибутов. Мои родительские продукты (настраиваемые) на самом деле не существуют в моем каталоге. Они по сути являются модельным уровнем, а затем продукты являются уровнем SKU. Так что «родительское производство%» работает для детей.

$query1 = "SELECT * FROM mage_catalog_product_entity WHERE type_id= 'configurable'"; 
    //Find the parent id 
    $statusMessage = "Ok, found a product with a confgurable attribute"; 
    $result1 = $this->runQuery($query1, "query1", $statusMessage); 
    while ($row1 = mysql_fetch_assoc($result1)) { //entering the first loop where products are configurable 
     $this->parentId = $row1['entity_id']; 
     $this->parentSku = $row1['sku']; 

     echo "The SKU was $this->parentSku" . "<br />"; 

    //insert these into the link table for association 
    $query2 = "SELECT * FROM mage_catalog_product_entity WHERE type_id= 'simple' AND sku LIKE '" . $this->parentSku . "%';"; 
    // find the child ids that belong to the parent 
    $statusMessage = "Found some children for $this->parentSku"; 
    $result2 = $this->runQuery($query2, "query2", $statusMessage); 
    while ($row2 = mysql_fetch_assoc($result2)) {//entering the second loop where SKU is like model sku 
     $this->childId = $row2['entity_id']; 
     $this->childSku = $row2['sku']; 

     echo "Now we're working with a child SKU $this->childSku" . "<br />"; 

     //"REPLACE INTO catalog_product_super_attribute SET product_id='".$product->entity_id."', attribute_id='".$attribute->attribute_id."', position='".$position."'"; 
     $query3 = "REPLACE INTO mage_catalog_product_super_attribute (product_id, attribute_id, position) VALUES ('" . $this->childId . "', '76', '0');"; 
     $message3 = "Inserted attribute for color for ID $this->childId SKU $this->childSku"; 
     $result3 = $this->runQuery($query3, "query3", $message3); 

     $query4 = "REPLACE INTO mage_catalog_product_super_attribute_label (product_super_attribute_id, store_id, use_default, value) VALUES (LAST_REPLACE_ID(), '0', '0', 'Color');"; 
     $message4 = "Inserted attribute for Color SKU $this->childSku ID was $this->db->insert_id"; 
     $result4 = $this->runQuery($query4, "query4", $message4); 

     $query5 = "REPLACE INTO mage_catalog_product_super_attribute (product_id, attribute_id, position) VALUES ('" . $this->childId . "', '529', '0');"; 
     $message5 = "Inserted attribute for Product Size SKU $this->childSku"; 
     $result5= $this->runQuery($query5, "query5", $message5); 


     $query6 = "REPLACE INTO mage_catalog_product_super_attribute_label (product_super_attribute_id, store_id, use_default, value) VALUES (LAST_REPLACE_ID(), '0', '0', 'Size');"; 
     $message6 = "Inserted attribute for Size SKU $this->childSku ID was $this->db->insert_id"; 
     $result6 = $this->runQuery($query6, "query6", $message6); 

     $query7 = "REPLACE INTO mage_catalog_product_super_link (product_id, parent_id) VALUES ('" . $this->childId . "', '" . $this->parentId . "');"; 
     $message7 = "Inserted $this->childId and $this->parentId into the link table"; 
     $result7 = $this->runQuery($query7, "query7", $message7); 

     $query8 = "REPLACE INTO mage_catalog_product_relation (parent_id, child_id) VALUES ('" . $this->parentId . "', '" . $this->childId . "');"; 
     $message8 = "Inserted $this->childId and $this->parentId into the link table"; 
     $result8 = $this->runQuery($query8, "query8", $message8); 

     } //end while row 2 the child ID 

      } //end while row 1 the parent id 
1

Удивительно, но это работает, если все ваши простые продукты разделяют ту же цену:

 $childProducts = $configurable->getTypeInstance(true)->getUsedProductIds($configurable); 

     // Don't add this product if it's already there 
     if(!in_array($child->getId(), $childProducts)) {  
      $childProducts[] = $child->getId(); 
     } 


     $existingIds = $configurable->getTypeInstance(true)->getUsedProductAttributeIds($configurable); 
     $newAttributes = array(); 

     foreach($configurable->getTypeInstance(true)->getSetAttributes($configurable) as $attribute) { 

     if(!in_array($attribute->getId(), $existingIds) && $configurable->getTypeInstance(true)->canUseAttribute($attribute) 
      && $child->getAttributeText($attribute->getAttributeCode())) { 

      // Init configurable attribute 
      $configurableAtt = Mage::getModel('catalog/product_type_configurable_attribute') 
       ->setProductAttribute($attribute); 

      // Add new attribute to array 
      $newAttributes[] = array(
       'id'    => $configurableAtt->getId(), 
       'label'   => $configurableAtt->getLabel(), 
       'position'  => $attribute->getPosition(), 
       'values'   => $configurableAtt->getPrices() ? $configurable->getPrices() : array(), 
       'attribute_id' => $attribute->getId(), 
       'attribute_code' => $attribute->getAttributeCode(), 
       'frontend_label' => $attribute->getFrontend()->getLabel(), 
      ); 
     } 
    } 

    if(!empty($newAttributes)) { 

     $configurable->setCanSaveConfigurableAttributes(true); 
     $configurable->setConfigurableAttributesData($newAttributes); 
    } 
     $configurable->setConfigurableProductsData(array_flip($childProducts)); 
     $configurable->save(); 
3

код из принятого ответа по Scimon больше не работает в последних версиях Magento (по крайней мере, в 1.7). Но, к счастью, вам нужно всего лишь небольшое исправление, чтобы получить его снова работает:

private function _attachProductToConfigurable($_childProduct, $_configurableProduct) { 
    $loader = Mage::getResourceModel('catalog/product_type_configurable')->load($_configurableProduct, $_configurableProduct->getId()); 

    $ids = $_configurableProduct->getTypeInstance()->getUsedProductIds(); 
    $newids = array(); 
    foreach ($ids as $id) { 
     $newids[$id] = 1; 
    } 

    $newids[$_childProduct->getId()] = 1; 

    //$loader->saveProducts($_configurableProduct->getid(), array_keys($newids));     
    $loader->saveProducts($_configurableProduct, array_keys($newids));     
} 
+0

У меня был исключенный ответ? Это было давно, я не занимался разработкой Magento в течение года или около того, поэтому идите с этим. – Scimon

+0

Это, вероятно, должно было быть редактирование принятого ответа ИМХО. –

+0

@Joseph: У меня не было достаточной репутации, чтобы сделать это во время написания, поэтому я опубликовал новый ответ. – aeno

0

@ решение aeno не работал для меня, так что я уточнена его немного.Это было протестировано с использованием продукта, созданного методом Mage::getModel('catalog/product')->load().

private function _attachProductToConfigurable($childProduct, $configurableProduct) 
{ 
    $childIds = $configurableProduct->getTypeInstance()->getUsedProductIds(); 
    $childIds[] = $childProduct->getId(); 
    $childIds = array_unique($childIds); 

    Mage::getResourceModel('catalog/product_type_configurable') 
     ->saveProducts($configurableProduct, $childIds); 
} 
Смежные вопросы