답변:
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/placeholder/.jpg'
\Magento\Catalog\Api\ProductRepositoryInterfaceFactory
대신에 더 잘 작동 할 수 있다고 생각합니다 . 적어도, 그것은 내가 지금 사용하고있는 것입니다. \Magento\Catalog\Model\ProductFactory
get()
productRepositry
vendor/magento/module-catalog/Model/ProductRepository.php:258
Magento가이 기능을 기본적으로 제공하지 않는 이유는 다음과 같습니다.
장기 솔루션 – 쿼리 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
다음 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>