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?

Alex
la source
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.

Fabian Schmengler
la source
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'
Franck Garnier
la source
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();
Hùng Thế Hiển
la source
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();
Shihas Suliaman
la source
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 ...

tassleoff
la source
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();
Abhinav Singh
la source
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) ?>"/>
Jack Rose
la source
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

mrtuvn
la source
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

WebArtisan
la source
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();
    }
Miguel
la source
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>';
}
Dhaval
la source
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.

Milan Simek
la source
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(); ?>
Baharuni Asif
la source