jak zapisać niestandardowy atrybut obrazu w Magento 2

13

podgląd w backend

podgląd w backend 2

Muszę wyświetlić kilka zdjęć produktu w interfejsie użytkownika w zależności od warunku: należy użyć wirtualnych kopii lustrzanych.

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

namespace Dcw\Vm\Observer;

use Magento\Framework\Event\ObserverInterface;

class ChangeTemplateObserver extends \Magento\ProductVideo\Observer\ChangeTemplateObserver
{
    /**
     * @param mixed $observer
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
     * @return void
     */
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $observer->getBlock()->setTemplate('Dcw_Vm::helper/gallery.phtml');
    }
}

Szablon:

<div class="admin__field field-image-vm">
    <div class="admin__field-control">
        <div class="admin__field admin__field-option">
            <input type="checkbox"
                   id="use-for-vm"
                   data-role="vm-save"
                   data-form-part="<?php /* @escapeNotVerified */ echo $formName ?>"
                   value="1"
                   class="admin__control-checkbox"
                   name="<?php /* @escapeNotVerified */ echo $elementName ?>[<%- data.file_id %>][vm]"
            <% if (data.useforvm == 1) { %>checked="checked"<% } %> />

            <label for="use-for-vm" class="admin__field-label">
                <?php /* @escapeNotVerified */ echo __('Use for Virutal Mirror')?>
            </label>
        </div>
    </div>
</div>

Zainstaluj skrypt:

<?php

namespace Dcw\Vm\Setup;

use Magento\Framework\Setup\InstallSchemaInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Catalog\Model\ResourceModel\Product\Gallery;

class InstallSchema implements InstallSchemaInterface {

    public function install(SchemaSetupInterface $setup, ModuleContextInterface $context) {
        $setup->startSetup();

        $setup->getConnection()->addColumn(
                $setup->getTable(Gallery::GALLERY_TABLE), 'vm', [
            'type' => \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
            'unsigned' => true,
            'nullable' => false,
            'default' => 0,
            'comment' => 'use for Vm'                ]
        );

        $setup->endSetup();
    }

}

Jak zapisać zaznaczone obrazy w backendie? A jak filtrować te obrazy w interfejsie? Czy możesz mi w tym pomóc?

AKTUALIZACJA:

obserwowanie obserwatora (na zdarzenie catalog_product_save_after) dla istniejących obrazów działa, ale dla nowych obrazów nie działa.

<?php

namespace Dcw\Vm\Observer;

use Magento\Framework\Event\ObserverInterface;

class Productsaveafter implements ObserverInterface {

    protected $request;
    protected $resource;

    /**
     * 
     * @param \Magento\Framework\App\RequestInterface $request
     * @param \Magento\Framework\App\ResourceConnection $resource\
     */
    public function __construct(
    \Magento\Framework\App\RequestInterface $request, \Magento\Framework\App\ResourceConnection $resource
    ) {
        $this->request = $request;
        $this->resource = $resource;
    }

    public function execute(\Magento\Framework\Event\Observer $observer) {

        $vm = array();
        $data = $this->request->getPostValue();

        if (isset($data['product']['media_gallery']['images'])) {
            $images = $data['product']['media_gallery']['images'];

            foreach ($images as $image) {
                if (isset($image['vm']) && $image['vm'] == 1) {
                    $vm[$image['value_id']] = 1;
                } else {
                    $vm[$image['value_id']] = 0;
                }
            }
   // print_r($images);exit;
            $connection = $this->resource->getConnection();
            $tableName = 'catalog_product_entity_media_gallery'; //gives table name with prefix
            $product = $observer->getProduct();
            $mediaGallery = $product->getMediaGallery();

            if (isset($mediaGallery['images'])) {
                foreach ($mediaGallery['images'] as $image) {
                    if (isset($vm[$image['value_id']])) {
                        //Update Data into table
                        $sql = "Update " . $tableName . " Set vm = " . $vm[$image['value_id']] . " where value_id = " . $image['value_id'];
                        $connection->query($sql);
                    }
                }
            }
        }
    }

}
Siva Kumar Koduru
źródło
Które wydarzenie obserwujesz? Spróbuję go odtworzyć i sprawdzić, dlaczego nie działa.
Siarhey Uchukhlebau
catalog_product_save_after, jeśli obraz jest nową wartością id będzie pusty, więc po raz pierwszy nie będzie działać.
Siva Kumar Koduru
A którego wydarzenia używasz ChangeTemplateObserver?
Siarhey Uchukhlebau
<preferencja = = Magento \ ProductVideo \ Observer \ ChangeTemplateObserver "type =" Dcw \ Vm \ Observer \ ChangeTemplateObserver "/>
Siva Kumar Koduru
Czy moja odpowiedź ci pomogła?
Siarhey Uchukhlebau,

Odpowiedzi:

9

W twoim obserwatorze jest dużo niepotrzebnego kodu. Możesz to zmienić w następujący sposób:

<?php

namespace Dcw\Vm\Observer;

use Magento\Framework\Event\ObserverInterface;

class ProductSaveAfter implements ObserverInterface {

    protected $request;
    protected $resource;

    /**
     *
     * @param \Magento\Framework\App\RequestInterface $request
     * @param \Magento\Framework\App\ResourceConnection $resource\
     */
    public function __construct(
        \Magento\Framework\App\RequestInterface $request, \Magento\Framework\App\ResourceConnection $resource
    ) {
        $this->request = $request;
        $this->resource = $resource;
    }

    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $data = $this->request->getPostValue();

        if (isset($data['product']['media_gallery']['images'])) {
            // print_r($images);exit;
            $connection = $this->resource->getConnection();
            $tableName = 'catalog_product_entity_media_gallery'; //gives table name with prefix
            $product = $observer->getProduct();
            $mediaGallery = $product->getMediaGallery();

            if (isset($mediaGallery['images'])) {
                foreach ($mediaGallery['images'] as $image) {
                        //Update Data into table
                    $vmValue = !empty($image['vm']) ? (int)$image['vm'] : 0;
                        $sql = "UPDATE " . $tableName . " SET vm = " . $vmValue . " WHERE value_id = " . $image['value_id'];
                        $connection->query($sql);
                }
            }
        }
    }

}

Ponieważ nie musisz przechowywać danych z żądania, ponieważ nie ma go value_idw nowo utworzonych obrazach, dlatego Twoje dane nie pozostały podczas dodawania nowego obrazu.

Aby uzyskać dane w innych miejscach, napisałem wtyczkę. Dodaje kolumnę vmdo galerii multimediów wybierz:

app / code / Dcw / Vm / 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">
    <type name="Magento\Catalog\Model\ResourceModel\Product\Gallery">
        <plugin name="afterCreateBatchBaseSelect" type="Dcw\Vm\Plugin\Product\Gallery" sortOrder="10" disabled="false"/>
    </type>
</config>

Kod:

<?php

namespace Dcw\Vm\Plugin\Product;

class Gallery
{
    public function afterCreateBatchBaseSelect(
        \Magento\Catalog\Model\ResourceModel\Product\Gallery $subject,
        \Magento\Framework\DB\Select $select
    ) {
        $select->columns('vm');

        return $select;
    }
}

Zatem teraz niestandardowy atrybut vmpowinien zawsze istnieć w danych mediów produktów.

Aby ukryć obrazy vm na interfejsie, możesz napisać wtyczkę:

app / code / Dcw / Vm / etc / frontend / 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">
    <type name="Magento\Catalog\Model\Product">
        <plugin name="afterGetMediaGalleryImages" type="Dcw\Vm\Plugin\Product" sortOrder="10" disabled="false"/>
    </type>
</config>

Kod:

<?php

namespace Dcw\Vm\Plugin;

class Product
{
    /**
     * @param \Magento\Catalog\Model\Product $subject
     * @param \Magento\Framework\Data\Collection $result
     * @return mixed
     */
    public function afterGetMediaGalleryImages(\Magento\Catalog\Model\Product $subject, $result)
    {
        foreach ($result as $key => $image) {
            if ($image['vm']) {
                $result->removeItemByKey($key);
            }
        }

        return $result;
    }
}

Aby uzyskać obrazy vm z produktu, użyj kodu napisanego przez @Marius (bez wtyczki, która usuwa te obrazy):

$images = []; 
foreach ($product->getMediaGalleryImages() as $image) {
    if ($image->getVm()) {
        $images[] = $image;
    }
}
Siarhey Uchukhlebau
źródło
@SivaKumarKoduru Cieszę się, że mogę Ci pomóc
Siarhey Uchukhlebau
Witaj, @Siarhey Uchukhlebau Muszę zaimplementować Twój kod po stronie zaplecza. Ale kiedy przesyłam wiele obrazów, mam tylko jeden obraz obrazu z maszyną wirtualną, tak jak w rzeczywistości potrzebuję wszystkich obrazów wybranych wartości do danych pocztowych.
Rasik Miyani,
@SiarheyUchukhlebau Dzięki za to myślę, że już prawie jestem: atrybuty zachowują dla mnie, jednak wartości nie są wyświetlane w formularzu edycji produktu? Zastanawiasz się, czy masz czas, by zobaczyć, co zrobiłem źle? Pytanie wspomina data.useforvm, aby pobrać wartości, jednak nigdzie się do nich nie odwołuje, czy brakuje mi kroku? magento.stackexchange.com/questions/301685/…
harri
4

Pobieranie w interfejsie:

Powiedzmy, że jest to produkt, dla którego chcesz wyświetlić wirtualne lustro $product.
Możesz pobrać obrazy oznaczone niestandardowym atrybutem w następujący sposób:

$images = []; 
foreach ($product->getMediaGalleryImages() as $image) {
    if ($image->getVm()) {
        $images[] = $image;
    }
}

Następnie możesz zapętlić $imagestablicę i wyświetlić je tam, gdzie potrzebujesz.

Aby zapisać wartość tego pola wyboru w backendie, myślę, że musisz napisać afterwtyczkę do metody, do \Magento\Catalog\Model\Product\Attribute\Backend\Media\ImageEntryConverter::convertFromktórej dołączasz wartość otrzymaną z posta w $entryArray.

Marius
źródło
w $ image nie ma właściwości z vm, ale w db istniało to pole. więc powraca pusta tablica.
Siva Kumar Koduru
Dobrze. Będę kopać dalej.
Marius
jakakolwiek pomoc w tym, naprawdę jest to coś trudnego do zarządzania js w magento2.
Siva Kumar Koduru
Przepraszam, nie znalazłem nic przydatnego. Postaram się sprawdzić, czy mogę coś dostać po pracy.
Marius