Magento 1.9 Product Status – Changing with Script Not Visible in Admin

magento-1.9productproduct-imagesstatus

I'm trying to get all product without image to desactivate them.
I started from this thread https://stackoverflow.com/questions/3565377/how-can-i-find-all-products-without-images-in-magento

At first, it was just to extract products without images, and it was working fine, but now I need to disable them and it's half working.

The problem is, when the code return that the status has changed, when I go back in Magento Admin, the product is still enable. (cache and indexes refreshed)

But when I run again the code, the status has changed and I can't see the product on the site.

So the code is working BUT I don't know why the admin product manager can't see that change.

I didn't find threads where I can get a glimpse of a solution.
Maybe I'm just doing all wrong and I can't PROPERLY change the status from a collection.

Here my php file (mymagento/var/import/dev/test.php) :

header('Content-Type: text/html; charset=utf-8');
require_once('../../../app/Mage.php'); //Path to Magento
umask(0);
Mage::app();

$storeId = 1; //check in magento admin
echo "Store ID : ".$storeId."\n<br />\n";
//this builds a collection that's analagous to 
//select * from products where image = 'no_selection'
$products = Mage::getModel('catalog/product')
    ->getCollection()
    ->addAttributeToSelect('*')
    ->addAttributeToFilter(
        array(
            array (
            'attribute' => 'image',
            'like' => 'no_selection'
            ),
            array(
                'attribute' => 'image',
                'null' => '1'
            ),
            array(
                'attribute' => 'small_image',
                'null' => '1'
            ),
            array(
                'attribute' => 'thumbnail',
                'null' => '1'
            ),
            array(
                'attribute' => 'image',
                'nlike' => '%/%/%'
            ),
            array(
                'attribute' => 'small_image',
                'nlike' => '%/%/%'
            ),
            array(
                'attribute' => 'thumbnail',
                'nlike' => '%/%/%'
            )
        ),
        null,
        'left'
    );
echo  "SKU;NAME;VISIBLE;STATUS\n<br />\n";
foreach($products as $product)
{   
    $product->load();

    if($product->getVisibility() == 4 && $product->getStatus() == 1) {
        echo  $product->getSku() . ";".$product->getName().";".$product->getVisibility().";".$product->getStatus()."\n<br />\n";
        try {
            Mage::getModel('catalog/product_status')->updateProductStatus($product->getId(), $storeId, Mage_Catalog_Model_Product_Status::STATUS_DISABLED);
            echo "Product #".$product->getSku()." : Status changed to ".$product->getStatus().". \n<br />\n";
        } catch(Exception $e) {
            echo "Product #".$product->getSku()." Status could not be changed: ".$e->getMessage()."\n<br />\n";
        }
    }
    try {
        $product->save();
        echo "Product #".$product->getSku()." : saved\n<br />\n";
    } catch ( Exception $e ) {
        echo "Product #".$product->getSku()." could not be saved: ".$e->getMessage();
    }                        
} 

It's just a script to run 1 time to get rid of products without images to start on good bases for the next update.

Thank you for your time !

Best Answer

So, I came with a solution.

My problem was not fully related to my code. When in admin product panel, I was looking at the default view of my product who was enable when the scope of my code was only for the EN store (which was disable when I switched the view).

I was not looking the product from the good store...

Anyway, I had to disable the product on both default and EN store.

Moreover, I find that some of my product did not have image selected BUT had images in the media gallery.

So, I add a condition when the script find no image selected, it has to look the media gallery to see if images are in it. If there are, I took the first image and add it to.

The only problem is that it ADD the image to the gallery media. That's mean I've got the images in it, twice, because I couldn't find a way to just add the image in the gallery to the images/thumbnail/small_image attributes. but it's another problem.

For instance, here my nearly final code :

<?
header('Content-Type: text/html; charset=utf-8');
require_once('../../../app/Mage.php'); //Path to Magento
umask(0);
Mage::app();

// Variable init
global $defautStoreId;
global $frStoreId; 
global $statusChangedCount;
global $imagesUpdatedCount;
$relativePath = "../../../media/catalog/product/"; // path for the images
$defautStoreId = 0;
$frStoreId = 1; //check in magento admin
$statusChangedCount = 0;
$imagesUpdatedCount = 0;
$start = time();
echo "Store ID : ".$frStoreId."\n<br />\n";

//this builds a collection that's analagous to 
//select * from products where image = 'no_selection'
$products = Mage::getModel('catalog/product')
    ->setStoreId($frStoreId)
    ->getCollection()
    ->addAttributeToSelect('*')
    ->addAttributeToFilter('type_id', array("nlike" => "configurable")) // filter out configurable product
    ->addAttributeToFilter('status', array("eq" => 1)) // filter out configurable product
    ->addAttributeToFilter('visibility', array("eq" => 4)) // filter in visible product
    // ->addAttributeToFilter('sku', array("eq" => 32501634)) //ID product for debug
    ->addAttributeToFilter(
        array(
            array (
            'attribute' => 'image',
            'like' => 'no_selection'
            ),
            array(
                'attribute' => 'image',
                'null' => '1'
            ),
            array(
                'attribute' => 'small_image',
                'null' => '1'
            ),
            array(
                'attribute' => 'thumbnail',
                'null' => '1'
            ),
            array(
                'attribute' => 'image',
                'nlike' => '%/%/%'
            ),
            array(
                'attribute' => 'small_image',
                'nlike' => '%/%/%'
            ),
            array(
                'attribute' => 'thumbnail',
                'nlike' => '%/%/%'
            )
        ),
        null,
        'left'
    );
echo "Total products : ".count($products)."\n<br />\n";
echo  "SKU;NOM;VISIBILITE;STATUS\n<br />\n";
foreach($products as $product)
{   
    //Loading product and gallery
    $product->load($product->getId());
    $mediaGallery = $product->getMediaGallery();
    //echo "<pre><xmp>".print_r($product->getData(), true)."</xmp></pre>\n<br />\n"; //uncomment to see all product attributes
    echo  $product->getSku() . ";".$product->getName().";".$product->getVisibility().";".$product->getStatus()."\n<br />\n";
    // echo  $product->getImage() . ";<pre><xmp>".print_r($mediaGallery, true)."</xmp></pre>\n<br />\n";
    if ($mediaGallery["images"] == NULL) {
        disableProduct($product->getId(), $product->getSku());
    } else {
        $mediaAttribute = array (
            'image',
            'thumbnail',
            'small_image'                  
        );
        // getting the path of the first image
        $filepath_to_image = $relativePath.$mediaGallery["images"][0]["file"];
        // add image to gallery and 
        try {
            $product->addImageToMediaGallery($filepath_to_image, $mediaAttribute, true, false);
            echo "Product #".$product->getSku()." image added to gallery.\n<br />\n";
            $imagesUpdatedCount++;
        } catch(Exception $e) {
            //If exception caught, disable product
            echo "Product #".$product->getSku()." Error while adding image :".$e->getMessage()."\n<br />\n";
            disableProduct($product->getId(), $product->getSku());
        }
    }
    // save the product
    try {
        $product->save();
        echo "Product #".$product->getSku()." : saved\n<br />\n";
    } catch ( Exception $e ) {
        echo "Product #".$product->getSku()." could not be saved: ".$e->getMessage();
    }                    
} 
echo "Total status changed : ".$statusChangedCount."\n<br />\n";
echo "Total images updated : ".$imagesUpdatedCount."\n<br />\n";
$end = time();  
echo "Elapsed time : ".($end-$start)." seconds";
// Disable function
function disableProduct($productId, $productSku) {
    global $defautStoreId;
    global $frStoreId; 
    global $statusChangedCount;
    try {
            Mage::getModel('catalog/product_status')->updateProductStatus($productId, $frStoreId, Mage_Catalog_Model_Product_Status::STATUS_DISABLED);
            Mage::getModel('catalog/product_status')->updateProductStatus($productId, $defautStoreId, Mage_Catalog_Model_Product_Status::STATUS_DISABLED);
            echo "Product #".$productSku." Status changed.\n<br />\n";
            $statusChangedCount++;
    } catch(Exception $e) {
            echo "Product #".$productSku." Status could not be changed: ".$e->getMessage()."\n<br />\n";
    }
}
?>

I think I can improve it especially for the disable part function and the addImageToMedia part. But no time for this anymore.

Another precision, when I tested this on 1200 product, I got an 500 internal server error. Only 30 products has not been processed. You may want add a limitation to 1000 products to run it correctly.

Related Topic