从 Magento 的产品集合中获取产品媒体库图像

8

我在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
}

显然,如果每次都重新加载产品,那么将会增加代码运行所需的开销。

是否有一种方法可以将媒体库图像添加到集合中?


你可以进行连接操作:mediagallerycollection -> join productcollection,其中productId在(id,id,id,id)中。由于每个产品通常有多张图片,因此您不能将它们简单地连接到productcollection中。 - Anton S
1
这个问题已经在另一个帖子中得到了回答:https://dev59.com/Fm025IYBdhLWcg3wnnYw - Tharsan
这个回答解决了你的问题吗?如何在加载集合时同时加载产品媒体库? - TylerH
5个回答

18

您可以使用

$product->load('media_gallery');

在加载的集合中,调用 getMediaGalleryImages 函数之前。


6
奇妙的是,这个方法有效。魔法发生在Mage_Eav_Model_Entity_Abstract->load($object, $entityId, $attributes)中。如果$attributes为空,它将调用loadAllAttribute($object)。因此,$product->load('blah')将加载所有缺失的属性,包括'media_gallery'。 - William Tran
2
那么这是否加载单个产品?如果是这样,那么对于大量的产品来说使用这种方法是禁止的,会抵消使用集合的好处。 - ahnbizcad
神奇!它起作用了。如果你正在使用它来上传产品图片,请确保在使用此功能之前先保存产品。 - Yash Patadia
1
是的,这会加载整个产品,因此这个答案完全错误,原因有两个:
  1. 显然,加载整个产品也会得到媒体库。
  2. 函数load的使用方式不正确。
- WonderLand

7

一个简单的方法供以后参考:

在您的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');

这只会加载三张主要图片(小图、缩略图和主图),而不会加载媒体库。 - WonderLand

1
你可以创建一个帮助类,并在每次需要为一组产品加载媒体库图像时使用它:
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数量和分页上添加了一些额外的检查。

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;
}

请注意,在查询中已经对标签和默认值相关信息进行了注释。 - WonderLand
我正在扩展一个扩展程序,以便我们可以在Magento首页上展示产品,并想知道我可以在哪里实现此代码,以便我们可以在主页上使用集合加载产品的图库图片。不确定是否必须将此函数添加到模型中或从模板文件运行。 - zigojacko
你可以覆盖这个类 Mage_Catalog_Block_Product_List… 或者将其放在与模板相关的任何类中… 你只需要将集合传递给它,它就应该能够胜任工作… 点赞永远受欢迎 ;) - WonderLand
我同意,反正它能够工作并且比加载产品更快。 (我很惊讶这个答案被踩了,而至少有两个完全错误但得分很高的答案) - WonderLand

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接