Magento: Ein einzelnes Produkt laden

Bei Magento gibt es mehrere Möglichkeiten ein einzelnes Produkt Objekt zu laden.

1. Laden anhand der ID

1
2
3
$product = Mage::getModel('catalog/product')
                        ->setStoreId(Mage::app()->getStore()->getId())
                        ->load($productId);

2. Laden anhand eine Attributs

1
2
3
4
$product = Mage::getModel('catalog/product')
                        ->setStoreId(Mage::app()->getStore()->getId())
                        ->loadByAttribute($attributeName, $attributeValue)
						->load();

Hierbei ist zu beachten, das eigentlich die Product Collection geladen wird und einfach das erste Objekt der Collection zurückgegeben wird.
Siehe: Mage_Catalog_Model_Abstract

1
2
3
4
5
6
7
8
9
10
11
public function loadByAttribute($attribute, $value, $additionalAttributes = '*')
{
    $collection = $this->getResourceCollection()
        ->addAttributeToFilter($attribute, $value)
        ->setPage(1,1);
 
    foreach ($collection as $object) {
        return $object;
    }
    return false;
}

Wichtig: bei der zweiten Variaten werden nur die reinen Produktdaten geladen.
Bei der ersten Variaten wird das Objekt von diversen Observern mit weiteren Daten angereichert, da die _beforeLoad und die _afterLoad Funktion automatisch aufgerufen werden.

Siehe: Mage_Catalog_Model_Abstract

1
2
3
4
5
6
7
8
9
public function load($id, $field=null)
{
    $this->beforeLoad($id, $field);
    $this->_getResource()->load($this, $id, $field);
    $this->_afterLoad();
    $this->setOrigData();
    $this ->_hasDataChanges = false;
    return $this;
}

In der Funktion _afterLoad werden dabei folgende Events gefeuert.

1
2
3
4
5
6
protected function _afterLoad()
{
    Mage::dispatchEvent('model_load_after', array('object'=>$this));
    Mage::dispatchEvent($this ->_eventPrefix.'_load_after', $this->getEventData());
    return $this;
}

Das Event „catalog_product_load_after“ wird z.B. vom CatalogInventory Observer überwacht
Siehe: /app/code/core/Mage/CatalogInventory/etc/config.xml

1
2
3
4
5
6
7
8
9
10
11
<events>
    <catalog_product_load_after>
        <observers>
            <inventory>
                <class>cataloginventory/observer</class>
                <method>addInventoryData</method>
            </inventory>
        </observers>
    </catalog_product_load_after>
...
</events>

Siehe: Mage_CatalogInventory_Model_Observer

1
2
3
4
5
6
7
8
9
10
11
12
13
public function addInventoryData($observer)
{
    $product = $observer->getEvent()->getProduct();
    if ($product instanceof Mage_Catalog_Model_Product) {
        $productId = intval($product->getId());
        if (!isset($this->_stockItemsArray[$productId])) {
            $this->_stockItemsArray[$productId] = Mage::getModel('cataloginventory/stock_item');
        }
        $productStockItem = $this->_stockItemsArray[$productId];
        $productStockItem->assignProduct($product);
    }
    return $this;
}

Dabei wird in der Funktion „assignProduct“ das StockItem Objekt im Produkt Objekt gespeichert:

Siehe: Mage_CatalogInventory_Model_Stock_Item

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public function assignProduct(Mage_Catalog_Model_Product $product)
{
    if (!$this->getId() || !$this->getProductId()) {
        $this->_getResource()->loadByProductId($this, $product->getId());
        $this->setOrigData();
    }
 
    $this->setProduct($product);
    $product->setStockItem($this);
 
    $product->setIsInStock($this->getIsInStock());
    Mage::getSingleton('cataloginventory/stock_status')
        ->assignProduct($product, $this->getStockId(), $this->getStockStatus());
    return $this;
}

Fazit

Man sollte also immer daran denken, dass wenn man ein Produkt per „loadByAttribute“ lädt, eventuell nicht alle Daten im Produkt Objekt geladen werden, die man im jeweiligen Kontext benötigt.
Das gilt übrigens generell, wenn man ein Objekt per Collection lädt. Wenn man über Objekte einer Collection iteriert, werden die Funktionen _beforeLoad und _afterLoad der geladenen Objekte nicht aufgerufen.

Dieser Beitrag wurde unter Magento abgelegt und mit , , verschlagwortet. Setze ein Lesezeichen auf den Permalink.

Die Kommentarfunktion ist geschlossen.