skąd pochodzi is_salable?

27

Uwaga: jeśli edytujesz produkty według kodu PHP, a następnie ponownie zindeksuj je w adminie później, oszczędzaj swoje godziny próbując dowiedzieć się, dlaczego nie pokazują się tak jak ja poniżej ...

Krążę w kółko, próbując ustalić, jak is_salableustawiony jest produkt, a tym samym dowiedzieć się, dlaczego moje produkty są teraz wyświetlane.

Jest tylko jedno miejsce w kodzie, które mogę znaleźć:

$salable = $this->isAvailable();

ale nie mogę się dowiedzieć, skąd i skąd to się bierze, ponieważ kiedy podążam isAvailable, wydaje się, że zapętla się z powrotem ...

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

następujące $ this-> isAvailable () stąd przechodzi kilka wierszy:

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

wywołuje to aplikację / code / core / Mage / Catalog / Model / Product / Type / 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;
}

która wywołuje rodzica: /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;
}

który właśnie wywołuje / odbiera dane na temat wartości is_saleable?!? Czy dobrze to wyśledziłem? Skąd ta wartość?

Wydałem rekursywny grep dla mojej instalacji dla is_salable, na pewno powinno to pokazywać wszystkie wiersze, w których jest ustawione, ale nie widzę od razu żadnego:

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

UZNANY:

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

To było setIsSalable, że nie myślałem / wiedziałem, że powinienem szukać, a nie tylko setIsSalable .

Hayden Thring
źródło

Odpowiedzi:

18

isAvailable() wygląda tak:

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

Oznacza to, że wynik metody zależy od rodzaju produktu.
Każdy typ produktu ma isSalable()metodę:

  • Mage_Catalog_Model_Product_Type_Grouped::isSalable() - dla zgrupowanych produktów
  • Mage_Catalog_Model_Product_Type_Configurable::isSalable() - dla produktów konfigurowalnych
  • Mage_Catalog_Model_Product_Type_Abstract::isSalable()- dla pozostałych rodzajów produktu, ponieważ wszystkie typy produktów są rozszerzone Mage_Catalog_Model_Product_Type_Abstract.
    Myślę, że ta rozmowa $this->getTypeInstance(true)cię myli. Metoda getTypeInstance()nie zwraca instancji modelu produktu, ale instancji typu produktu.

[EDYCJA]
W przypadku prostego produktu nazywa się to Mage_Catalog_Model_Product_Type_Grouped::isSalable(). Ta metoda sprawdza, czy produkt jest włączony. Jeśli nie, to falsejest zwracane. Jeśli jest włączony, sprawdza, czy ma właściwość, is_salablektórą może ustawić jeden z twoich obserwatorów.
Jeśli nie ma takiej właściwości, sprawdza, czy instancja typu produktu $this->isComposite(). Jeśli tak, to nie można go sprzedać.
W przypadku produktów konfigurowalnych sprawdza, czy powyższe warunki są spełnione i czy z produktem konfigurowalnym powiązany jest prosty produkt, który można sprzedać (ponownie z powyższymi warunkami)
To samo dzieje się w przypadku produktu zgrupowanego, ale w inny sposób.

Podsumowując is_salable, nie musi istnieć. Ale na wypadek, gdybyś miał obserwatora, który ustawia tę właściwość, bierze to pod uwagę przy sprawdzaniu, czy produkt można sprzedać.
Oto przykład z rdzenia: Metoda Mage_CatalogInventory_Model_Stock_Status::assignProduct()cals To $product->setIsSalable()
samo dotyczy Mage_CatalogInventory_Model_Stock_Status::addStockStatusToProducts.
Ostatni jest wywoływany przez zdarzenie catalog_product_collection_load_after.

Marius
źródło
bardzo dziękuję za pomoc, prześledziłem isAvailable do isSalable i Configurable.php's isSalable, który po prostu wywołuje Abstract.php's isSalable, ale wszystko, co robi, to sprawdź „is_salable”, ale nie znajduję żadnego ustawienia tego ?? dodam mój kod powyżej.
Hayden Thring
dodał do mojego pytania
Hayden Thring
2
Tak jest. Wspomniałem o tym w mojej odpowiedzi catalog_product_collection_load_after. Ale to tylko przykład. Istnieje również zestaw cataloginventory/observer::addInventoryDatapołączeń . Mogą być inni, ale nie szukałem wszystkiego. assignProductis_salable
Marius
1
Nie mam na to niezawodnej metody. Może pobierz wszystkie zdarzenia, które zaczynają się od catalog_product_i debuguj metody wywoływane przez obserwatorów w tych zdarzeniach. i sprawdź, czy ktoś zadzwoni setIsSalablelubsetData('is_salable')
Marius
1
XmlConnect umożliwia połączenie aplikacji mobilnej z witryną. Zignoruj ​​to.
Marius
2

jeśli Salable zwraca false, Reindexing może również mieć problem z reindeksowaniem danych

Hassan Ali Shahzad
źródło
0

Jeśli po ponownym indeksowaniu i debugowaniu nie ma końca, a konfigurowalny produkt nadal jest wyświetlany jako niedostępny, upewnij się, że wszystkie proste mają status Włączony we WSZYSTKICH widokach sklepu. Po prostu zmarnowałem dwie godziny, zastanawiając się, dlaczego konfigurowalnego nie ma w magazynie, bez względu na to, co zrobiłem, dopóki nie sprawdziłem wszystkich widoków sklepu i nie odkryłem, że jakieś ciało wyłączyło status.

David Tay
źródło