在庫のある製品のみを含む製品コレクションを取得する


7

これには簡単な答えがあるかもしれませんが、私はそれを見つけることができません。有効になっているが在庫がない商品を除いて、商品コレクションを取得しようとしています。

次の方法を試しましたが、これによりエラーが発生します。

$productIds = array('3','4','9');

$productCollection = Mage::getResourceModel('catalog/product_collection')
    ->addAttributeToSelect(
        array('name', 'image', 'price')
    )
    ->addIdFilter($productIds)
;

$this->_productCollection = Mage::getSingleton('cataloginventory/stock')
    ->addInStockFilterToCollection( $productCollection )
;

次のエラーが発生します。

PHP Fatal error: Call to a member function getTypeInstance() on a non-object in app/code/core/Mage/Catalog/Block/Product/Abstract.php on line 117

app / code / core / Mage / Catalog / Block / Product / Abstract.php:117には以下のメソッドがあります:

/**
 * Retrieve url for add product to cart
 * Will return product view page URL if product has required options
 *
 * @param Mage_Catalog_Model_Product $product
 * @param array $additional
 * @return string
 */
public function getAddToCartUrl($product, $additional = array())
{
    // line 117:
    if (!$product->getTypeInstance(true)->hasRequiredOptions($product)) {
        return $this->helper('checkout/cart')->getAddUrl($product, $additional);
    }
    $additional = array_merge(
        $additional,
        array(Mage_Core_Model_Url::FORM_KEY => $this->_getSingletonModel('core/session')->getFormKey())
    );
    if (!isset($additional['_escape'])) {
        $additional['_escape'] = true;
    }
    if (!isset($additional['_query'])) {
        $additional['_query'] = array();
    }
    $additional['_query']['options'] = 'cart';
    return $this->getProductUrl($product, $additional);
}

コレクションをフィルタリングして在庫のある商品のみを取得する簡単な方法はありますか?明らかにisSaleable()、ループの内側について知っています。ありがとう。


1
間違った方法を引用して修正しています...
Melvyn

1
これから判断すると、これは貼り付けたコードではなく、テンプレートでうまくいきません。では、コレクションをどのようにループし、ループ内で呼び出しが失敗していることを確認しますか?その$this->getAddToCartUrl($product)外に迷う者はいません。
Melvyn 14

回答:


23

質問に答える。あなたはこれを使うでしょう(あなたのバージョンとそれほど変わらない):

$productCollection = Mage::getResourceModel('catalog/product_collection')
                        ->addAttributeToSelect(array('name', 'image', 'price'))
                        ->addAttributeToFilter('status', array('eq' => Mage_Catalog_Model_Product_Status::STATUS_ENABLED));

Mage::getSingleton('cataloginventory/stock')
    ->addInStockFilterToCollection($productCollection);

$this->_productCollection = $productCollection;

しかし、エラーの原因は正確にはわかりません。これは、getSubmitUrl/ getAddToCartUrlproduct paramがブール値のfalseであり、コレクション自体ではないためです。


はい、これは元の質問に対する答えです。
ジョンゴシ14

3
Magentoがシンプルな製品を使用して入手可能かどうかを判断していることを考えると、構成可能な製品の在庫情報を使用してcataloginventory_stock_itemに参加するため、構成可能な製品には役に立たないと思います。
Ricardo Martins

私の問題を解決する素晴らしい
Sourav

3

おそらく1日遅れて1ドル足りないかもしれませんが、この2番目のステップの作業をすべて行う代わりに、cataloginventorystock_stock_statusテーブルをコレクションselect()に単純に結合できます。

$collection = Mage::getModel('catalog/product')->getCollection();
$collection->getSelect()->join('cataloginventory_stock_status', 'cataloginventory_stock_status.product_id = e.entity_id', array('stock_status'));
$collection->getSelect()->where("`cataloginventory_stock_status`.`stock_status` = 1");

追加のjoin()またはwhere()句と組み合わせてこれを行うことができます。それが正しい方向に役立つことを願っています。


2

Newermindは元の質問に正しく答えました。彼に感謝します。将来の冒険者のために、これが私のコードのどこが悪いかです。Melvyn氏の助力に感謝します。

問題

問題の私のコードから、オブジェクト$this->_productCollectionが含まれています。ビューでそのオブジェクトを反復処理する場合、$_product変数は配列です。

$_products = $this->_productCollection;

foreach ( $_products as $_product ) {
    echo gettype( $_product ); // <-- returns type [array]
}

app/code/core/Mage/Catalog/Block/Product/Abstract.php:117(最終的に)のメソッドはを呼び出しますgetTypeInstance()。そのメソッドはオブジェクト、特にのインスタンスを期待していますMage_Catalog_Model_Product

ビューでは$this->getSubmitUrl($_product)、foreachループ内で呼び出していました。

$_products = $this->_productCollection;

foreach ( $_products as $_product ) {
    echo $this->getSubmitUrl( $_product );
}

getSubmitUrl()は、Mage_Catalog_Block_Product_Abstract115行目のメソッドです。123行目でが呼び出されgetAddToCartUrl()、が呼び出されgetTypeInstance()オブジェクトが期待されます。問題は、配列を渡していたことです。

単純なOOPの原則ですが、あまりにも疲れていてそれを見ることができなかったと思います。助けてくれてありがとう。

ソリューション

したがって、残念ながら、このaddInStockFilterToCollectionメソッドは在庫の在庫オブジェクトを返します-私が求めていたものではありません。在庫がある商品の商品コレクションが必要です。

また、このaddInStockFilterToCollectionメソッドはMage_Catalog_Model_Resource_Eav_Mysql4_Product_Link_Product_Collectionコレクションでのみ機能します。

では、コレクションを取得するにはどうすればよいですか?私のアプローチは次のとおりでした:

  1. 在庫のある製品のコレクションを取得します。
  2. 結果セットからID配列を作成します。
  3. 在庫の結果からIDを使用して、製品コレクションを取得します。

コードは次のとおりです。

$inStockProductIds = array();

$inStockCollection = Mage::getModel('cataloginventory/stock')
    ->getItemCollection()
    ->addFieldToFilter('is_in_stock', 
        array( 'eq' => 1 )
    )
    ->addFieldToFilter( 'entity_id', 
        array( 'in' => array ('1', '2') )
    )
;

if ( $inStockCollection) {
    foreach ($inStockCollection as $stockProduct) {
        $inStockProductIds[] = $stockProduct->getId();
    }
}

$this->_productCollection = Mage::getModel('catalog/product')
    ->getCollection()
    ->addAttributeToSelect(
        array('name', 'image', 'price')
    )
    ->addIdFilter( $inStockProductIds )
    ->setPageSize( 2 )
    ->load();
;

return $this->_productCollection;

これにより、在庫のある商品のみを含む商品コレクションが返されます。少し重いですが、動作します。これに関する改善があれば幸いです。ありがとう。


なぜ単に次のような$collection = Mage::getModel("catalog/product")->getCollection() ... ; Mage::getSingleton('cataloginventory/stock')->addInStockFilterToCollection($col);ことをしないのですか?戻り値で何もしないことに注意してください。ただし、コレクションは更新され、在庫フィルターが含まれています。
sbditto85 2015年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.