comment enregistrer l'attribut personnalisé de l'image dans magento 2

13

aperçu dans le backend

aperçu dans le backend 2

J'ai besoin d'afficher quelques images du produit en frontend en fonction de la condition: l'utilisation du miroir virtuel doit être vérifiée.

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

Modèle:

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

Script d'installation:

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

}

Comment enregistrer l'état des images vérifiées dans le backend? Et comment filtrer ces images en frontend? Pouvez-vous m'aider à ce sujet?

MISE À JOUR:

l'observateur suivant (sur événement catalog_product_save_after) pour les images existantes fonctionne, mais pour les nouvelles images ne fonctionne pas.

<?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
la source
Quel événement observez-vous? Je vais essayer de le reproduire et de vérifier pourquoi cela ne fonctionne pas.
Siarhey Uchukhlebau
catalog_product_save_after, si l'image est une nouvelle valeur, l'ID sera nul, donc la première fois ne fonctionnera pas.
Siva Kumar Koduru
Et quel événement vous utilisez pour le ChangeTemplateObserver?
Siarhey Uchukhlebau
<préférence pour = "Magento \ ProductVideo \ Observer \ ChangeTemplateObserver" type = "Dcw \ Vm \ Observer \ ChangeTemplateObserver" />
Siva Kumar Koduru
Ma réponse vous a-t-elle aidé?
Siarhey Uchukhlebau

Réponses:

9

Dans votre observateur, il y a beaucoup de code inutile. Vous pouvez le changer comme:

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

}

Parce que vous n'avez pas besoin de stocker les données d'une demande, car il n'y value_iden a pas dans les images nouvellement créées, vos données ne sont donc pas restées lors de l'ajout de la nouvelle image.

Pour obtenir des données ailleurs, j'ai écrit un plugin. Il ajoute la colonne vmà la galerie multimédia, sélectionnez:

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

Alors maintenant, votre attribut personnalisé vmdevrait toujours exister dans les données des médias des produits.

Pour masquer les images vm sur le frontend, vous pouvez écrire un 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>

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

Pour obtenir les images vm du produit, utilisez le code écrit par @Marius (sans plugin qui supprime ces images):

$images = []; 
foreach ($product->getMediaGalleryImages() as $image) {
    if ($image->getVm()) {
        $images[] = $image;
    }
}
Siarhey Uchukhlebau
la source
@SivaKumarKoduru Je suis heureux de vous aider
Siarhey Uchukhlebau
Bonjour, @Siarhey Uchukhlebau Je dois implémenter votre code côté backend.Mais lorsque je télécharge plusieurs images, je n'ai obtenu qu'une seule image avec VM, comme cela en fait, j'ai besoin de toutes les images sélectionnées dans les données de publication.
Rasik Miyani
@SiarheyUchukhlebau Merci pour cela, je pense que j'y suis presque: les attributs me sont épargnés mais les valeurs ne s'affichent pas dans le formulaire d'édition du produit? Vous vous demandez si vous avez le temps de voir ce que j'ai fait de mal? La question mentionne data.useforvm pour extraire des valeurs mais qui ne semblent référencées nulle part, y a-t-il une étape qui me manque? magento.stackexchange.com/questions/301685/…
harri
4

Récupération en frontend:

Disons que le produit pour lequel vous souhaitez afficher le miroir virtuel est $product.
Vous pouvez obtenir les images marquées de votre attribut personnalisé comme ceci:

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

Ensuite, vous pouvez parcourir le $imagestableau et les afficher là où vous en avez besoin.

Pour enregistrer la valeur de cette case à cocher dans le backend, je pense que vous devez écrire un afterplugin pour la méthode \Magento\Catalog\Model\Product\Attribute\Backend\Media\ImageEntryConverter::convertFromoù vous attachez la valeur que vous obtenez de la poste dans le $entryArray.

Marius
la source
dans $ image il n'y a pas de propriété avec vm, mais dans db ce champ existait. donc son tableau vide de retour.
Siva Kumar Koduru
D'accord. Je vais creuser plus loin.
Marius
aucune aide à ce sujet, c'est vraiment quelque chose de difficile à gérer js dans magento2.
Siva Kumar Koduru
Désolé, je n'ai rien trouvé d'utile. J'essaierai de voir si je peux obtenir quelque chose après le travail.
Marius