Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disabling a Magento Product via code

Tags:

php

magento

More precisely, how to simulate the action made when a user selects "Status: Disabled" in the Product edit page in backend - so that it's not shown, sold, showed in various lists etc.?

From what I've gathered, Magento sets the status of a product to 2 when disabled, that being Mage_Catalog_Model_Product_Status::STATUS_DISABLED.

I've tried the code below in Mage_Catalog_Model_Product to see how/if it works, but it doesn't:

    public function getStatus()
    {
        return 2;
//        return $this->_getData('status');
    }

But I think that's not enough as I presume Magento uses events to notify listeners that the Product has been disabled.

PS: Magento EE 1.11.0.2

like image 257
nevvermind Avatar asked Apr 06 '12 13:04

nevvermind


1 Answers

You could use

Mage::getModel('catalog/product_status')->updateProductStatus($product->getId(), $storeId, Mage_Catalog_Model_Product_Status::STATUS_DISABLED);

Which looks like this

Mage_Catalog_Model_Product_Status

/**
 * Update status value for product
 *
 * @param   int $productId
 * @param   int $storeId
 * @param   int $value
 * @return  Mage_Catalog_Model_Product_Status
 */
public function updateProductStatus($productId, $storeId, $value)
{
    Mage::getSingleton('catalog/product_action')
        ->updateAttributes(array($productId), array('status' => $value), $storeId);

    // add back compatibility event
    $status = $this->_getResource()->getProductAttribute('status');
    if ($status->isScopeWebsite()) {
        $website = Mage::app()->getStore($storeId)->getWebsite();
        $stores  = $website->getStoreIds();
    } else if ($status->isScopeStore()) {
        $stores = array($storeId);
    } else {
        $stores = array_keys(Mage::app()->getStores());
    }

    foreach ($stores as $storeId) {
        Mage::dispatchEvent('catalog_product_status_update', array(
            'product_id'    => $productId,
            'store_id'      => $storeId,
            'status'        => $value
        ));
    }

    return $this;
}

The dispatch event is based on

        <catalog_product_status_update>
            <observers>
                <sales_quote>
                    <class>sales/observer</class>
                    <method>catalogProductStatusUpdate</method>
                </sales_quote>
            </observers>
        </catalog_product_status_update>

Here is the method

Mage_Sales_Model_Observer



   /**
     * Catalog Mass Status update process
     *
     * @param Varien_Event_Observer $observer
     * @return Mage_Sales_Model_Observer
     */
    public function catalogProductStatusUpdate(Varien_Event_Observer $observer)
    {
        $status     = $observer->getEvent()->getStatus();
        if ($status == Mage_Catalog_Model_Product_Status::STATUS_ENABLED) {
            return $this;
        }
        $productId  = $observer->getEvent()->getProductId();
        Mage::getResourceSingleton('sales/quote')->markQuotesRecollect($productId);

        return $this;
    }

Here is the resource model

Mage_Catalog_Model_Resource_Product_Status

/**
     * Update product status for store
     *
     * @param int $productId
     * @param int $storId
     * @param int $value
     * @return Mage_Catalog_Model_Resource_Product_Status
     */
    public function updateProductStatus($productId, $storeId, $value)
    {
        $statusAttributeId  = $this->_getProductAttribute('status')->getId();
        $statusEntityTypeId = $this->_getProductAttribute('status')->getEntityTypeId();
        $statusTable        = $this->_getProductAttribute('status')->getBackend()->getTable();
        $refreshIndex       = true;
        $adapter            = $this->_getWriteAdapter();

        $data = new Varien_Object(array(
            'entity_type_id' => $statusEntityTypeId,
            'attribute_id'   => $statusAttributeId,
            'store_id'       => $storeId,
            'entity_id'      => $productId,
            'value'          => $value
        ));

        $data = $this->_prepareDataForTable($data, $statusTable);

        $select = $adapter->select()
            ->from($statusTable)
            ->where('attribute_id = :attribute_id')
            ->where('store_id     = :store_id')
            ->where('entity_id    = :product_id');

        $binds = array(
            'attribute_id' => $statusAttributeId,
            'store_id'     => $storeId,
            'product_id'   => $productId
        );

        $row = $adapter->fetchRow($select);

        if ($row) {
            if ($row['value'] == $value) {
                $refreshIndex = false;
            } else {
                $condition = array('value_id = ?' => $row['value_id']);
                $adapter->update($statusTable, $data, $condition);
            }
        } else {
            $adapter->insert($statusTable, $data);
        }

        if ($refreshIndex) {
            $this->refreshEnabledIndex($productId, $storeId);
        }

        return $this;
    }

There is no observer that directly executes this function, but an event is dispatched in Status.php.

like image 76
Vern Burton Avatar answered Oct 01 '22 19:10

Vern Burton