Nhận bộ sưu tập sản phẩm chỉ chứa các sản phẩm trong kho


7

Có thể có một câu trả lời đơn giản cho vấn đề này, nhưng tôi không thể tìm thấy nó. Tôi đang cố gắng truy xuất bộ sưu tập sản phẩm, ngoại trừ các sản phẩm được bật nhưng hết hàng.

Tôi đã thử cách tiếp cận sau đây, nhưng điều này gây ra lỗi:

$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 )
;

Xảy ra lỗi sau:

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

ứng dụng / mã / lõi / Pháp sư / Danh mục / Khối / Sản phẩm / Tóm tắt.php: 117 có phương pháp sau:

/**
 * 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);
}

Có cách nào đơn giản để lọc một bộ sưu tập để chỉ lấy các sản phẩm có trong kho không? Rõ ràng tôi biết về isSaleable()bên trong vòng lặp. Cảm ơn.


1
Bạn đang trích dẫn sai phương pháp, sửa chữa ...
Melvyn

1
Và đánh giá từ đó, điều này đi sai trong mẫu của bạn, không phải trong mã bạn đã dán. Vậy làm thế nào để bạn lặp qua bộ sưu tập của mình và bạn có chắc cuộc gọi bị lỗi trong vòng lặp của mình không? Không phải một số đi lạc $this->getAddToCartUrl($product)bên ngoài của nó.
Melvyn

Câu trả lời:


23

Để trả lời câu hỏi. Bạn sẽ sử dụng cái này (không khác lắm so với phiên bản của bạn):

$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;

Nhưng tôi không biết chính xác nguyên nhân gây ra lỗi của bạn, vì có vẻ như liên quan đến thực tế là getSubmitUrl/ getAddToCartUrlparam sản phẩm là boolean sai và không phải là bộ sưu tập.


Vâng, đây là câu trả lời cho câu hỏi ban đầu, thx newermind.
Jongosi

3
Tôi e rằng nó không giúp ích cho các sản phẩm có thể định cấu hình, vì nó sẽ tham gia cataloginventory_stock_item bằng cách sử dụng thông tin chứng khoán sản phẩm có thể định cấu hình, phù thủy là không chính xác, vì Magento sử dụng các sản phẩm đơn giản để nói có sẵn hay không.
Ricardo Martins

Thật tuyệt khi giải quyết vấn đề của tôi
Sourav

3

Có lẽ trễ một ngày và một đô la ngắn, nhưng thay vì thực hiện tất cả công việc bước thứ hai này, bạn chỉ cần tham gia cataloginventorystock_stock_statusbảng vào bộ sưu tập của mình 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");

Bạn có thể làm điều này kết hợp với các mệnh đề nối () hoặc where () bổ sung. Hy vọng nó sẽ giúp bạn đi đúng hướng.


2

Newermind trả lời đúng câu hỏi ban đầu; tôi cảm ơn anh ấy Đối với các nhà thám hiểm trong tương lai, đây là những gì sai với mã của tôi. Đặc biệt cảm ơn Melvyn vì sự giúp đỡ của anh ấy.

Vấn đề

Từ mã của tôi trong câu hỏi, $this->_productCollectioncó chứa một đối tượng . Khi chúng ta lặp lại đối tượng đó trong khung nhìn, $_productbiến là một mảng .

$_products = $this->_productCollection;

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

Phương thức tại app/code/core/Mage/Catalog/Block/Product/Abstract.php:117(cuối cùng) gọi getTypeInstance(). Phương thức đó đang mong đợi một đối tượng , cụ thể là một thể hiện của Mage_Catalog_Model_Product.

Trong khung nhìn, tôi đã gọi $this->getSubmitUrl($_product)bên trong vòng lặp foreach:

$_products = $this->_productCollection;

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

getSubmitUrl()là một phương thức của Mage_Catalog_Block_Product_Abstractdòng 115. Trên dòng 123 nó gọi getAddToCartUrl(), nó gọi getTypeInstance()và đang mong đợi một đối tượng . Vấn đề là, tôi đã đưa cho nó một mảng .

Nguyên tắc OOP đơn giản, nhưng tôi đoán rằng tôi đã quá mệt mỏi để xem nó. Thx tất cả để được giúp đỡ.

Giải pháp

Vì vậy, thật không may, addInStockFilterToCollectionphương thức trả về một đối tượng chứng khoán tồn kho - không phải là những gì tôi đã theo sau. Tôi cần một bộ sưu tập các sản phẩm trong kho .

Ngoài ra, addInStockFilterToCollectionphương pháp chỉ hoạt động với một Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Link_Product_Collectionbộ sưu tập.

Vậy, làm thế nào để có được bộ sưu tập? Cách tiếp cận của tôi như sau:

  1. Nhận một bộ sưu tập các sản phẩm trong kho.
  2. Tạo một mảng ID từ tập kết quả.
  3. Nhận bộ sưu tập sản phẩm, sử dụng ID từ kết quả trong kho.

Đây là mã:

$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;

Điều đó trả về một bộ sưu tập sản phẩm, chỉ chứa các sản phẩm trong kho. Nó hơi nặng, nhưng nó hoạt động. Tôi đánh giá cao bất kỳ cải tiến về điều này. Cảm ơn.


tại sao không chỉ làm một cái gì đó như: $collection = Mage::getModel("catalog/product")->getCollection() ... ; Mage::getSingleton('cataloginventory/stock')->addInStockFilterToCollection($col);chú ý tôi không làm gì với giá trị trả về, nhưng bộ sưu tập được cập nhật để có bộ lọc instock trên đó.
sbditto85
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.