da dove viene is_salable?


27

Nota: se hai modificato i prodotti con il codice PHP, quindi reindicizzali nell'amministratore dopo, risparmia le tue ore personali cercando di capire perché non vengono visualizzati come me di seguito ...

Sto girando in tondo cercando di capire come is_salableè impostato un prodotto, e quindi capire perché i miei prodotti ora stanno mostrando.

C'è solo un posto nel codice che posso trovare che lo imposta:

$salable = $this->isAvailable();

ma non riesco a capire come o dove ottenga questo, come quando lo seguo isAvailablesembra semplicemente tornare indietro ....

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

seguendo $ this-> isAvailable () da qui va qualche riga:

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

questo quindi chiama isSalable di app / code / core / Mage / Catalogue / Model / Product / Type / Configurable.php

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

che chiama il genitore: /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;
}

che fa solo una chiamata di dati get / get sul valore is_saleable?!? L'ho rintracciato giusto? Da dove viene questo valore?

Ho emesso un grep ricorsivo sulla mia installazione per is_salable, sicuramente questo dovrebbe mostrare tutte le linee in cui è impostato ma non ne vedo subito:

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

TROVATO:

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

Era setIsSalable che non pensavo / sapevo cercare piuttosto che setIsSalable .

Risposte:


18

isAvailable() Somiglia a questo:

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

Ciò significa che il risultato del metodo dipende dal tipo di prodotto.
Ogni tipo di prodotto ha un isSalable()metodo:

  • Mage_Catalog_Model_Product_Type_Grouped::isSalable() - per prodotti raggruppati
  • Mage_Catalog_Model_Product_Type_Configurable::isSalable() - per prodotti configurabili
  • Mage_Catalog_Model_Product_Type_Abstract::isSalable()- per il resto dei tipi di prodotto poiché si estendono tutti i tipi di prodotto Mage_Catalog_Model_Product_Type_Abstract.
    Penso che la chiamata $this->getTypeInstance(true)ti confonda. Il metodo getTypeInstance()non restituisce un'istanza del modello del prodotto, ma un'istanza di un tipo di prodotto.

[EDIT]
Per un prodotto semplice questo si chiama Mage_Catalog_Model_Product_Type_Grouped::isSalable(). Questo metodo controlla se il prodotto è abilitato. In caso contrario, falseviene restituito. Se è abilitato, controlla se ha una proprietà is_salableche può essere impostata da uno dei tuoi osservatori.
Se non dispone di tale proprietà, verifica se l'istanza del tipo di prodotto $this->isComposite(). Se lo è, non è vendibile.
Per i prodotti configurabili controlla se sono soddisfatte le condizioni di cui sopra e se esiste un prodotto semplice associato a quello configurabile che è vendibile (sempre con le condizioni di cui sopra)
Lo stesso viene fatto per il prodotto raggruppato ma in modo diverso.

In conclusione is_salablenon deve esistere. Ma nel caso in cui tu abbia un osservatore che imposta quella proprietà che viene presa in considerazione quando controlla se il prodotto può essere venduto.
Ecco un esempio dal core: il metodo Mage_CatalogInventory_Model_Stock_Status::assignProduct()cals $product->setIsSalable()
Same vale per Mage_CatalogInventory_Model_Stock_Status::addStockStatusToProducts.
L'ultimo viene chiamato dall'evento catalog_product_collection_load_after.


grazie ancora per il tuo aiuto, ho fatto risalire isAvailable a isSalable e isSalable di Configurable.php che chiama solo IsSalable di Abstract.php ma tutto ciò che fa è controllare 'is_salable' ma non trovo alcuna impostazione ?? aggiungerò il mio codice sopra.
Hayden Thring,

aggiunto alla mia domanda
Hayden Thring,

2
Si C'è. L'ho menzionato nella mia risposta catalog_product_collection_load_after. Ma questo è solo un esempio. C'è anche cataloginventory/observer::addInventoryDataquella chiamata assignProductche imposta is_salable. Potrebbero essercene altri ma non ho cercato tutto.
Marius

1
Non ho un metodo affidabile per farlo. Forse ottenere tutti gli eventi che iniziano con catalog_product_ed eseguire il debug dei metodi chiamati dagli osservatori su quegli eventi. e vedi se uno chiama setIsSalableosetData('is_salable')
Marius

1
XmlConnect ti consente di connettere la tua applicazione mobile al tuo sito web. Ignoralo.
Marius


0

Se dopo la reindicizzazione e il debug è_salabile a non finire e il tuo prodotto configurabile viene ancora visualizzato come esaurito, assicurati che tutti i semplici abbiano lo stato impostato su Abilitato, in TUTTE le visualizzazioni del negozio. Ho appena perso due ore a chiedermi perché un configurabile fosse esaurito, qualunque cosa facessi, fino a quando non ho controllato tutte le visualizzazioni del negozio e ho scoperto che un corpo aveva disabilitato lo stato.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.