Magento 2 Rest Api dapatkan url Gambar Mini

12

Bagaimana cara kami mendapatkan url ke gambar kecil suatu produk melalui API lainnya.

/V1/products/{sku}/media akan memberi kami url relatif seperti "/m/b/mb01-blue-0.jpg"

dan url gambar akan menjadi baseurl/catalog/product/m/b/mb01-blue-0.jpg

Ini berfungsi dengan baik. Tetapi bagaimana kita mendapatkan thumbnail yang biasanya berada di folder cache.

Mohammed Shameem
sumber
Tidak ada fungsi seperti itu di luar kotak. Anda harus menulis API khusus.
Sinisa Nedeljkovic

Jawaban:

10

Jika Anda memerlukan jalur lengkap gambar mini dengan sistem cache Magento 2 melalui API, Anda dapat membuat API khusus berdasarkan kelas ProductRepository asli.

Buat modul baru. (dijelaskan dalam posting lain)

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

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

Buat antarmuka Anda 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);
}

Buat model Anda 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;
    }

}

Mengakses

Pergi ke /rest/V1/custom/products/{sku}

Anda harus mengambil gambar mini dengan URL frontend gambar di-cache:

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

Komentar:

Parameter ketiga dari fungsi startEnvironmentEmulation digunakan untuk memaksa penggunaan area frontend jika Anda sudah menggunakan storeId yang sama. (berguna untuk area API)

Saya tidak menguji API khusus ini, Anda dapat mengadaptasi kode tetapi logikanya benar tetapi saya sudah menguji bagian tersebut untuk mengambil URL gambar di API khusus lainnya.

Solusi ini menghindarkan Anda dari kesalahan seperti ini:

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'
Franck Garnier
sumber
Saya pikir kekuatan ini bekerja lebih baik dengan \Magento\Catalog\Api\ProductRepositoryInterfaceFactorybukan \Magento\Catalog\Model\ProductFactory, karena Anda dapat menghubungi get()di productRepositryobjek dengan SKU langsung. Setidaknya, itulah yang saya gunakan sekarang.
thaddeusmt
Kami tidak menganjurkan untuk menyediakan ProductRepositoryInterface sendiri, karena ada satu yang disediakan oleh modul Katalog. Dan kami kira Anda akan menyesuaikan yang sudah ada jika diperlukan. Karena idealnya semua klien yang bergantung pada ProductRepositoryInterface Katalog tidak boleh terpengaruh dengan perubahan Anda. Ada dua kemungkinan solusi untuk masalah arus: 1. Tambahkan URL sebagai bagian dari ProductInterface sebagai atribut ekstensi 2. Perkenalkan layanan penyelesai URL khusus. Solusi pertama tidak sesuai dengan arsitektur kontrak Layanan saat ini, karena atribut ini harus hanya-baca.
Igor Minyaylo
Memang, jawaban ini adalah untuk membuktikan kemungkinan penyelesaian masalah ini. Solusi terbaik adalah menambahkan layanan penyelesai URL khusus dan berdasarkan pada API katalog asli.
Franck Garnier
hai @ franck Garnier saya mendapatkan kesalahan seperti yang ditunjukkan pada screenshot ini prntscr.com/g5q4ak bagaimana cara mengatasinya tolong sarankan saya terima kasih?
Nagaraju K
Kesalahan Anda eksplisit, fungsi tidak ada. Saya hanya memberi Anda contoh kode, tetapi Anda harus menyesuaikannya dengan kebutuhan Anda. Misalnya mengimplementasikan fungsi getCacheKey seperti di sini:vendor/magento/module-catalog/Model/ProductRepository.php:258
Franck Garnier
2

Alasan mengapa Magento tidak menyediakan fungsionalitas ini di luar kotak adalah sebagai berikut:

  • Untuk mengembalikan URL gambar mini gambar sebagai bagian dari Produk dengan atribut atau atribut ekstensi yang berarti memperkenalkan dukungan atribut Read-Only (non-modifiable) di Objek Data. Karena URL adalah representasi dari beberapa data. Data diambil dari sumber yang berbeda, karena nama domain milik konfigurasi sistem, tetapi path milik modul Katalog.
  • Untuk saat ini Magento tidak mendukung atribut baca-saja atau layanan untuk API Kueri.

Sebagai solusi jangka panjang - API Kueri harus menjawab pertanyaan ini, karena mereka akan memberikan kemampuan untuk bidang yang hanya dapat dibaca dan dikomputasi. Sebagai solusi yang dapat kami sediakan untuk waktu terdekat komunitas - kami dapat mengimplementasikan / memperkenalkan layanan penyelesai URL khusus yang akan mengembalikan URL untuk jenis entitas tertentu (seperti Produk, Kategori, Gambar dll.)

Untuk alasan yang sama, kami tidak menyediakan URL Produk sebagai bagian dari ProductInterface

Berikut tanggapan saya yang ditujukan untuk masalah ini (URL Produk): https://community.magento.com/t5/Programming-Questions/Retrieving-the-product-URL-for-the-current-store-from-a/mp / 55387 / highlight / true # M1400

Igor Minyaylo
sumber
1
Kapan layanan penyelesai URL semacam itu akan tersedia di luar kotak?
Franck Garnier
Jawabannya adalah dari 2017. Apakah ini telah ditambahkan di Magenta 2.1.x 2.2.x atau 2.3.x sejak saat itu?
Marcus Wolschon
1

Seharusnya dimungkinkan dengan url berikut: /rest/V1/products/{sku}

Ini akan mengembalikan produk dan harus ada simpul untuk custom_attributes yang berisi tautan thumbnail

<custom_attributes>
    <item>
        <attribute_code>thumbnail</attribute_code>
        <value>/m/b/mb01-blue-0.jpg</value>
    </item>
</custom_attributes>
DanCarlyon
sumber
cache / 1 / thumbnail / 88x110 / beff4985b56e3afdbeabfc89641a4582 / m / b / mb02-blue-0.jpg ini adalah lokasi thumbnail. apakah ada cara untuk mendapatkan ini?
Mohammed Shameem
/ V1 / products / {sku} / media dan / rest / V1 / products / {sku} memberikan hasil yang sama dengan yang pertama memberikan media sendiri dan kemudian memberikan semua informasi lainnya juga.
Mohammed Shameem
@MohammedShameem sudahkah Anda menemukan solusi yang berfungsi?
torayeff
@torayeff belum. Saya kira harus menulis satu. Apakah Anda memiliki saran?
Mohammed Shameem