cómo guardar el atributo personalizado de imagen en magento 2

13

vista previa en el backend

vista previa en el backend 2

Necesito mostrar algunas imágenes del producto en la interfaz según la condición: se debe verificar el uso del espejo virtual.

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

Modelo:

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

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

}

¿Cómo guardar el estado de las imágenes marcadas en el backend? ¿Y cómo filtrar esas imágenes en frontend? ¿Me puedes ayudar con esto?

ACTUALIZAR:

El siguiente observador (en caso de evento catalog_product_save_after) para imágenes existentes funciona, pero para imágenes nuevas no funciona.

<?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
fuente
¿Qué evento observas? Intentaré reproducirlo y comprobar por qué no funciona.
Siarhey Uchukhlebau
catalog_product_save_after, si la imagen es nueva, el ID de valor será nulo, por lo que la primera vez no funcionará.
Siva Kumar Koduru
¿Y qué evento estás usando para el ChangeTemplateObserver?
Siarhey Uchukhlebau
<preferencia para = "Magento \ ProductVideo \ Observer \ ChangeTemplateObserver" type = "Dcw \ Vm \ Observer \ ChangeTemplateObserver" />
Siva Kumar Koduru
¿Te ayudó mi respuesta?
Siarhey Uchukhlebau

Respuestas:

9

En su observador hay mucho código innecesario. Puedes cambiarlo como:

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

}

Debido a que no necesita almacenar datos de una solicitud, ya que no existe value_iden las imágenes recién creadas, sus datos no permanecieron al agregar la nueva imagen.

Para obtener datos en otros lugares escribí un complemento. Está agregando la columna vma la galería de medios seleccione:

aplicación / código / 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>

Código:

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

Por lo tanto, ahora su atributo personalizado vmsiempre debe existir en los datos multimedia de los productos.

Para ocultar las imágenes vm en la interfaz, puede escribir el complemento:

aplicación / código / 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>

Código:

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

Para obtener las imágenes vm del producto, use el código escrito por @Marius (sin un complemento que elimine estas imágenes):

$images = []; 
foreach ($product->getMediaGalleryImages() as $image) {
    if ($image->getVm()) {
        $images[] = $image;
    }
}
Siarhey Uchukhlebau
fuente
@SivaKumarKoduru, me alegra poder ayudarte
Siarhey Uchukhlebau
Hola, @Siarhey Uchukhlebau. Tengo que implementar su código en el lado del backend. Pero cuando subo varias imágenes, solo obtengo un dato de imagen con VM. De esta forma, realmente necesito el valor de todas las imágenes seleccionadas en los datos de publicación.
Rasik Miyani
@SiarheyUchukhlebau Gracias por esto, creo que estoy casi allí: los atributos me ahorran, sin embargo, los valores no se muestran en el formulario de edición del producto. ¿Te preguntas si tienes tiempo para ver lo que hice mal? La pregunta menciona data.useforvm para extraer valores, sin embargo, eso no parece referenciado en ningún lado, ¿hay un paso que me falta? magento.stackexchange.com/questions/301685/…
harri
4

Recuperando en frontend:

Digamos que el producto para el que desea mostrar el espejo virtual es $product.
Puede obtener las imágenes que están marcadas con su atributo personalizado como este:

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

Luego puede recorrer la $imagesmatriz y mostrarlos donde lo necesite.

Para guardar el valor de esa casilla de verificación en el backend, creo que debe escribir un aftercomplemento para el método \Magento\Catalog\Model\Product\Attribute\Backend\Media\ImageEntryConverter::convertFromdonde adjunta el valor que obtiene de la publicación en el $entryArray.

Marius
fuente
en $ image no hay propiedad con vm, pero en db ese campo existió, por lo que su matriz vacía regresa.
Siva Kumar Koduru
Okay. Cavaré más.
Marius
cualquier ayuda en esto, realmente es algo difícil administrar js en magento2.
Siva Kumar Koduru
Lo siento, no encontré nada útil. Intentaré ver si puedo conseguir algo después del trabajo.
Marius