how to save image custom attribute in magento 2
In your observer there is a lot of unnecessary code. You can change it like:
<?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);
}
}
}
}
}
Because you don't need to store data from a request, as it has no value_id
in newly created images, therefore your data didn't remain when adding the new image.
To get data in other places I wrote a plugin. It's adding the column vm
to media gallery select:
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;
}
}
So now your custom attribute vm
should always exists in the products media data.
To hide the vm-images on the frontend you can write 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;
}
}
To obtain the vm-images from the product, use code writen by @Marius (without a plugin that deletes this images):
$images = []; foreach ($product->getMediaGalleryImages() as $image) { if ($image->getVm()) { $images[] = $image; } }
Retrieving in frontend:
Let's say that the product for which you want to display the virtual mirror is $product
.
You can get the images that are marked with your custom attribute like this:
$images = [];
foreach ($product->getMediaGalleryImages() as $image) {
if ($image->getVm()) {
$images[] = $image;
}
}
Then you can loop through the $images
array and display them where you need.
To save the value of that checkbox in the backend I think you need to write an after
plugin for the method \Magento\Catalog\Model\Product\Attribute\Backend\Media\ImageEntryConverter::convertFrom
where you attach the value you get from post in the $entryArray
.