Magento 2 Rest Api get URL immagine miniature


12

Come ottenere l'URL dell'immagine in miniatura di un prodotto tramite l'API di riposo.

/V1/products/{sku}/media ci procurerebbe l'URL relativo come "/m/b/mb01-blue-0.jpg"

e l'URL dell'immagine sarebbe baseurl/catalog/product/m/b/mb01-blue-0.jpg

Funziona benissimo. Ma come possiamo ottenere la miniatura che di solito risiede nella cartella cache.


Tale funzionalità non è pronta all'uso. Dovrai scrivere un'API personalizzata.
Sinisa Nedeljkovic,

Risposte:


10

Se è necessario il percorso completo dell'immagine di anteprima con il sistema cache Magento 2 tramite API, è possibile creare l'API personalizzata in base alla classe ProductRepository nativa.

Crea un nuovo modulo. (spiegato in altri post)

Creare un file etc / webapi.xml :

<?xml version="1.0"?>
<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Webapi:etc/webapi.xsd">
    <route url="/V1/custom/products/{sku}" method="GET">
        <service class="Vendor\ModuleName\Api\ProductRepositoryInterface" method="get"/>
        <resources>
            <resource ref="Magento_Catalog::products"/>
        </resources>
    </route>
</routes>

Creare un file etc / di.xml :

<?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Vendor\ModuleName\Api\ProductRepositoryInterface" type="Vendor\ModuleName\Model\ProductRepository" />
</config>

Crea la tua interfaccia Api \ ProductRepositoryInterface.php :

namespace Vendor\ModuleName\Api;

/**
 * @api
 */
interface ProductRepositoryInterface
{
    /**
     * Get info about product by product SKU
     *
     * @param string $sku
     * @param bool $editMode
     * @param int|null $storeId
     * @param bool $forceReload
     * @return \Magento\Catalog\Api\Data\ProductInterface
     * @throws \Magento\Framework\Exception\NoSuchEntityException
     */
    public function get($sku, $editMode = false, $storeId = null, $forceReload = false);
}

Crea il tuo modello Model \ ProductRepository.php :

namespace Vendor\ModuleName\Model;


class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterface
{
    /**
     * @var \Magento\Catalog\Model\ProductFactory
     */
    protected $productFactory;

    /**
     * @var Product[]
     */
    protected $instances = [];

    /**
     * @var \Magento\Catalog\Model\ResourceModel\Product
     */
    protected $resourceModel;

    /**
     * @var \Magento\Store\Model\StoreManagerInterface
     */
    protected $storeManager;

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

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

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


    /**
     * {@inheritdoc}
     */
    public function get($sku, $editMode = false, $storeId = null, $forceReload = false)
    {
        $cacheKey = $this->getCacheKey([$editMode, $storeId]);
        if (!isset($this->instances[$sku][$cacheKey]) || $forceReload) {
            $product = $this->productFactory->create();

            $productId = $this->resourceModel->getIdBySku($sku);
            if (!$productId) {
                throw new NoSuchEntityException(__('Requested product doesn\'t exist'));
            }
            if ($editMode) {
                $product->setData('_edit_mode', true);
            }
            if ($storeId !== null) {
                $product->setData('store_id', $storeId);
            } else {
                // Start Custom code here

                $storeId = $this->storeManager->getStore()->getId();
            }
            $product->load($productId);

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

            $imageUrl = $this->getImage($product, 'product_thumbnail_image')->getUrl();

            $customAttribute = $product->setCustomAttribute('thumbnail', $imageUrl);

            $this->appEmulation->stopEnvironmentEmulation();

            // End Custom code here

            $this->instances[$sku][$cacheKey] = $product;
            $this->instancesById[$product->getId()][$cacheKey] = $product;
        }
        return $this->instances[$sku][$cacheKey];
    }

    /**
     * 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(75, 75);

        return $image;
    }

}

Accesso

Vai a /rest/V1/custom/products/{sku}

Dovresti recuperare l'immagine in miniatura con l'URL del frontend dell'immagine memorizzato nella cache:

<custom_attributes>
    <item>
        <attribute_code>thumbnail</attribute_code>
        <value>http://{domain}/media/catalog/product/cache/1/thumbnail/75x75/e9c3970ab036de70892d86c6d221abfe/s/r/{imageName}.jpg</value>
    </item>
</custom_attributes>

Commenti :

Il terzo parametro della funzione startEnvironmentEmulation viene utilizzato per forzare l'uso dell'area frontend se si è già nello stesso storeId. (utile per l'area API)

Non testare questa API personalizzata, è possibile adattare il codice ma la logica è corretta ma ho già testato la parte per recuperare l'URL dell'immagine in un'altra API personalizzata.

Questa soluzione alternativa ti evita di avere questo tipo di errori:

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'

Penso che questo potrebbe funzionare meglio con \Magento\Catalog\Api\ProductRepositoryInterfaceFactoryinvece di \Magento\Catalog\Model\ProductFactory, poiché puoi chiamare direttamente get()l' productRepositryoggetto con lo SKU. Almeno, è quello che sto usando ora.
Thaddeusmt,

Non incoraggiamo a fornire la propria ProductRepositoryInterface, perché ce n'è una fornita dal modulo Catalog. E supponiamo che personalizzerai quello esistente, se necessario. Perché idealmente tutti i client che dipendono dal ProductRepositoryInterface del catalogo non dovrebbero essere interessati dalla modifica. Esistono due possibili soluzioni per il problema di currect: 1. Aggiungi URL come parte di ProductInterface come attributo di estensione 2. Introduzione al servizio di risoluzione URL dedicato. La prima soluzione non si adatta all'attuale architettura del contratto di servizio, poiché questo attributo dovrebbe essere di sola lettura.
Igor Minyaylo,

In effetti, questa risposta è di mettere in evidenza una possibile soluzione a questo problema. La soluzione migliore è aggiungere un servizio di risoluzione URL dedicato e basarsi sull'API del catalogo nativo.
Franck Garnier,

ciao @franck Garnier sto ricevendo un errore come mostrato in questo screenshot prntscr.com/g5q4ak come risolvere per favore suggeriscimi grazie?
Nagaraju K

L'errore è esplicito, la funzione non esiste. Ti faccio solo un esempio di codice, ma devi adattarlo alle tue esigenze. Ad esempio implementa la funzione getCacheKey come qui:vendor/magento/module-catalog/Model/ProductRepository.php:258
Franck Garnier

2

I motivi per cui Magento non fornisce questa funzionalità pronta all'uso sono i seguenti:

  • Restituire l'URL dell'anteprima dell'immagine come parte del Prodotto con attributo o attributo di estensione che significherà introdurre il supporto degli attributi di sola lettura (non modificabili) negli oggetti dati. Perché l'URL è una rappresentazione di alcuni dati. Dati presi da fonti diverse, poiché il nome dominio appartiene alla configurazione del sistema, ma il percorso appartiene al modulo Catalogo.
  • Per ora Magento non supporta gli attributi di sola lettura o il servizio per l'API Query.

Come soluzione a lungo termine - Le API di query dovrebbero rispondere a questa domanda, poiché forniranno la possibilità di campi di sola lettura e calcolati. Come soluzione potremmo fornire il tempo più vicino alla community - potremmo implementare / introdurre un servizio di risoluzione URL dedicato che restituirà l'URL per tipi di entità specifici (come Prodotto, Categoria, Immagine ecc.)

Per lo stesso motivo non forniamo l'URL del prodotto come parte di ProductInterface

Ecco la mia risposta dedicata a questo problema (URL del prodotto): https://community.magento.com/t5/Programming-Questions/Retrieving-the-product-URL-for-the-current-store-from-a/mp / 55387 / luce / true # M1400


1
Quando sarà disponibile un servizio di risoluzione URL di questo tipo?
Franck Garnier,

La risposta è del 2017. Da allora è stato aggiunto questo in Magenta 2.1.x 2.2.xo 2.3.x?
Marcus Wolschon,

1

Dovrebbe essere possibile con il seguente URL: /rest/V1/products/{sku}

Questo restituirà il prodotto e dovrebbe esserci un nodo per custom_attributes che contiene un link di anteprima

<custom_attributes>
    <item>
        <attribute_code>thumbnail</attribute_code>
        <value>/m/b/mb01-blue-0.jpg</value>
    </item>
</custom_attributes>

cache / 1 / thumbnail / 88x110 / beff4985b56e3afdbeabfc89641a4582 / m / b / mb02-blue-0.jpg questa è la posizione della miniatura. c'è un modo per ottenerlo?
Mohammed Shameem,

/ V1 / products / {sku} / media e / rest / V1 / products / {sku} danno lo stesso risultato che il primo fornisce ai media da solo e il successivo fornisce anche tutte le altre informazioni.
Mohammed Shameem,

@MohammedShameem hai trovato una soluzione funzionante?
Torayeff,

@torayeff non ancora. Immagino che dovrò scriverne uno. Hai qualche suggerimento?
Mohammed Shameem,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.