Wie man ein benutzerdefiniertes Bildattribut in Magento 2 speichert

13

Vorschau im Backend

Vorschau im Backend 2

Ich muss ein paar Bilder des Produkts im Frontend anzeigen, basierend auf der Bedingung: Die Verwendung für den virtuellen Spiegel sollte überprüft werden.

<?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');
    }
}

Vorlage:

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

Skript installieren:

<?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();
    }

}

Wie speichere ich den Status der überprüften Bilder im Backend? Und wie filtert man diese Bilder im Frontend? Kannst du mir dabei helfen?

AKTUALISIEREN:

Der folgende Beobachter (bei Ereignis catalog_product_save_after) für vorhandene Bilder funktioniert, für neue Bilder jedoch nicht.

<?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
quelle
Welches Ereignis beobachten Sie? Ich werde versuchen, es zu reproduzieren und zu überprüfen, warum es nicht funktioniert.
Siarhey Uchukhlebau
catalog_product_save_after, wenn image new value id ist, wird null sein, also funktioniert das erste mal nicht.
Siva Kumar Koduru
Und welches Event nutzt du für das ChangeTemplateObserver?
Siarhey Uchukhlebau
<Einstellung für = "Magento \ ProductVideo \ Observer \ ChangeTemplateObserver" type = "Dcw \ Vm \ Observer \ ChangeTemplateObserver" />
Siva Kumar Koduru
Hat meine Antwort dir geholfen?
Siarhey Uchukhlebau

Antworten:

9

In Ihrem Beobachter steckt viel unnötiger Code. Sie können es wie folgt ändern:

<?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);
                }
            }
        }
    }

}

Da Sie keine Daten aus einer Anfrage speichern müssen, da value_idin neu erstellten Bildern keine vorhanden sind, sind Ihre Daten beim Hinzufügen des neuen Bildes nicht erhalten geblieben.

Um Daten an anderen Orten zu erhalten, habe ich ein Plugin geschrieben. Es wird die Spalte vmzur Mediengalerie hinzugefügt. Wählen Sie:

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>

Code:

<?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;
    }
}

Daher sollte Ihr benutzerdefiniertes Attribut jetzt vmimmer in den Mediendaten des Produkts vorhanden sein.

Um die VM-Images im Frontend auszublenden, können Sie ein Plugin schreiben:

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>

Code:

<?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;
    }
}

Um die VM-Images vom Produkt zu erhalten, verwenden Sie den von @Marius geschriebenen Code (ohne ein Plugin, das diese Images löscht):

$images = []; 
foreach ($product->getMediaGalleryImages() as $image) {
    if ($image->getVm()) {
        $images[] = $image;
    }
}
Siarhey Uchukhlebau
quelle
@SivaKumarKoduru Ich bin froh, Ihnen zu helfen
Siarhey Uchukhlebau
Hallo, @Siarhey Uchukhlebau Ich muss deinen Code auf der Backend-Seite implementieren. Aber wenn ich mehrere Bilder hochlade, dann habe ich nur ein Bild mit VM-Daten.
Rasik Miyani
@SiarheyUchukhlebau Danke dafür, ich glaube, ich bin fast da: Attribute speichern für mich, aber die Werte werden nicht in der Produktbearbeitungsform angezeigt? Sie fragen sich, ob Sie Zeit haben und sehen können, was ich falsch gemacht habe? In der Frage wird data.useforvm erwähnt, um Werte abzurufen, die jedoch nirgendwo referenziert zu sein scheinen. Gibt es einen Schritt, den ich vermisse? magento.stackexchange.com/questions/301685/…
harri
4

Abrufen im Frontend:

Angenommen, das Produkt, für das Sie den virtuellen Spiegel anzeigen möchten, ist $product.
Sie können die Bilder, die mit Ihrem benutzerdefinierten Attribut markiert sind, folgendermaßen abrufen:

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

Anschließend können Sie das $imagesArray durchlaufen und dort anzeigen, wo Sie es benötigen.

Um den Wert dieses Kontrollkästchens im Backend zu speichern, müssen Sie meines Erachtens ein afterPlugin für die Methode schreiben , \Magento\Catalog\Model\Product\Attribute\Backend\Media\ImageEntryConverter::convertFromin der Sie den Wert anhängen, den Sie von der Post erhalten $entryArray.

Marius
quelle
in $ image gibt es keine Eigenschaft mit vm, aber in db existierte dieses Feld, so dass es ein leeres Array zurückgibt.
Siva Kumar Koduru
In Ordnung. Ich werde weiter graben.
Marius
jede hilfe dabei, es ist wirklich etwas schwierig, js in magento2 zu verwalten.
Siva Kumar Koduru
Entschuldigung, ich habe nichts Nützliches gefunden. Ich werde versuchen zu sehen, ob ich nach der Arbeit etwas bekommen kann.
Marius