REST APIを使用して、製品のサムネイル画像へのURLを取得する方法を教えてください。
/V1/products/{sku}/media
次のような相対URLを取得します "/m/b/mb01-blue-0.jpg"
画像のURLは baseurl/catalog/product/m/b/mb01-blue-0.jpg
これは正常に機能します。しかし、通常はキャッシュフォルダーにあるサムネイルをどのように取得しますか。
REST APIを使用して、製品のサムネイル画像へのURLを取得する方法を教えてください。
/V1/products/{sku}/media
次のような相対URLを取得します "/m/b/mb01-blue-0.jpg"
画像のURLは baseurl/catalog/product/m/b/mb01-blue-0.jpg
これは正常に機能します。しかし、通常はキャッシュフォルダーにあるサムネイルをどのように取得しますか。
回答:
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の3番目のパラメーターは、同じ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>