Magento 2 Rest Api 썸네일 이미지 URL 받기


12

나머지 API를 통해 URL을 제품의 썸네일 이미지로 가져 오는 방법은 무엇입니까?

/V1/products/{sku}/media 우리에게 상대 URL을 얻을 것입니다 "/m/b/mb01-blue-0.jpg"

이미지 URL은 baseurl/catalog/product/m/b/mb01-blue-0.jpg

이것은 잘 작동합니다. 그러나 일반적으로 캐시 폴더에있는 축소판을 얻는 방법은 무엇입니까?


기본적으로 그러한 기능은 없습니다. 사용자 정의 API를 작성해야합니다.
Sinisa Nedeljkovic

답변:


10

API를 통해 Magento 2 캐시 시스템에서 썸네일 이미지의 전체 경로가 필요한 경우 기본 ProductRepository 클래스를 기반으로 사용자 정의 API를 작성할 수 있습니다.

새 모듈을 작성하십시오. (다른 게시물에서 설명)

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 함수의 세 번째 매개 변수 는 이미 동일한 storeId에있는 경우 프론트 엔드 영역을 강제로 사용하는 데 사용됩니다. (API 영역에 유용)

이 사용자 정의 API를 테스트하지 않고 코드를 조정할 수 있지만 논리는 정확하지만 이미 다른 사용자 정의 API에서 이미지 URL을 검색하기 위해 파트를 테스트했습니다.

이 해결 방법은 이러한 종류의 오류가 발생하지 않도록합니다.

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'

SKU 를 사용하여 객체를 직접 호출 할 수 있기 때문에이 \Magento\Catalog\Api\ProductRepositoryInterfaceFactory대신에 더 잘 작동 할 수 있다고 생각합니다 . 적어도, 그것은 내가 지금 사용하고있는 것입니다. \Magento\Catalog\Model\ProductFactoryget()productRepositry
thaddeusmt

Catalog 모듈에서 제공하는 ProductRepositoryInterface가 있으므로 자체 ProductRepositoryInterface를 제공하지 않는 것이 좋습니다. 그리고 필요한 경우 기존 항목을 사용자 정의한다고 가정합니다. 카탈로그의 ProductRepositoryInterface에 의존하는 모든 클라이언트가 변경에 영향을 미치지 않아야하기 때문입니다. 올바른 문제에 대한 두 가지 가능한 솔루션이 있습니다. 1. 확장 속성으로 ProductInterface의 일부로 URL을 추가합니다. 2. 전용 URL 확인자 서비스를 도입합니다. 첫 번째 솔루션은 현재 서비스 계약 아키텍처에 맞지 않습니다.이 특성은 읽기 전용이어야하기 때문입니다.
Igor Minyaylo

실제로이 답변은이 문제에 대한 가능한 해결 방법을 증거로 제시하는 것입니다. 가장 좋은 솔루션은 전용 URL 확인자 서비스를 추가하고 기본 카탈로그 API를 기반으로하는 것입니다.
Franck Garnier

안녕하세요 @ franck Garnier이 스크린 샷과 같이 오류가 발생합니다 prntscr.com/g5q4ak 해결 방법 감사합니다.
Nagaraju K

오류가 명시 적이며 함수가 존재하지 않습니다. 코드 예제 만 제공하지만 필요에 맞게 코드를 조정해야합니다. 예를 들어 다음과 같은 getCacheKey 함수를 구현하십시오.vendor/magento/module-catalog/Model/ProductRepository.php:258
Franck Garnier

2

Magento가이 기능을 기본적으로 제공하지 않는 이유는 다음과 같습니다.

  • 데이터 객체에서 읽기 전용 (수정 불가능) 속성 지원을 의미하는 속성 또는 확장 속성이있는 제품의 일부로 이미지 축소판 URL을 반환합니다. URL은 일부 데이터를 나타 내기 때문입니다. 도메인 이름이 시스템 구성에 속하지만 경로가 카탈로그 모듈에 속하므로 다른 소스에서 가져온 데이터입니다.
  • 현재 Magento는 Query API에 대한 읽기 전용 특성 또는 서비스를 지원하지 않습니다.

장기 솔루션 – 쿼리 API는 읽기 전용 및 계산 필드에 대한 기능을 제공하므로이 질문을 해결해야합니다. 우리는 가장 가까운 시간에 커뮤니티를 제공 할 수있는 솔루션으로 특정 엔티티 유형 (제품, 카테고리, 이미지 등)의 URL을 리턴하는 전용 URL 리졸버 서비스를 구현 / 소개 할 수 있습니다.

같은 이유로 우리는 ProductInterface의 일부로 제품 URL을 제공하지 않습니다

다음은이 문제 (제품 URL)에 대한 답변입니다 : https://community.magento.com/t5/Programming-Questions/Retrieving-the-product-URL-for-the-current-store-from-a/mp / 55387 / highlight / true # M1400


1
그러한 URL 확인자 서비스는 언제부터 제공됩니까?
Franck Garnier

정답은 2017 년입니다. 이후 Magenta 2.1.x 2.2.x 또는 2.3.x에 추가 되었습니까?
Marcus Wolschon

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 썸네일 위치입니다. 이것을 얻는 방법이 있습니까?
Mohammed Shameem

/ V1 / products / {sku} / media 및 / rest / V1 / products / {sku}는 전자가 미디어 만 제공하는 것과 동일한 결과를 제공하고 나중에 다른 모든 정보도 제공합니다.
Mohammed Shameem

@MohammedShameem 작동하는 솔루션이 있습니까?
torayeff

@torayeff는 아직 없습니다. 하나 써야 할 것 같아요. 당신은 어떤 제안이 있습니까?
Mohammed Shameem
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.