2

I've built an image importer (due to some custom requirements on image name matching SKUs) and in it, I delete all of a product's existing images before importing new ones. My code looks like this:

/* @var $mediaApi Mage_Catalog_Model_Product_Attribute_Media_Api */
$mediaApi = Mage::getModel("catalog/product_attribute_media_api");

$items = $mediaApi->items($product->getId());
foreach ($items as $item) {
    $mediaApi->remove($product->getId(), $item['file']);
}

This calls Mage_Catalog_Model_Product_Attribute_Media_Api::remove() which looks like this:

/**
 * Remove image from product
 *
 * @param int|string $productId
 * @param string $file
 * @return boolean
 */
public function remove($productId, $file, $identifierType = null)
{
    $product = $this->_initProduct($productId, null, $identifierType);

    $gallery = $this->_getGalleryAttribute($product);

    if (!$gallery->getBackend()->getImage($product, $file)) {
        $this->_fault('not_exists');
    }

    $gallery->getBackend()->removeImage($product, $file);

    try {
        $product->save();
    } catch (Mage_Core_Exception $e) {
        $this->_fault('not_removed', $e->getMessage());
    }

    return true;
}

The line $gallery->getBackend()->removeImage($product, $file); suggests that it deletes the image file, but if you look at Mage_Catalog_Model_Product_Attribute_Backend_Media::removeImage() you'll see that it doesn't:

/**
 * Remove image from gallery
 *
 * @param Mage_Catalog_Model_Product $product
 * @param string $file
 * @return Mage_Catalog_Model_Product_Attribute_Backend_Media
 */
public function removeImage(Mage_Catalog_Model_Product $product, $file)
{
    $attrCode = $this->getAttribute()->getAttributeCode();

    $mediaGalleryData = $product->getData($attrCode);

    if (!isset($mediaGalleryData['images']) || !is_array($mediaGalleryData['images'])) {
        return $this;
    }

    foreach ($mediaGalleryData['images'] as &$image) {
        if ($image['file'] == $file) {
            $image['removed'] = 1;
        }
    }

    $product->setData($attrCode, $mediaGalleryData);

    return $this;
}

Two questions:

  1. Is there any normal Magento situation where a product's image is used in more than one place? (The CMS and WYSIWYG image tools don't let you link to product images that I know of.)
  2. Before I go building a custom solution to delete unused images from the media directory, I want to make sure: Should I be expecting Magento to delete these images for me? From the code that I can find, it doesn't attempt to do that.
2

Magento is notoriously sloppy with it's files, nothing gets cleaned up. And you're right, there's only one place the files get used, with that product.

So you can remove them. But instead of using a module running a cron once per week or so is a much cleaner solution in my opinion.

Below a nice bash script that will do the cleaning up (source)

#!/bin/bash

LOG=var/log/del_unused_img.log

function search_db() {
    COUNT=$(mysql -uYOURUSER -pYOURPASSWORD YOURDB --execute="SELECT count(*) FROM catalog_product_entity_media_gallery WHERE value = \"$1\"")
    echo $(echo ${COUNT} | cut -d" " -f2)
}
echo "Start: "\n >> ${LOG}
echo $(date) >> ${LOG}
for IMG in $(find media/catalog/product/ -name '*.jpg' ! -path '*cache*' ! -name 'google*'); do
    # search in db
    if [ $(search_db ${IMG/'media/catalog/product'/}) != 1 ]; then
        IMG=${IMG##*/}
        for CACHE_IMG in $(find media/catalog/product/ -name "${IMG}"); do
            echo "${CACHE_IMG}" >> ${LOG}
            rm "${CACHE_IMG}"
        done
    fi
done
echo "End: "\n >> ${LOG}
echo $(date) >> ${LOG}
  • Magento doesn't do windows, dusting or vacuuming. <grin> Notorious bloatage: unused image files, expired quotes that haven't been converted to sales orders, effective cache garbage collection, etc. And if you ever are unlucky enough to have a system where PHP doesn't do cleanup on session files... neither does Magento. – Fiasco Labs Jun 23 '15 at 4:57
  • @FiascoLabs I know, I know.... but still we love here. She's just a bit lazy. Still, the community has come up with solutions and with a little tweaking a shop can run without too much garbage – Sander Mangel Jun 23 '15 at 6:52
  • Why does this explicitly avoid clearing files from the cache directory? – Tyler V. Dec 23 '15 at 2:09
  • @TylerV. because those can, and should be flushed using either a cron or the button in the backend. I've encountered issue where it removed incorrect cached versions – Sander Mangel Dec 23 '15 at 16:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.