【问题标题】:Get Product Media Gallery Images from a Product Collection in Magento从 Magento 中的产品集合中获取产品媒体库图像
【发布时间】:2011-12-14 23:49:09
【问题描述】:

我在 Magento 中有一系列产品,我希望能够从中获取媒体库图像。但是我发现我必须遍历我的收藏并再次加载产品才能使 getMediaGalleryImages() 函数正常工作。

$products = Mage::getModel('catalog/product')
    ->getCollection()
    ->addAttributeToSelect('*')
    ->addAttributeToFilter('visibility', 4)
    ->addAttributeToFilter('status', 1);

foreach($products as $product) {
    $_product = Mage::getModel('catalog/product')->load($product->getId());

    $product->getMediaGalleryImages();      // This returns nothing
    $_product->getMediaGalleryImages();     // Returns the Collection of Images
}

显然我可以继续每次只重新加载产品,但这会增加运行此代码所需的时间的相当多的开销。

有没有办法将媒体库图像添加到集合中?

【问题讨论】:

标签: php magento


【解决方案1】:

你可以使用

$product->load('media_gallery');

在 getMediaGalleryImages 之前(在您加载到集合中的产品上)。

【讨论】:

  • 奇怪的是,这行得通。魔法发生在 Mage_Eav_Model_Entity_Abstract->load($object, $entityId, $attributes)。如果 $attributes 为空,它将调用 loadAllAttribute($object)。所以 $product->load('blah') 会加载所有缺失的属性,包括'media_gallery'
  • 那么这会加载单个产品吗?如果是这样,那么将其用于大量产品是禁止的,并且会抵消使用集合的好处。
  • 魔术!有效。如果您在产品图片上传的某个地方使用,请确保在使用之前保存产品。
  • 是的,这会加载整个产品,所以这个答案是完全错误的,原因有两个:1. 很明显,加载整个产品你也会得到媒体库,2. 函数加载的使用方式错误
【解决方案2】:

一个简单的方法供将来参考:

在你的 foreach 之外添加

$mediaBackend = Mage::getModel('catalog/product_attribute_backend_media');
$mediaGalleryAttribute = Mage::getModel('eav/config')->getAttribute(Mage::getModel('catalog/product')->getResource()->getTypeId(), 'media_gallery');
$mediaBackend->setAttribute($mediaGalleryAttribute);

然后做foreach:

foreach ($productCollection as $product) {
    $mediaBackend->afterLoad($product);
}

您将在产品上加载图库。

【讨论】:

    【解决方案3】:

    通过以下代码使用集合加载产品的缓存图像

    Mage::helper('catalog/image')->init($_product, 'small_image')->resize(135);
    

    //或

    Mage::helper('catalog/image')->init($_product, 'thumbnail')->resize(135);
    

    //或

    Mage::helper('catalog/image')->init($_product, 'image')->resize(135);
    

    这是我使用的集合

    $collection = Mage::getModel('catalog/product')->getCollection()
            ->addAttributeToSelect('small_image') //or
            ->addAttributeToSelect('thumbnail')  //or
            ->addAttributeToSelect('image');
    

    【讨论】:

    • 这不会加载媒体库,而只会加载 3 个主图像(小图像、拇指图像、主图像)
    【解决方案4】:

    您可以创建一个帮助类,并在每次需要为产品集合加载媒体库图像时使用它:

    class My_Package_Helper_Media extends Mage_Core_Helper_Abstract {
        public function addMediaGalleryAttributeToProductCollection( &$productCollection )
        {
            $storeId = Mage::app()->getStore()->getId();
    
            $ids = array();
            foreach ( $productCollection as $product ) {
                $ids[] = $product->getEntityId();
            }
    
            $resource = Mage::getSingleton( 'core/resource' );
            $conn = Mage::getSingleton( 'core/resource' )->getConnection( 'catalog_read' );
            $select = $conn->select()
                ->from(
                       array( 'mg' => $resource->getTableName( 'catalog/product_attribute_media_gallery' ) ),
                       array(
                             'mg.entity_id', 'mg.attribute_id', 'mg.value_id', 'file' => 'mg.value',
                             'mgv.label', 'mgv.position', 'mgv.disabled',
                             'label_default' => 'mgdv.label',
                             'position_default' => 'mgdv.position',
                             'disabled_default' => 'mgdv.disabled'
                             )
                       )
                ->joinLeft(
                           array( 'mgv' => $resource->getTableName( 'catalog/product_attribute_media_gallery_value' ) ),
                           '(mg.value_id=mgv.value_id AND mgv.store_id=' . $storeId . ')',
                           array()
                           )
                ->joinLeft(
                           array( 'mgdv' => $resource->getTableName( 'catalog/product_attribute_media_gallery_value' ) ),
                           '(mg.value_id=mgdv.value_id AND mgdv.store_id=0)',
                           array()
                           )
                ->where( 'entity_id IN(?)', $ids );
    
            $mediaGalleryByProductId = array();
    
            $stmt = $conn->query( $select );
            while ( $gallery = $stmt->fetch() ) {
                $k = $gallery[ 'entity_id' ];
                unset( $gallery[ 'entity_id' ] );
                if ( !isset($mediaGalleryByProductId[$k]) ) {
                    $mediaGalleryByProductId[$k] = array();
                }
                $mediaGalleryByProductId[$k][] = $gallery;
            }
            unset( $stmt ); // finalize statement
    
            // Updating collection ...
            foreach ( $productCollection as &$product ) {
                $productId = $product->getEntityId();
                if ( isset( $mediaGalleryByProductId[ $productId ] ) ) {
                    $product->setData( 'media_gallery', array( 'images' => $mediaGalleryByProductId[ $productId ] ) );
                }
            }
            unset( $mediaGalleryByProductId );
        }
    }
    

    示例用法:

    $coll = Mage::getResourceModel('catalog/product_collection')
        ->setStoreId( Mage::app()->getStore()->getId() )
        ->addAttributeToFilter( 'sku', array( 'in' => array( 'AAA', 'BBB' ) ) );
    Mage::helper('my_package/media')->addMediaGalleryAttributeToProductCollection( $coll );
    

    【讨论】:

      【解决方案5】:

      这里是你要找的代码,抱歉耽搁了:)

      它来自这个讨论: http://www.magentocommerce.com/boards/viewthread/17414/

      我刚刚对 id a 的数量和分页添加了一些额外的检查

      function addMediaGalleryAttributeToCollection(Mage_Catalog_Model_Resource_Product_Collection $_productCollection)
      {
          if (Mage::getStoreConfig('color_selector_plus/colorselectorplusgeneral/showonlist', Mage::app()->getStore())) {
      
              $_mediaGalleryAttributeId = Mage::getSingleton('eav/config')->getAttribute('catalog_product', 'media_gallery')->getAttributeId();
              $_read = Mage::getSingleton('core/resource')->getConnection('catalog_read');
      
              $pageCur = $_productCollection->getCurPage();
              $pageSize = $_productCollection->getPageSize();
              $offset = $pageSize * ($pageCur - 1);
      
              $ids = $_productCollection->getAllIds($pageSize, $offset);
      
              // added check on products number: if 0 ids the following query breaks
              if (count($ids) > 0) {
      
                  $sql = '
          SELECT
              main.entity_id, `main`.`value_id`, `main`.`value` AS `file`, `value`.`disabled`,
              /*`value`.`label`, `value`.`position`, */
             /*`default_value`.`label` AS `label_default`, */
             /*`default_value`.`position` AS `position_default`, */
              `default_value`.`disabled` AS `disabled_default`
          FROM `catalog_product_entity_media_gallery` AS `main`
              LEFT JOIN `catalog_product_entity_media_gallery_value` AS `value`
                  ON main.value_id=value.value_id AND value.store_id=' . Mage::app()->getStore()->getId() . '
              LEFT JOIN `catalog_product_entity_media_gallery_value` AS `default_value`
                  ON main.value_id=default_value.value_id AND default_value.store_id=0
          WHERE (
              main.attribute_id = ' . $_read->quote($_mediaGalleryAttributeId) . ')
              AND (main.entity_id IN (' . $_read->quote($_productCollection->getAllIds()) . '))
          /*ORDER BY IF(value.position IS NULL, default_value.position, value.position) ASC */
      ';
                  $_mediaGalleryData = $_read->fetchAll($sql);
      
      
                  $_mediaGalleryByProductId = array();
                  foreach ($_mediaGalleryData as $_galleryImage) {
                      $k = $_galleryImage['entity_id'];
                      unset($_galleryImage['entity_id']);
                      if (!isset($_mediaGalleryByProductId[$k])) {
                          $_mediaGalleryByProductId[$k] = array();
                      }
                      $_mediaGalleryByProductId[$k][] = $_galleryImage;
                  }
                  unset($_mediaGalleryData);
                  foreach ($_productCollection as &$_product) {
                      $_productId = $_product->getData('entity_id');
                      if (isset($_mediaGalleryByProductId[$_productId])) {
                          $_product->setData('media_gallery', array('images' => $_mediaGalleryByProductId[$_productId]));
                      }
                  }
                  unset($_mediaGalleryByProductId);
              }
          }
          return $_productCollection;
      }
      

      【讨论】:

      • 注意与标签和默认值相关的信息已在查询中注释
      • 我正在扩展一个扩展,以便我们可以在 Magento 主页上展示产品,我想知道我可以在哪里实现此代码,以便我们可以load a product's gallery images with the collection at homepage。不确定我们是否必须将此函数添加到模型中或从模板文件中运行。
      • 你可以覆盖这个类 Mage_Catalog_Block_Product_List ...或将它放在与你的模板相关的任何类中......你只需要将集合传递给它,它应该可以完成工作......投票总是受欢迎的;)
      • 我同意,无论如何它可以工作并且加载产品更快。 (我很惊讶这个答案被否决了,而至少有 2 个答案完全错误但得分很高)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-30
      • 1970-01-01
      相关资源
      最近更新 更多