откуда берется 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);
}**

это тогда вызывает приложение / код / ​​ядро ​​/ Маг / Каталог / Модель / Продукт / Тип / Configurable.php's 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's 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;
}

который просто выполняет вызов has / get для значения is_saleable?!? Я правильно это отследил? Откуда эта ценность?

Я выполнил рекурсивный grep для моей установки для is_salable, конечно, это должно показать все строки, где оно установлено, но я не вижу сразу:

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 .

Хайден Тринг
источник

Ответы:

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 и isSalable Configurable.php, который просто вызывает isSalable Abstract.php, но все, что он делает, это проверка 'is_salable', но я не нашел его настройки ?? я добавлю свой код след выше.
Хайден Тринг
добавил к моему вопросу
Hayden Thring
2
Да, есть. Я упомянул об этом в своем ответе catalog_product_collection_load_after. Но это всего лишь пример. Существует также, cataloginventory/observer::addInventoryDataчто звонки, assignProductкоторые устанавливает is_salable. Могли быть и другие, но я не искал всех.
Мариус
1
У меня нет надежного способа сделать это. Может быть, получить все события, которые начинаются с, catalog_product_и отладить методы, вызываемые наблюдателями для этих событий. и посмотреть, если один звонит setIsSalableилиsetData('is_salable')
Мариус
1
XmlConnect позволяет подключить мобильное приложение к вашему веб-сайту. Игнорируй это.
Мариус
2

Если Salable возвращает false, то при переиндексации также может возникнуть проблема переиндексации данных.

Хасан Али Шахзад
источник
0

Если после переиндексации и отладки is_salable без конца и ваш конфигурируемый продукт все еще показывает, что его нет в наличии, убедитесь, что все простые имеют статус «Включено» во всех представлениях магазина. Я просто потратил два часа на размышления о том, почему конфигурируемый товар отсутствует на складе, независимо от того, что я сделал, пока я не проверил все представления магазина и не обнаружил, что какое-то тело отключило статус.

Дэвид Тэй
источник