Saltar al contenido

Magento 2 Rest Api obtener la URL de la imagen en miniatura

Solución:

Si necesita la ruta completa de la imagen en miniatura con el sistema de caché Magento 2 a través de API, puede crear su API personalizada basada en la clase nativa ProductRepository.

Crea un nuevo módulo. (explicado en otras publicaciones)

Crear un etc / webapi.xml expediente :

<?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="VendorModuleNameApiProductRepositoryInterface" method="get"/>
        <resources>
            <resource ref="Magento_Catalog::products"/>
        </resources>
    </route>
</routes>

Crear un etc / di.xml expediente :

<?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="VendorModuleNameApiProductRepositoryInterface" type="VendorModuleNameModelProductRepository" />
</config>

Crea tu interfaz Api ProductRepositoryInterface.php :

namespace VendorModuleNameApi;

/**
 * @api
 */
interface ProductRepositoryInterface
{
    /**
     * Get info about product by product SKU
     *
     * @param string $sku
     * @param bool $editMode
     * @param int|null $storeId
     * @param bool $forceReload
     * @return MagentoCatalogApiDataProductInterface
     * @throws MagentoFrameworkExceptionNoSuchEntityException
     */
    public function get($sku, $editMode = false, $storeId = null, $forceReload = false);
}

Crea tu modelo Modelo ProductRepository.php :

namespace VendorModuleNameModel;


class ProductRepository implements MagentoCatalogApiProductRepositoryInterface
{
    /**
     * @var MagentoCatalogModelProductFactory
     */
    protected $productFactory;

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

    /**
     * @var MagentoCatalogModelResourceModelProduct
     */
    protected $resourceModel;

    /**
     * @var MagentoStoreModelStoreManagerInterface
     */
    protected $storeManager;

    /**
     * @var MagentoCatalogHelperImageFactory
     */
    protected $helperFactory;

    /**
     * @var MagentoStoreModelAppEmulation
     */
    protected $appEmulation;

    /**
     * ProductRepository constructor.
     * @param MagentoCatalogModelProductFactory $productFactory
     * @param MagentoCatalogModelResourceModelProduct $resourceModel
     * @param MagentoStoreModelStoreManagerInterface $storeManager
     */
    public function __construct(
        MagentoCatalogModelProductFactory $productFactory,
        MagentoCatalogModelResourceModelProduct $resourceModel,
        MagentoStoreModelStoreManagerInterface $storeManager,
        MagentoStoreModelAppEmulation $appEmulation,
        MagentoCatalogHelperImageFactory $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, MagentoFrameworkAppArea::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 MagentoCatalogModelProduct $product
     * @param string $imageId
     * @param array $attributes
     * @return MagentoCatalogBlockProductImage
     */
    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;
    }

}

Acceso

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

Debe recuperar la imagen en miniatura con la URL de la interfaz de la imagen en caché:

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

Comentarios:

El tercer parámetro de la función startEnvironmentEmulation se usa para forzar el uso del área de frontend si ya está en el mismo storeId. (útil para el área de API)

No pruebo esta API personalizada, puede adaptar el código pero la lógica es correcta, pero ya probé la parte para recuperar la URL de la imagen en otra API personalizada.

Esta solución te evita tener este tipo de errores:

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

Uncaught MagentoFrameworkViewAssetFileNotFoundException: Unable to resolve the source file for 'adminhtml/_view/en_US/Magento_Catalog/images/product/placeh‌​older/.jpg'

Las razones por las que Magento no proporciona esta funcionalidad de fábrica son las siguientes:

  • Devolver la URL de la miniatura de la imagen como parte del producto con atributo o atributo de extensión significará introducir compatibilidad con atributos de solo lectura (no modificables) en los objetos de datos. Porque URL es una representación de algunos datos. Datos tomados de diferentes fuentes, ya que el nombre de dominio pertenece a la configuración del sistema, pero la ruta pertenece al módulo Catálogo.
  • Por ahora, Magento no admite atributos de solo lectura o servicios para la API de consultas.

Como solución a largo plazo, las API de consulta deben abordar esta pregunta, ya que proporcionarán la capacidad para campos computados y de solo lectura. Como una solución que podríamos proporcionar a la comunidad en el momento más cercano, podríamos implementar / introducir un servicio de resolución de URL dedicado que devolverá la URL para tipos de entidad específicos (como Producto, Categoría, Imagen, etc.)

Por la misma razón, no proporcionamos la URL del producto como parte de ProductInterface

Aquí está mi respuesta dedicada a este problema (URL del producto): https://community.magento.com/t5/Programming-Questions/Retrieving-the-product-URL-for-the-current-store-from-a/mp / 55387 / highlight / true # M1400

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *