come salvare l'attributo personalizzato dell'immagine in magento 2


13

anteprima nel backend

anteprima nel backend 2

Devo visualizzare alcune immagini del prodotto in frontend in base alle condizioni: l'uso per il mirror virtuale deve essere verificato.

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

Modello:

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

Installa script:

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

}

Come salvare lo stato delle immagini controllate nel back-end? E come filtrare quelle immagini in frontend? Puoi aiutarmi su questo?

AGGIORNARE:

il seguente osservatore (sull'evento catalog_product_save_after) per le immagini esistenti funziona, ma per le nuove immagini non funziona.

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

}

Quale evento osservi? Proverò a riprodurlo e verificherò perché non funziona.
Siarhey Uchukhlebau,

catalog_product_save_after, se l'immagine è un nuovo valore id sarà nullo, quindi la prima volta non funziona.
Siva Kumar Koduru,

E quale evento stai usando per ChangeTemplateObserver?
Siarhey Uchukhlebau,

<preferenza per = "Magento \ ProductVideo \ Observer \ ChangeTemplateObserver" type = "Dcw \ Vm \ Observer \ ChangeTemplateObserver" />
Siva Kumar Koduru

La mia risposta ti ha aiutato?
Siarhey Uchukhlebau,

Risposte:


9

Nel tuo osservatore c'è molto codice non necessario. Puoi cambiarlo come:

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

}

Poiché non è necessario archiviare dati da una richiesta, poiché non sono presenti value_idnelle immagini appena create, pertanto i dati non sono rimasti durante l'aggiunta della nuova immagine.

Per ottenere dati in altri posti ho scritto un plugin. Aggiunge la colonna vmalla selezione della galleria multimediale:

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>

Codice:

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

Quindi ora il tuo attributo personalizzato vmdovrebbe sempre esistere nei dati multimediali dei prodotti.

Per nascondere le immagini VM sul frontend puoi scrivere plugin:

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>

Codice:

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

Per ottenere le immagini VM dal prodotto, utilizzare il codice scritto da @Marius (senza un plug-in che elimina queste immagini):

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

@SivaKumarKoduru Sono felice di aiutarti
Siarhey Uchukhlebau

Ciao, @Siarhey Uchukhlebau Devo implementare il tuo codice sul lato back-end. Ma quando carico più immagini, ho ottenuto solo un dato immagine con VM, quindi in realtà ho bisogno di tutte le immagini valore selezionato nei dati post.
Rasik Miyani,

@SiarheyUchukhlebau Grazie per questo penso di essere quasi arrivato: gli attributi mi salvano ma i valori non vengono visualizzati nel modulo di modifica del prodotto? Ti chiedi se hai tempo di vedere cosa ho fatto di sbagliato? La domanda menziona data.useforvm per estrarre valori che tuttavia non sembrano riferiti da nessuna parte, c'è un passo che mi manca? magento.stackexchange.com/questions/301685/…
harri

4

Recupero in frontend:

Supponiamo che sia il prodotto per il quale si desidera visualizzare il mirror virtuale $product.
È possibile ottenere le immagini contrassegnate con l'attributo personalizzato in questo modo:

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

Quindi è possibile eseguire il ciclo attraverso l' $imagesarray e visualizzarli dove è necessario.

Per salvare il valore di quella casella nel back-end, penso che sia necessario scrivere un afterplugin per il metodo in \Magento\Catalog\Model\Product\Attribute\Backend\Media\ImageEntryConverter::convertFromcui si allega il valore che si ottiene dalla posta nel $entryArray.


in $ image non esiste alcuna proprietà con vm, ma in db quel campo esisteva. quindi il suo array vuoto di ritorno.
Siva Kumar Koduru,

Ok. Scaverò ulteriormente.
Marius

qualsiasi aiuto su questo, è davvero qualcosa di difficile gestire js in magento2.
Siva Kumar Koduru,

Mi dispiace non ho trovato nulla di utile. Proverò a vedere se riesco a ottenere qualcosa dopo il lavoro.
Marius
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.