is_salable来自哪里?


27

注意:如果您一直在通过PHP代码编辑产品,请在之后将它们重新编入管理员的索引中,并节省大量时间尝试找出为什么它们在下面没有像我一样显示出来...

我正在兜圈子,试图弄清楚is_salable产品的设置方式,从而弄清楚为什么我的产品现在展示。

我发现在代码中只有一个地方可以设置它:

$salable = $this->isAvailable();

但是我无法弄清楚如何或从何处获得此信息,因为当我遵循时,isAvailable它似乎只是循环回去...。

/app/code/core/Mage/Catalog/Model/Product.php

    public function isSalable()
    {
        Mage::dispatchEvent('catalog_product_is_salable_before', array(
            'product'   => $this
        ));

        $salable = $this->isAvailable();

    $object = new Varien_Object(array(
        'product'    => $this,
        'is_salable' => $salable
    ));
    Mage::dispatchEvent('catalog_product_is_salable_after', array(
        'product'   => $this,
        'salable'   => $object
    ));
    return $object->getIsSalable();
}

从这里跟随$ this-> isAvailable()之后,它会走几行:

**public function isAvailable()
{ 
    return $this->getTypeInstance(true)->isSalable($this);
}**

然后调用app / code / core / Mage / Catalog / Model / Product / Type / Configurable.php的isSalable

public function isSalable($product = null)
{
    $salable = parent::isSalable($product);

    if ($salable !== false) {
        $salable = false;
        if (!is_null($product)) {
            $this->setStoreFilter($product->getStoreId(), $product);
        }
        foreach ($this->getUsedProducts(null, $product) as $child) {
            if ($child->isSalable()) {
                $salable = true;
                break;
            }
        }
    }

    return $salable;
}

它调用父级:/app/code/core/Mage/Catalog/Model/Product/Type/Abstract.php的isSalable:

public function isSalable($product = null)
{
    $salable = $this->getProduct($product)->getStatus() == Mage_Catalog_Model_Product_Status::STATUS_ENABLED;
    if ($salable && $this->getProduct($product)->hasData('is_salable')) {
        $salable = $this->getProduct($product)->getData('is_salable');
    }
    elseif ($salable && $this->isComposite()) {
        $salable = null;
    }

    return (boolean) (int) $salable;
}

is / saleable值仅拥有/获取数据的哪个?!?我追踪正确吗?这个值从哪里来?

我在安装中为is_salable发出了一个递归grep,肯定会显示设置它的任何行,但是我看不到任何行:

grep -r is_salable *
app/code/core/Mage/CatalogInventory/Model/Stock/Status.php:            $object = new Varien_Object(array('is_in_stock' => $product->getData('is_salable')));
app/code/core/Mage/XmlConnect/Block/Wishlist.php:                $itemXmlObj->addChild('is_salable', (int)$item->getProduct()->isSalable());
app/code/core/Mage/XmlConnect/Block/Catalog/Product.php:            $item->addChild('is_salable', (int)$product->isSalable());
app/code/core/Mage/XmlConnect/Block/Cart/Crosssell.php:                $itemXmlObj->addChild('is_salable', 0);
app/code/core/Mage/XmlConnect/Block/Cart/Crosssell.php:                $itemXmlObj->addChild('is_salable', (int)$product->isSalable());
app/code/core/Mage/Catalog/Model/Product.php:        Mage::dispatchEvent('catalog_product_is_salable_before', array(
app/code/core/Mage/Catalog/Model/Product.php:            'is_salable' => $salable
app/code/core/Mage/Catalog/Model/Product.php:        Mage::dispatchEvent('catalog_product_is_salable_after', array(
app/code/core/Mage/Catalog/Model/Product.php:        if ($this->hasData('is_salable')) {
app/code/core/Mage/Catalog/Model/Product.php:            return $this->getData('is_salable');
app/code/core/Mage/Catalog/Model/Product/Type/Abstract.php:        if ($salable && $this->getProduct($product)->hasData('is_salable')) {
app/code/core/Mage/Catalog/Model/Product/Type/Abstract.php:            $salable = $this->getProduct($product)->getData('is_salable');

发现:

grep -r setIsSalable *
app/code/core/Mage/CatalogInventory/Model/Stock/Status.php:        $product->setIsSalable($stockStatus);
app/code/core/Mage/CatalogInventory/Model/Stock/Status.php:                    $product->setIsSalable($status);

我不认为/不知道要寻找的是setIsSalable,而不仅仅是setIsSalable

Answers:


18

isAvailable() 看起来像这样:

public function isAvailable()
{
    return $this->getTypeInstance(true)->isSalable($this)
        || Mage::helper('catalog/product')->getSkipSaleableCheck();
}

这意味着该方法的结果取决于产品类型。
每种产品类型都有一种isSalable()方法:

  • Mage_Catalog_Model_Product_Type_Grouped::isSalable() -用于分组产品
  • Mage_Catalog_Model_Product_Type_Configurable::isSalable() -用于可配置产品
  • Mage_Catalog_Model_Product_Type_Abstract::isSalable()-对于其余产品类型,因为所有产品类型都可以扩展Mage_Catalog_Model_Product_Type_Abstract
    我认为这个电话$this->getTypeInstance(true)使您感到困惑。该方法getTypeInstance()不返回产品模型的实例,而是产品类型的实例。

[编辑]
对于一个简单的产品,它称为Mage_Catalog_Model_Product_Type_Grouped::isSalable()。此方法检查产品是否启用。如果不是,则false返回。如果启用,则它将检查它是否具有is_salable可以由您的观察者之一设置的属性。
如果没有这样的属性,则检查产品类型实例是否为$this->isComposite()。如果是,那么它就不适合出售。
对于可配置产品,它将检查是否满足上述条件,以及是否有与该可配置产品相​​关的简单产品可出售(再次符合上述条件)
。对分组产品也是如此,但是方式不同。

总之,is_salable不必存在。但是,以防万一您有一个观察者来设置该属性,在检查产品是否可以出售时会考虑它。
这是核心示例:方法Mage_CatalogInventory_Model_Stock_Status::assignProduct()cals $product->setIsSalable()
同样适用Mage_CatalogInventory_Model_Stock_Status::addStockStatusToProducts
事件调用了最后一个catalog_product_collection_load_after


再次非常感谢您的帮助,我已将isAvailable追溯到isSalable和Configurable.php的isSalable,后者仅调用Abstract.php的isSalable,但它所做的只是检查“ is_salable”,但我没有找到它的设置?我将在上面添加我的代码跟踪。
Hayden Thring

加入到我的问题
海登思林

2
就在这里。我在回答中提到了它catalog_product_collection_load_after。但这只是一个例子。还有cataloginventory/observer::addInventoryData那个电话assignProduct该套is_salable。可能还有其他人,但我并没有全力以赴。
Marius

1
我没有执行此操作的可靠方法。也许获取所有以这些事件开头的事件,catalog_product_并调试观察者在这些事件上调用的方法。看看是否有人打来电话setIsSalablesetData('is_salable')
马里斯(Marius)

1
XmlConnect允许您将移动应用程序连接到您的网站。忽略它。
Marius


0

如果在重新索引和调试之后is_salable一直没有结束,并且您的可配置产品仍然显示为缺货,请确保在所有商店视图中所有简单商品的状态都设置为Enabled。我只是浪费了两个小时,想知道为什么不管我做什么,可配置的东西都缺货了,直到我检查了所有的商店视图,发现某个机体禁用了该状态。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.