3

I'm looking for best practice on how to query to database in observer.

Ok so this is the idea, i use observer to catch event catalog_product_save_after (which will be fired after product is saved in admin page), after that, i get product id, and query to database to get data. Then after some code, i will update data to database.

I've searched a lot, but what i found is just some direct sql solution (which i don't think is good practice for this). Here is what i've found:

(i was not try the third one)

Ok so here is what i do so far:

events.xml

<?xml version="1.0"?>
<!--
/**
 * Copyright © 2013-2017 Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
 <event name="sales_model_service_quote_submit_success">
 <observer name="sendEmailCustom" instance="Synergy\Butility\Observer\Quote\Webapi\SubmitObserver" />
 </event>
 <event name="catalog_product_save_after">
 <observer name="saveProduct" instance="Synergy\Butility\Observer\ProductSaveObserver" />
 </event>
</config>

ProductSaveObserver.php

<?php
namespace Synergy\Butility\Observer;
use Magento\Framework\Event\ObserverInterface;
class ProductSaveObserver implements ObserverInterface
{ 
 public function __construct(
 \Magento\Framework\App\ResourceConnection $resource
 ) {
 $this->_resource = $resource;
 }
 public function execute(\Magento\Framework\Event\Observer $observer)
 {
 $productId = $observer->getProduct()->getId();
 $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
 $resource = $objectManager->get('\Magento\Framework\App\ResourceConnection');
 $connection = $resource->getConnection();
 $tableName = $resource->getTableName('catalog_product_flat_32');
 $product_query = "SELECT * FROM " . $tableName . " WHERE entity_id = " . $productId;
 $product = $connection->query($product_query);
 foreach ($product as $data) {
 var_dump($product->getData());
 }
 exit;
 // $sql = "UPDATE " . $tableName . " SET customer_type = '" . $this->getCustomerType() . "' WHERE entity_id = " . $this->getEntityId($observer);
 // $connection->query($sql);
 } 
}

Thanks for reading :)

sv3n
11.7k7 gold badges44 silver badges75 bronze badges
asked Oct 17, 2018 at 14:23

2 Answers 2

0

Ok so my solution is not really answer for this question, but it helped me, if some one is going to my situation, i hope this answer will help them
So this answer is nearly answer the question "how to update custom attribute using observer after product saved".
Take a look on this link and you will find out:
https://webkul.com/blog/mass-update-products-attribute-magento-2/
So basically if you follow this solution, you don't need to use query in observer anymore

Here is how i did:

ProductSaveObserver.php

<?php
namespace Synergy\Butility\Observer;
use Magento\Framework\Event\ObserverInterface;
class ProductSaveObserver implements ObserverInterface
{ 
 public function __construct(
 \Magento\Framework\App\ResourceConnection $resource
 ) {
 $this->_resource = $resource;
 }
 public function execute(\Magento\Framework\Event\Observer $observer)
 {
 // AB-18 update news_to_day take data from news_to_date in catalog_product_flat_32 table after "saved product" in admin page
 $productId = $observer->getProduct()->getId();
 $productIdArr = [$productId];
 $news_to_date = $observer->getProduct()->getNewsToDate();
 $news_to_date = substr($news_to_date,0,-8);
 $news_to_date = $news_to_date.'00:00:00';
 $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
 $productActionObject = $objectManager->create('Magento\Catalog\Model\Product\Action');
 $productActionObject->updateAttributes($productIdArr, array('news_to_day' => $news_to_date), 0);
 }
}
answered Oct 18, 2018 at 11:22
0

I have a bit cleaner version for you

<?php
namespace Synergy\Butility\Observer;
use Magento\Catalog\Model\Product;
use Magento\Catalog\Model\ProductRepository;
use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\Exception\CouldNotSaveException;
use Magento\Framework\Exception\InputException;
use Magento\Framework\Exception\StateException;
class ProductSaveObserver implements ObserverInterface
{
 private const NEWS_TO_DAY = 'news_to_day';
 
 /** @var ProductRepository */
 private $productRepository;
 /**
 * ProductSaveObserver constructor.
 * @param ProductRepository $productRepository
 */
 public function __construct(
 ProductRepository $productRepository
 )
 {
 $this->productRepository = $productRepository;
 }
 /**
 * @param Observer $observer
 * @throws CouldNotSaveException
 * @throws InputException
 * @throws StateException
 */
 public function execute(Observer $observer): void
 {
 /** @var Product $product */
 $product = $observer->getProduct();
 // i believe this is a custom attribute in a product, news_to_day
 $newsToDate = $product->getData(self::NEWS_TO_DAY);
 $newsToDate = substr($newsToDate, 0, -8);
 $newsToDate = $newsToDate . '00:00:00';
 $product->setCustomAttribute(self::NEWS_TO_DAY, $newsToDate);
 // a repository should save a product entity
 $this->productRepository->save($product);
 }
}

Please never use this type of code in your scripts, it is really bad

$objectManager = \Magento\Framework\App\ObjectManager::getInstance();

Please read this article as to how to create a new instance in magento2 http://www.rosenborgsolutions.com/magento-new-class-instance.php

answered Aug 17, 2020 at 21:26

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.