Obtention de l'URL d'image complète du produit dans le modèle


23

J'essaie de créer un bloc statique pour afficher des produits dynamiques. Ce code est censé obtenir chaque catégorie enfant et imprimer l'image de chaque produit dans chaque catégorie.

<?php
    $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
    $category = $objectManager->get('Magento\Framework\Registry')->registry('current_category');
    ?><ol><?php
    foreach ($category->getChildrenCategories() as $child_category) {
        ?><li>
            <ul><?php
                foreach ($child_category->getProductCollection() as $product) {
                    ?><li><img src="<?php echo $product->getImage();?>"/><li><?php
                }
            ?></ul>
        </li><?php
    }
    ?></ol>

Il fonctionne presque sauf que les img srcs ne sont que "/a/b/ab001.jpg" à titre d'exemple et non le chemin complet par exemple "/ pub / media / catalog / product / cache / 1 / small_image / 240x300 / abc123def456 / a / b / 001.jpg "afin que les images ne soient pas trouvées. Quelle est la bonne façon d'obtenir des images de produits?


1
N'essayez pas d'utiliser le gestionnaire d'objets directement sur votre modèle. Nous devons créer un nouveau bloc ou réutiliser les fonctions existantes.
Khoa TruongDinh

Réponses:


28

Si votre bloc s'étend Magento\Catalog\Block\Product\AbstractProduct, vous pouvez utiliser:

$imageType = 'category_page_list'; // choose which image
$image = $block->getImage($product, $imageType);

Ensuite, obtenez l'URL de l'image avec

$image->getImageUrl();

ou si vous voulez le sortir comme <img>élément:

echo $image->toHtml();

Si votre bloc ne prolonge pas / ne peut pas étendre le bloc de produit abstrait, vous pouvez créer vous-même une getImage()méthode:

public function getImage($product, $imageId)
{
    return $this->imageBuilder->setProduct($product)
        ->setImageId($imageId)
        ->create();
}

$this->imageBuilder doit être injecté comme Magento\Catalog\Block\Product\ImageBuilder


Les variables $imageTypeou $imageIddoivent être l'un des types d'images définis dans le thème, par exemple category_page_list.

Voir app/design/frontend/Magento/luma/etc/view.xmlpour tous les types d'images dans le thème Luma, par exemple.

Dans Magento 2, ces types d'images sont utilisés au lieu de définir la largeur et la hauteur directement dans le modèle.


J'essaie votre code mais Uncaught Magento\Framework\View\Asset\File\NotFoundException: Unable to resolve the source file for 'adminhtml/_view/en_US/Magento_Catalog/images/product/placeholder/.jpg'
j'obtiens

@ ND17 deux questions: 1) utilisez-vous le bloc dans la zone d'administration? Ce code est destiné uniquement à l'interface 2) avez-vous configuré une image d'espace réservé? Si ce n'est pas le cas et qu'un produit n'a pas d'image, vous obtiendrez toujours des erreurs
Fabian Schmengler

1
@davideghz l'un des types d'images définis dans le thème, par exemple category_page_list. Voir: github.com/magento/magento2/blob/… dans Magento 2, vous les utilisez au lieu de définir la largeur et la hauteur directement dans le modèle
Fabian Schmengler

3
Une idée de pourquoi cela ramènerait l'espace réservé au lieu de l'image assignée?
Laura

2
J'ai le même problème que @Laura. Il renvoie toujours l'image d'espace réservé au lieu de l'image attribuée (l'image affectée est parfaitement visible dans la liste des produits ou la page de détails du produit générique sinon).
fritzmg

9

Si vous devez redimensionner l'image du produit et utiliser le système de cache d'image Magento par défaut et que vous n'êtes pas dans la zone frontend, vous pouvez utiliser cette solution de contournement.

Cas d'utilisation: il peut être utile si vous avez besoin de redimensionner les URL des images sur votre API personnalisée pour une application externe.

Code de fonction:

/**
 * @var \Magento\Catalog\Model\ProductFactory
 */
protected $productFactory;

/**
 * @var \Magento\Catalog\Helper\ImageFactory
 */
protected $helperFactory;

/**
 * @var \Magento\Store\Model\App\Emulation
 */
protected $appEmulation;

/**
 * Constructor.
 *
 * @param \Magento\Catalog\Model\ProductFactory $productFactory
 * @param \Magento\Store\Model\App\Emulation $appEmulation
 * @param \Magento\Catalog\Helper\ImageFactory $helperFactory
 * @param \Magento\Store\Model\StoreManagerInterface $storeManager
 */
public function __construct(
    \Magento\Catalog\Model\ProductFactory $productFactory,
    \Magento\Store\Model\App\Emulation $appEmulation,
    \Magento\Catalog\Helper\ImageFactory $helperFactory,
    \Magento\Store\Model\StoreManagerInterface $storeManager,
) {
    $this->productFactory                   = $productFactory;
    $this->imageBuilder                     = $imageBuilder;
    $this->helperFactory                    = $helperFactory;
    $this->appEmulation                     = $appEmulation;
    $this->storeManager                     = $storeManager;
}

/**
 * Retrieve product image
 *
 * @param \Magento\Catalog\Model\Product $product
 * @param string $imageId
 * @param array $attributes
 * @return \Magento\Catalog\Block\Product\Image
 */
public function getImage($product, $imageId, $attributes = [])
{
    $image = $this->helperFactory->create()->init($product, $imageId)
        ->constrainOnly(true)
        ->keepAspectRatio(true)
        ->keepTransparency(true)
        ->keepFrame(false)
        ->resize(200, 300);

    return $image;
}

public function customFunction()
{
    // some stuff here

    $storeId = $this->storeManager->getStore()->getId();

    $this->appEmulation->startEnvironmentEmulation($storeId, \Magento\Framework\App\Area::AREA_FRONTEND, true);

    $product = $this->productFactory->create()->loadByAttribute('sku', 'productSKU');
    $imageUrl = $this->getImage($product, 'product_base_image')->getUrl();

    echo $imageUrl;

    $this->appEmulation->stopEnvironmentEmulation();

    // some stuff here
}

L'exemple de sortie:

http://{domain}/media/catalog/product/cache/1/image/200x300/e9c3970ab036de70892d86c6d221abfe/s/r/{imageName}.jpg

Commentaires :

Le troisième paramètre de la fonction startEnvironmentEmulation est utilisé pour forcer l'utilisation de la zone frontend si vous êtes déjà sur le même storeId. (utile pour la zone API)

Cette solution de contournement vous évite d'avoir ce type d'erreurs:

http://XXXX.com/pub/static/webapi_rest/_view/en_US/Magento_Catalog/images/product/placeholder/.jpg

Uncaught Magento\Framework\View\Asset\File\NotFoundException: Unable to resolve the source file for 'adminhtml/_view/en_US/Magento_Catalog/images/product/placeh‌​older/.jpg'

1
Merci pour le conseil sur l'émulation de l'environnement, juste ce dont j'avais besoin.
thaddeusmt

2
L'émulation de l'environnement m'a sauvé la journée. Merci beaucoup!
medina

+1 pour l'utilité de l'API
tony

8

Essayez-le

$store = $objectManager->get('Magento\Store\Model\StoreManagerInterface')->getStore();
$imageUrl = $store->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA) . 'catalog/product' . $product->getImage();

1
Celui-ci est bon car il donnera automatiquement l'URL sécurisée / non sécurisée selon la demande actuelle
Milan Simek

3

Essayez ce code ..

$ProductImageUrl = $block->getUrl('pub/media/catalog').'product'.$_product->getImage();

Bienvenue dans Magento SE. Les réponses qui ne contiennent qu'une seule ligne de code ne sont souvent pas très utiles. Dans ce cas, il est relativement clair comment cette ligne est censée être utilisée, mais l'utilisation getUrl()n'est pas la bonne façon même si elle peut fonctionner accidentellement. Il prend un $routeparamètre sous la forme "module / contrôleur / action". "pub / media / catalog" ressemble à un itinéraire, mais ne l'est pas.
Fabian Schmengler

N'utilise pas le gestionnaire d'objets, bonne réponse. Même si une seule ligne.
LM_Fielding

@LM_Fielding Toutes les réponses qui n'utilisent pas le gestionnaire d'objets ne sont pas automatiquement bonnes.
Fabian Schmengler

Essayez ce code et postez votre commentaire
Shihas Suliaman

1

Peut Magento\Catalog\Helper\Product::getImageUrl()- être pourrait aider. Je ne comprends pas pourquoi les développeurs de Magento ne l'ont pas implémenté en Magento\Catalog\Helper\Imageclasse car la getUrlméthode dans l'image helper ne retourne pas ce à quoi on pourrait s'attendre ...


1

Veuillez essayer ce code:

$prdId = 35;
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$hotPrd = $objectManager->get('Magento\Catalog\Model\Product')->load($prdId);
$store = $objectManager->get('Magento\Store\Model\StoreManagerInterface')->getStore();
echo $store->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA) . 'catalog/product' . $hotPrd->getThumbnail();

1

Vous pouvez utiliser ObjectManager ou Block.

Gestionnaire d'objets:

$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$store = $objectManager->get('Magento\Store\Model\StoreManagerInterface')->getStore();
$imageUrl = $store->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA) . 'catalog/product' . $product->getImage();

Bloquer:

protected $_storeManagerInterface;

public function __construct(
  ...
  \Magento\Store\Model\StoreManagerInterface $storeManagerInterface,
  ...
)
{
  ...
  $this->_storeManagerInterface = $storeManagerInterface;
  ...
}

...

public function getStoreInterface($imgUrl){
   $store = $this->_storeManagerInterface->getStore();
   $storeMedia = $store->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA) . 'catalog/product' . $imgUrl;
   return $storeMedia;
}
...

Appelez la fonction:

<img src="<?php echo $block->getStoreInterface($imgUrl) ?>"/>

0

Essayez ce code

<img class="test-image" alt="image" src="<?php echo $block->getUrl('pub/media/catalog/product', ['_secure' => $block->getRequest()->isSecure()]).$product->getImage();?>" />

J'espère que ceci vous aidera


Ceci ajoute un src de " domain.com/pub/media/catalog//a/b/ab001.jpg " qui ne peut pas non plus être trouvé
Alex

Manque le répertoire du produit.
LM_Fielding

0

Dans votre module:

public function getProducts()
{
    //... create collection code goes here...

    $result = [ ];

    foreach ( $collection as $product ) {
        $result[] = [
            'id'        => $product->getId(),
            '_sku'      => $product->getSku(),
            'permalink' => $product->getProductUrl($product),
            'title'     => $product->getName(),
            'raw_price' => $product->getPrice(),
            'image_url' => $this->getUrl().'pub/media/catalog/product'.$product->getImage()
        ];
    }

    return $result;
}

Ensuite, dans votre bloc, vous obtiendrez ce résultat:

print_r($block->getProducts());

Eh bien, ce n'est pas parfait, mais ça marche pour moi.

Jetez un œil au résultat: entrez la description de l'image ici


0

Dans votre classe, injectez la dépendance StoreManagerInterface comme:

use \Magento\Framework\View\Element\Template\Context;
use \Magento\Store\Model\StoreManagerInterface;

public function __construct(Context $context, StoreManagerInterfac $storeManager)
    {
        parent::__construct($context);
        $this->_storeManager = $storeManager;

    }

après dans votre méthode, pour obtenir la vignette par exemple

public function getProductThumbnail(){

        return $this->_storeManager->getStore()->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA) . 'catalog/product' . $product->getImage();
    }

0

Vous pouvez essayer ce code ci-dessous.

$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$category = $objectManager->get('Magento\Framework\Registry')->registry('current_category');
$childcategories = $category->getChildrenCategories();

foreach($childcategories as $child)
    {
echo '<li class="sub-cat">';
        $cat = $objectManager->create('Magento\Catalog\Model\Category')->load($child->getId()); 
        ?>
        <a href="<?php echo $cat->getUrl(); ?>">
        <div class="sub-title">
            <h3><?php echo $cat->getName();?></h3>
        </div> 
    <?php
        if ($_imgUrl = $cat->getImageUrl())
        {
            $_imgHtml = '<div class="category-image"><img src="' . $_imgUrl . '" alt="' . $block->escapeHtml($cat->getName()) . '" title="' . $block->escapeHtml($cat->getName()) . '" class="image" /></div>';
            $_imgHtml = $_helper->categoryAttribute($cat, $_imgHtml, 'image');
            /* @escapeNotVerified */ echo $_imgHtml;
        }  

    ?>      
    <?php echo '</a></li>'; }
    echo '</ul>';
}

0

Ceci est une autre méthode de travail:

/** @var \Magento\Framework\UrlInterface $urlManager */
$url = $urlManager->getDirectUrl('pub/media/catalog/product' . $product->getImage());

Ou en respectant l'URL sécurisée / non sécurisée en fonction de la demande actuelle:

/** @var \Magento\Framework\UrlInterface $urlManager */
/** @var \Magento\Framework\App\RequestInterface $request */
$url = $urlManager->getDirectUrl(
    'pub/media/catalog/product' . $product->getImage(),
    ['_secure' => $request->isSecure()]
);

Je vais laisser l'instanciation de l'objet à votre imagination.


0

Nous pouvons obtenir l'URL de l'image de base dans un fichier phtml

$_objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$imageHelper  = $_objectManager->get('\Magento\Catalog\Helper\Image');
<?php $image_url = $imageHelper->init($product, 'product_base_image')->setImageFile($product->getFile())->resize($imagewidth, $imageheight)->getUrl(); ?>
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.