Magento 2 Rest Api รับ url Image Thumbnail


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 ที่กำหนดเอง
Sinisa Nedeljkovic

คำตอบ:


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ใช้เพื่อบังคับใช้พื้นที่ส่วนหน้าหากคุณอยู่ใน storeId เดียวกันอยู่แล้ว (มีประโยชน์สำหรับพื้นที่ 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วัตถุที่มีรหัสโดยตรง อย่างน้อยนั่นคือสิ่งที่ฉันใช้ตอนนี้
thaddeusmt

เราไม่สนับสนุนให้มี ProductRepositoryInterface ของตนเองเนื่องจากมีโมดูลที่จัดทำโดยโมดูลแคตตาล็อก และเราสมมติว่าคุณจะกำหนดค่าที่มีอยู่เดิมหากจำเป็น เนื่องจากเป็นการดีที่ลูกค้าทั้งหมดซึ่งขึ้นอยู่กับ ProductRepositoryInterface ของแค็ตตาล็อกจึงไม่ได้รับผลกระทบจากการเปลี่ยนแปลงของคุณ มีวิธีแก้ไขที่เป็นไปได้สองวิธีสำหรับการแก้ไขปัญหา: 1. เพิ่ม URL เป็นส่วนหนึ่งของ ProductInterface เป็นแอตทริบิวต์ส่วนขยาย 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

เหตุผลที่วีโอไอพีไม่ได้จัดเตรียมฟังก์ชั่นนี้ให้ใช้งานอยู่ในกล่องถัดไป:

  • ในการส่งคืน URL ภาพขนาดย่อเป็นส่วนหนึ่งของผลิตภัณฑ์ที่มีแอตทริบิวต์หรือแอตทริบิวต์ส่วนขยายที่จะแนะนำการสนับสนุนแอตทริบิวต์อ่านอย่างเดียว (ไม่สามารถแก้ไขได้) ใน Data Objects เนื่องจาก URL เป็นตัวแทนของข้อมูลบางอย่าง ข้อมูลที่นำมาจากแหล่งที่แตกต่างกันเนื่องจากชื่อโดเมนเป็นของการกำหนดค่าระบบ แต่เส้นทางเป็นของโมดูลแคตตาล็อก
  • ตอนนี้ Magento ไม่สนับสนุนคุณลักษณะหรือบริการแบบอ่านอย่างเดียวสำหรับ Query API

ในฐานะที่เป็นทางออกระยะยาว - Query APIs ควรตอบคำถามนี้เนื่องจากพวกเขาจะให้ความสามารถสำหรับฟิลด์แบบอ่านอย่างเดียวและแบบคำนวณ เป็นวิธีการแก้ปัญหาที่เราสามารถมอบให้กับชุมชนในเวลาที่ใกล้ที่สุด - เราสามารถใช้ / แนะนำบริการตัวแก้ไข URL เฉพาะซึ่งจะส่งคืน URL สำหรับประเภทเอนทิตีที่เฉพาะเจาะจง (เช่นผลิตภัณฑ์หมวดหมู่รูปภาพ ฯลฯ )

ด้วยเหตุผลเดียวกันเราไม่ได้ให้ URL ผลิตภัณฑ์เป็นส่วนหนึ่งของ ProductInterface

นี่คือการตอบสนองของฉันเกี่ยวกับปัญหานี้ (URL ผลิตภัณฑ์): https://community.magento.com/t5/Programming-Questions/Retrieving-the-product-URL-for-the-current-store-from-a/mp / 55387 / ไฮไลท์ / จริง # 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.