Magento 2 Repi Api отримати URL-адресу зображення ескізів


12

Як ми можемо отримати URL-адресу зображення на ескіз продукту за допомогою API відпочинку.

/V1/products/{sku}/media отримає нам відносну URL-адресу типу "/m/b/mb01-blue-0.jpg"

і URL-адреса зображення буде baseurl/catalog/product/m/b/mb01-blue-0.jpg

Це чудово працює. Але як нам отримати ескіз, який зазвичай знаходиться в папці кеша.


Немає такої функціональності поза коробкою. Вам доведеться написати спеціальний API.
Синіса Неделькович

Відповіді:


10

Якщо вам потрібен повний шлях мініатюрного зображення з кеш-системою Magento 2 через API, ви можете створити свій власний API на основі рідного класу ProductRepository.

Створіть новий модуль. (пояснено в інших публікаціях)

Створіть файл 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>

Створіть файл 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>

Створіть свій інтерфейс 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);
}

Створіть свою модель 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;
    }

}

Доступ

Йти до /rest/V1/custom/products/{sku}

Вам слід отримати мініатюрну картинку із кешованою URL-адресою фронтального зображення:

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

Коментарі:

Третій параметр функції startEnvironmentEmulation використовується для примусового використання області frontend, якщо ви вже в одному магазиніId. (корисно для області API)

Я не тестую цей користувальницький API, ви можете адаптувати код, але логіка правильна, але я вже тестував частину для отримання URL-адреси зображення в іншому спеціальному API.

Цей спосіб уникнути помилок:

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'

Я думаю, що це може працювати краще \Magento\Catalog\Api\ProductRepositoryInterfaceFactoryзамість цього \Magento\Catalog\Model\ProductFactory, оскільки ви можете зателефонувати get()на productRepositryоб'єкт безпосередньо за допомогою SKU. Принаймні, саме цим я зараз користуюся.
thaddeusmt

Ми не рекомендуємо надавати власний інтерфейс ProductRepositoryInterface, оскільки такий модуль надається каталогом. І ми припускаємо, що ви будете налаштовувати існуючий за потреби. Тому що в ідеалі всі клієнти, які залежать від ProductRepositoryInterface, не повинні впливати на вашу зміну. Існує два можливі рішення для правильної проблеми: 1. Додайте URL як частину ProductInterface як атрибут розширення 2. Інтубуйте спеціальну службу вирішення URL-адрес. Перше рішення не відповідає сучасній архітектурі контракту на надання послуг, оскільки цей атрибут повинен бути лише для читання.
Ігор Міняйло

Дійсно, ця відповідь полягає в тому, щоб довести можливе вирішення цього питання. Найкраще рішення - додати виділений сервіс для вирішення URL-адрес та на основі API рідного каталогу.
Франк Гарньє

привіт @franck Гарньє, я отримую помилку, як показано на цьому скріншоті prntscr.com/g5q4ak як вирішити, будь ласка, підкажіть мені спасибі?
Nagaraju K

У вас помилка явна, функція не існує. Я просто наводжу вам приклад коду, але вам потрібно адаптувати його до ваших потреб. Наприклад, реалізуйте таку функцію getCacheKey, як, наприклад, тут:vendor/magento/module-catalog/Model/ProductRepository.php:258
Франк Гарньє

2

Причини, через які Magento не надає цю функцію поза коробкою, наступні:

  • Повернути URL-адресу мініатюри зображень як частина продукту з атрибутом або атрибутом розширення, що означатиме запровадити підтримку атрибутів лише для читання (не змінюються) в об'єктах даних. Оскільки URL - це представлення деяких даних. Дані взяті з різних джерел, оскільки доменне ім’я належить до конфігурації системи, але шлях належить модулю Каталог.
  • Наразі Magento не підтримує атрибути чи сервіс для API запитів лише для читання.

Як довгострокове рішення - API запитів повинні вирішити це питання, оскільки вони нададуть можливість для редагування лише для читання та обчислених полів. Як рішення ми могли б запропонувати найближчий час для спільноти - ми могли б впровадити / запровадити спеціалізовану службу вирішення URL-адрес, яка поверне URL-адресу для певних типів сутності (наприклад, Продукт, Категорія, Зображення тощо)

З тієї ж причини ми не надаємо URL-адресу продукту як частину продукту

Ось моя відповідь, присвячена цій проблемі (URL-адреса продукту): https://community.magento.com/t5/Programming-Questions/Retrieving-the-product-URL-for-the-current-store-from-a/mp / 55387 / підсвітка / вірно # M1400


1
Коли така послуга вирішення URL-адрес буде доступна поза коробкою?
Франк Гарньє

Відповідь з 2017 року? Чи додано це в Magenta 2.1.x 2.2.x або 2.3.x?
Маркус Волшон

1

Це має бути можливо за допомогою наступного URL-адреси: /rest/V1/products/{sku}

Це поверне продукт і має бути вузол для custom_attributes, який містить мініатюрну посилання

<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 це розташування мініатюр. чи є спосіб це отримати?
Мохаммед Шайем

/ V1 / products / {sku} / media та / rest / V1 / products / {sku} дає такий же результат, коли перший дає медіа в поодинці, а пізній також надає всю іншу інформацію.
Мохаммед Шайем

@MohammedShameem Ви знайшли якесь робоче рішення?
torayeff

@torayeff ще немає Я думаю, що доведеться написати один. Чи є у вас якісь пропозиції?
Мохаммед Шамеем
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.