在Magento中删除产品的问题

I am trying to delete products from the catalog.

Whenever I try to delete product by using administration interface(mass or single action) it throws me a 500 internal server error. Whenever I try deleting product by using script(programmatically) it just hangs on delete method call.

No error output is shown, no exceptions thrown and logs are silent even though logging is turned on.

Here is the example code I use inside my script:

//...
$collection = Mage::getModel('catalog/product')->getCollection();
$collection->addAttributeToSelect('sku')
    ->addStoreFilter($store_id);
$collection->load();

// collection is not empty I checked
foreach ($collection as $product) {
    try {
        $product->delete(); // this is the line where it hangs
        print $product->getSku() . " deleted" . PHP_EOL;
    } catch (Exception $e) {
        print $e->getMessage();
    }
}

Does anyone have experience with something like this, and what might be a cause?

It's Magento Enterprise 1.11 which corresponds to Magento Community 1.6 as much as I know.

Magento products have to be deleted from 'admin' in php. You have to declare that you are deleting from a secure area. In an external script, you would normally use Mage::app('admin'); but you can just declare the 'isSecureArea' as I have below.

Also, catch the Mage_Core_Exception to see what the problem might be.

try {

    $collection = Mage::getModel('catalog/product')->getCollection();
    $collection->addAttributeToSelect('sku')->addStoreFilter($store_id);
    $collection->load();

    // collection is not empty I checked
    foreach ($collection as $product) {
        try {
                    // Register a secure area to simulate 'admin'
            Mage::register('isSecureArea', true);
            $product->delete(); // this is the line where it hangs
            Mage::unregister('isSecureArea');         

            print $product->getSku() . " deleted" . PHP_EOL;
        } catch (Exception $e) {
            print $e;
        }
    }
} catch (Mage_Core_Exception $e) {
    echo( $e->getMessage() );
} 

EDIT: A quick google search lead to another solution.

http://www.fortwaynewebdevelopment.com/magento-delete-products-programmatically/

This one looks like it should be in a file located in your magento root. It deletes all products, so watch out, but it goes about it differently. Instead of using a collection, it loads each product object by parsing out the product id's first, then for-each them. I thought about suggesting this first, but the collection model is always the 'magento way' and a good first try!

I've noticed that sometimes an object that is part of a collection is a bit different than a loaded object model. Magento is a little screwy like that. Hopefully this might help.

<?php
function deleteAllProducts()
{
    require_once 'app/Mage.php';
    Mage :: app("default") -> setCurrentStore( Mage_Core_Model_App :: ADMIN_STORE_ID );
    $products = Mage :: getResourceModel('catalog/product_collection')->setStoreId(1)->getAllIds();
    if(is_array($products))
    {
        foreach ($products as $key => $pId)
        {
            try
            {
                $product = Mage::getModel('catalog/product')->load($pId)->delete();
                echo "successfully deleted product with ID: ". $pId ."<br />";
            }
            catch (Exception $e)
            {
                echo "Could not delete product with ID: ". $pId ."<br />";
            }
        }
    }
}
deleteAllProducts();
?> 

We found a way around this issue which can help anyone with this problem to just finish the task.

Export all of the products that you want to be deleted and just import them afterwards with action 'delete entities'.

The issue with deleting products from administrator interface or custom script remains and I will continue to investigate on this and will update answer accordingly.

For deleting product by product SKU, use the following code:

<?php
//...
$collection = Mage::getModel('catalog/product')->getCollection();
$collection->addAttributeToSelect('sku')
    ->addStoreFilter($store_id);
$collection->load();

// collection is not empty I checked
foreach ($collection as $product) {
    try {

        $product = Mage::getModel('catalog/product')->loadByAttribute('sku', $product->getSku());

        $product->delete();
        echo $product->getSku() . " deleted" . PHP_EOL;

    } catch (Exception $e) {
        echo $e->getMessage();
    }
}