【问题标题】:Magento programmatically remove product imagesMagento 以编程方式删除产品图片
【发布时间】:2011-04-18 22:10:28
【问题描述】:

这一定是一个如此简单的编程任务,我在网上绝对找不到任何关于它的信息。基本上,我正在尝试删除产品图片。我想从产品的媒体库中删除所有图像。对于这样一个简单的任务,我可以不费力地完成一百万行代码吗?

请注意,我已经尝试过了:

$attributes = $product->getTypeInstance()->getSetAttributes();
if (isset($attributes['media_gallery'])) {
    $gallery = $attributes['media_gallery'];
    $galleryData = $product->getMediaGallery();//this returns NULL

    foreach($galleryData['images'] as $image){
        if ($gallery->getBackend()->getImage($product, $image['file'])) {
            $gallery->getBackend()->removeImage($product, $image['file']);
        }
    }
}

这绝对行不通。我试图在导入过程中删除图像,这样我就不会不断累积重复。任何帮助将不胜感激。

【问题讨论】:

  • stackoverflow.com/questions/5328763/… 看起来与您已经拥有的代码相同,但可能会提供一些见解,您是否确保 media/ 可访问?
  • 您能否提供一些错误消息或其他信息来帮助调试它为什么不工作?
  • Boomer,我的 /media/catalog 目录在树下的模式为 777。
  • 乔纳森,问题是 $product->getMediaGallery() 会返回 NULL,即使有媒体库和图像。甚至 $product->getImage() 也会返回一个图像。自 1.4 版以来,一定发生了一些变化。
  • Mage::getModel('catalog/product')->load($id)->getMediaGallery() 对我来说似乎工作正常。您是否正确加载了产品?

标签: image magento product


【解决方案1】:

好的,这就是我最终解决问题的方法。

if ($product->getId()){
    $mediaApi = Mage::getModel("catalog/product_attribute_media_api");
    $items = $mediaApi->items($product->getId());
    foreach($items as $item)
        $mediaApi->remove($product->getId(), $item['file']);
}

这是最终让我清醒的链接:http://www.magentocommerce.com/wiki/doc/webservices-api/api/catalog_product_attribute_media

可惜它不像 $product->getImages() 这么简单,嗯?

【讨论】:

  • 我真的可以用这个,请问我们必须在哪个文件中输入这个代码? if ($product->getId()){ $mediaApi = Mage::getModel("catalog/product_attribute_media_api"); $items = $mediaApi->items($product->getId()); foreach($items as $item) $mediaApi->remove($product->getId(), $item['file']); }
  • 以上代码用于自定义模块。你需要一个有特定任务的程序员使用上面的代码来完成。
  • 快速提示:如果商店对象的 ID 未设置为管理商店的 id ("0"),则现代版本的 Magento 不会让您以编程方式保存产品。如果您在前端商店上下文中使用上述内容,请务必先致电 Mage::app()->getStore()->setId(Mage_Core_Model_App::ADMIN_STORE_ID);
  • @Colin Tickle 的答案是对我有用的解决方案,这是在某些添加产品自动集成中其他解决方案不足的地方。
【解决方案2】:

在 Magento 1.7.0.2 中,我使用此代码从产品库中删除所有图像:

//deleting
Mage::app()->getStore()->setId(Mage_Core_Model_App::ADMIN_STORE_ID);
$mediaApi = Mage::getModel("catalog/product_attribute_media_api");
$items = $mediaApi->items($product->getId());
$attributes = $product->getTypeInstance()->getSetAttributes();
$gallery = $attributes['media_gallery'];
foreach($items as $item){
    if ($gallery->getBackend()->getImage($product, $item['file'])) {
        $gallery->getBackend()->removeImage($product, $item['file']);
    }
}
$product->save();

使用 Davids Tay 回答的代码,我得到了错误: 致命错误:未捕获的异常 'Mage_Eav_Model_Entity_Attribute_Exception' 带有消息 'SQLSTATE[23000]:完整性约束违规:1452 无法添加或更新子行:外键约束失败(base_xxx.catalog_product_entity_media_gallery_value,CONSTRAINT FK_CAT_PRD_ENTT_MDA_GLR_VAL_VAL_ID_CAT_PRD_ENTT_MDA_GLR_VAL_ID FOREIGN KEY( value_id) 参考 `catalog_prod)'

【讨论】:

    【解决方案3】:

    要从产品库中删除所有图片:

    $product = Mage::getModel('catalog/product')->load($id);
    $mediaGalleryAttribute = Mage::getModel('catalog/resource_eav_attribute')->loadByCode($entityTypeId, 'media_gallery');
    $gallery = $product->getMediaGalleryImages();
    foreach ($gallery as $image)
        $mediaGalleryAttribute->getBackend()->removeImage($product, $image->getFile());
    $product->save();
    

    【讨论】:

    • $entityTypeId = Mage::getModel('eav/entity')->setType('catalog_product')->getTypeId();
    • 或者只是:$entityTypeId = $product->getEntityTypeId();对于那些仍在阅读本主题的人 =)
    • @Pihtt 你也可以用 Mage_Catalog_Model_Product::ENTITY 替换“catalog_product”
    【解决方案4】:

    在删除图像的过程中,我发现了一件有趣的事情。当您尝试此代码时:

    $galleryData = $product->getMediaGallery(); //this returns NULL
    

    媒体库对象取决于您的产品是如何创建的,如果:

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

    如果满足以下条件,则媒体库将为空:

    $product = Mage::getModel('catalog/product')->load($id);
    

    然后媒体库是对象,您可以使用此对象从数据库中删除图像。 要从文件系统中删除图像,您必须添加这样的代码:

    @unlink(Mage::getBaseDir('media') . '\catalog\product\' . $image['file']);
    

    但是如果您想更改图像并将其命名为以前的图像(image1.png 替换为 image1.png),在这种情况下您将遇到浏览器缓存问题。

    您也可以尝试为产品加载媒体库:

    $product->getResource()->getAttribute('media_gallery')->getBackend()->afterLoad($product);
    

    【讨论】:

    • 图像将被删除,但图像的数据库条目仍然存在
    【解决方案5】:

    这是我最终决定用于此任务的代码。

    protected function _removeMediaGalleryImages(Mage_Catalog_Model_Product $product)
    {
        $mediaGalleryData = $product->getMediaGallery();
        if (!isset($mediaGalleryData['images']) || !is_array($mediaGalleryData['images'])) {
            return;
        }
    
        $toDelete = array();
        foreach ($mediaGalleryData['images'] as $image) {
            $toDelete[] = $image['value_id'];
        }
        Mage::getResourceModel('catalog/product_attribute_backend_media')->deleteGallery($toDelete);
    }
    

    【讨论】:

    • 您能解释一下发生了什么变化以及您是如何做到的吗?
    • 这对我来说效果很好,而且它没有使用任何“api 调用”类型的黑客攻击,而且是合乎逻辑的。
    • 我在循环中添加了一行删除图像文件:unlink(Mage::getBaseDir('media') . DS . 'catalog' . DS . 'product' . $image['file']);
    【解决方案6】:

    希望这个答案不是不受欢迎的,因为从技术上讲,它不是您所要求的通过 Magento 编程实现的解决方案,但我已经成功地自己清除了所有画廊图像,只需在 Magento 1.4.2.0 中截断相关表格(我相信它在 1.5 中也是相同的表结构)。

    TRUNCATE TABLE `catalog_product_entity_media_gallery`
    TRUNCATE TABLE `catalog_product_entity_media_gallery_value`
    

    然后删除 /media/catalog/product 目录中的所有图像文件。

    我自己确实在寻找一种以编程方式执行此操作的方法,但发现这种方法效率更高,并且没有遇到任何负面影响。

    【讨论】:

    • 真的截断了吗?在重度相关数据结构上,这只会为未来的麻烦而尖叫,因为 truncate 将您的增量 id-s 设置为 0 并从此时起期望错误的数据关系。 DELETE 是你正在寻找的那个。
    • CVM,哈哈,我只需要从特定产品中删除图像,而不是清除我的整个目录。
    • 在 TRUNCATE 上完全理解了这一点,我确实想到了这一点。但是,在检查这些表与产品的关系时,它们引用了产品实体 ID,但至关重要的是,其他产品表没有引用任何图库 ID。所以他们的移除是安全的。 @David,我稍后会用代码破解这个问题,看看能不能找到答案。
    【解决方案7】:
         Just use this code to create .php file and place it to root folder of magento.
    
        <?php 
        require_once 'app/Mage.php';
    
        Mage::app();
        Mage::app()->getStore()->setId(Mage_Core_Model_App::ADMIN_STORE_ID);
    
        $products = Mage::getModel('catalog/product')->getCollection();
          //->addAttributeToFilter('entity_id', array('gt' => 14000));
    
        $mediaApi = Mage::getModel("catalog/product_attribute_media_api");
    
        foreach($products as $product) {
            $prodID = $product->getId();
            $_product = Mage::getModel('catalog/product')->load($prodID);
            $items = $mediaApi->items($_product->getId());
            foreach($items as $item) {
                $mediaApi->remove($_product->getId(), $item['file']);
            }
        }
    ?>
    

    【讨论】:

      【解决方案8】:

      这个呢

      Mage::app()->getStore()->setId(Mage_Core_Model_App::ADMIN_STORE_ID);
          $mediaApi = Mage::getModel("catalog/product_attribute_media_api");
          $items = $mediaApi->items($product->getId());
          $attributes = $product->getTypeInstance()->getSetAttributes();
          $gallery = $attributes['media_gallery'];
          foreach($items as $item){
              if ($gallery->getBackend()->getImage($product, $item['file'])) {
                  $gallery->getBackend()->removeImage($product, $item['file']);
              }
          }
          $product->save();
      

      【讨论】:

        【解决方案9】:

        删除图像的最快方法,然后按照以下步骤操作: 删除所有记录

        1. catalog_product_entity_media_gallery
        2. catalog_product_entity_media_gallery_value'

        表,因为 magento 将所有产品图像数据保存在这些表中。

        然后从管理员的索引管理中索引设置图像黑色。

        然后删除图像from dir,然后转到media/catalog/product 的magento 目录,并从该文件夹中删除所有文件。

        另一个进程:

        Andy Simpson,您需要一个脚本,该脚本来自您的系统,is delete all productdelete from DB and file system

        第一步:root direct of magento system创建a php,其中包括Mage.php at first code

        require_once "YOURMAGENTODIR/app/Mage.php";
        umask(0);
        

        第二步:设置current store isadmin并设置开发者模式

        Mage::app('admin');
        Mage::setIsDeveloperMode(true);
        

        第3步:获取Product Collection并创建一个循环获取一件一件的产品

        $productCollection=Mage::getResourceModel('catalog/product_collection');
        

        第4步:使用以下代码逐一张获取产品图片并删除图片一:

        $remove=Mage::getModel('catalog/product_attribute_media_api')->remove($product->getId(),$eachImge['file']);
        

        完整代码:

        <?php
        require_once "YOURMAGENTODIR/app/Mage.php";
        umask(0);
        Mage::app('admin');
        Mage::setIsDeveloperMode(true);
        
        $productCollection=Mage::getResourceModel('catalog/product_collection');
        foreach($productCollection as $product){
        echo $product->getId();
        echo "<br/>";
                 $MediaDir=Mage::getConfig()->getOptions()->getMediaDir();
                echo $MediaCatalogDir=$MediaDir .DS . 'catalog' . DS . 'product';
        echo "<br/>";
        
        $MediaGallery=Mage::getModel('catalog/product_attribute_media_api')->items($product->getId());
        echo "<pre>";
        print_r($MediaGallery);
        echo "</pre>";
        
            foreach($MediaGallery as $eachImge){
                $MediaDir=Mage::getConfig()->getOptions()->getMediaDir();
                $MediaCatalogDir=$MediaDir .DS . 'catalog' . DS . 'product';
                $DirImagePath=str_replace("/",DS,$eachImge['file']);
                $DirImagePath=$DirImagePath;
                // remove file from Dir
        
                $io     = new Varien_Io_File();
                 $io->rm($MediaCatalogDir.$DirImagePath);
        
                $remove=Mage::getModel('catalog/product_attribute_media_api')->remove($product->getId(),$eachImge['file']);
            }
        
        
        }
        

        【讨论】:

          【解决方案10】:

          如果您想删除更多产品,例如 1000 或 5000,请使用带有直接查询的底部产品。

          在尝试这个之前备份你的数据库

          <?php
          require_once 'app/Mage.php';
          umask(0);
          Mage::app();
          set_time_limit(0);
          ini_set('display_error','1');
          
          
          $resource = Mage::getSingleton('core/resource');
          $connection = $resource->getConnection('core_write');
          
          $id = 101;
          $product = Mage::getModel('catalog/product')->load($id);
          
          $q = "DELETE FROM `catalog_product_entity_media_gallery` where entity_id = '".$product->getId()."'"; 
          
          $connection->query($q);
          
          ?>
          

          【讨论】:

            【解决方案11】:

            为此类事情访问数据库是个坏主意。 您可以在自定义模块中使用以下 sn-p 删除图像(或通过更改“位置”值重新排序)(为简单起见,我使用 ObjectManager,但您应该将 ProductFactory 和 ProductRepositoryInterface 放在构造函数中)

            $objectManager = ObjectManager::getInstance();
            
            //Get ProductFactory in order to instatiate the Product Object 
            $productFactory = $objectManager->get('\Magento\Catalog\Model\ProductFactory');
            
            //We have to use ProductRepositoryInterface in order to save the changes bellow to the product
            $productRepository = $objectManager->get('\Magento\Catalog\Api\ProductRepositoryInterface');
            
            //Load a Product by ID in this case 1
            $product = $productFactory->create()->load(1);
            
            //Gets an array containing arrays representing each image in the gallery
            $mediaGalleryEntries = $product->getMediaGalleryEntries();
            
            //Here we delete every image, you can use conditions in foreach
            foreach ($mediaGalleryEntries as $key => $imageEntry) {
                unset($mediaGalleryEntries[$key]);
            }
            
            //Finally set the altered entries and save using productRepository
            $product->setMediaGalleryEntries($mediaGalleryEntries);
            $productRepository->save($product);
            

            上面的代码在 Magento 2.3 中进行了测试,它还从文件系统中删除了图像。您可以使用它来删除或更改条目(更改位置、图像角色等)

            要查看每个 imageEntry,您可以使用 $imageEntry->getData() 访问其数据

            【讨论】:

              【解决方案12】:

              不久前我不得不做类似的事情 - 需要在导入期间替换所有产品图片。

              这个链接很有帮助:http://www.sharpdotinc.com/mdost/2010/03/02/magento-import-multiple-images-or-remove-images-durring-batch-import/

              希望它能帮助你朝着正确的方向前进。

              【讨论】:

                【解决方案13】:
                DELETE FROM catalog_product_entity_media_gallery WHERE value_id NOT IN (SELECT * FROM (SELECT MIN(value_id) FROM `catalog_product_entity_media_gallery` GROUP BY LEFT(value,17), entity_id  having count(*) > 1) x)
                

                为什么是 17 岁?

                你有这样重复的例子:

                /0/0/000116810609_1.jpg

                /0/0/000116810609_2.jpg

                /0/0/000116810609_3.jpg

                /0/0/000116810609_4.jpg

                LEFT(value,17)
                

                /0/0/000116810609

                /0/0/000116810609

                /0/0/000116810609

                /0/0/000116810609

                不,它们是重复的;)

                【讨论】:

                【解决方案14】:

                将下面的脚本放在magento root并执行

                 <?php
                
                  require_once("app/Mage.php");
                  umask(0);
                   Mage::app();
                   $ob = new Clean();
                   $ob->removemedia();
                
                 Class Clean {
                
                 function removemedia() {
                $read = Mage::getSingleton('core/resource')->getConnection('core_read');
                $select = $read->select()
                        ->from('catalog_product_entity_media_gallery', '*')
                        ->group(array('value_id'));
                
                $flushImages = $read->fetchAll($select);
                echo count($flushImages);
                $array = array();
                foreach ($flushImages as $item1) {
                    $array[] = $item1['value'];
                }
                
                $valores = $array;
                
                $pepe = 'media' . DS . 'catalog' . DS . 'product';
                
                $leer = $this->listDirectories($pepe);
                
                foreach ($leer as $item) {
                    try {
                        $item = strtr($item, '\\', '/');
                        if (!in_array($item, $valores)) {
                            $valdir[]['filename'] = $item;
                            unlink('media/catalog/product' . $item);
                        }
                    } catch (Zend_Db_Exception $e) {
                
                    } catch (Exception $e) {
                        //Mage::log($e->getMessage());
                    }
                  }
                 }
                
                function listDirectories($path) {
                    if (is_dir($path)) {
                       if ($dir = opendir($path)) {
                        while (($entry = readdir($dir)) !== false) {
                            if (preg_match('/^\./', $entry) != 1) {
                                if (is_dir($path . DS . $entry) && !in_array($entry, array('cache', 'watermark'))) {
                                    $this->listDirectories($path . DS . $entry);
                                } elseif (!in_array($entry, array('cache', 'watermark')) && (strpos($entry, '.') != 0)) {
                                    $this->result[] = substr($path . DS . $entry, 21);
                                }
                            }
                        }
                        closedir($dir);
                    }
                 }
                 return $this->result;
                 }
                
                  }
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2011-12-11
                  • 1970-01-01
                  • 1970-01-01
                  • 2023-03-18
                  • 2022-06-22
                  • 2016-03-14
                  相关资源
                  最近更新 更多