Magento 2:如何在观察者中获取报价产品 ID?
Magento 2: How to get quote product id in an observer?
产品 ID 未显示并通过此错误 **{"0": "警告:为 foreach() 提供的参数无效 ** 请帮我解决这个问题。
这里我要return如果属性码不等于5431
那怎么可能。
<?php
namespace Softadroit\Prescription\Observer;
use Magento\Framework\Event\ObserverInterface;
use \Magento\Framework\Event\Observer as EventObserver;
use Psr\Log\LoggerInterface;
class Orderplaceafter implements ObserverInterface
{
protected $_responseFactory;
protected $_url;
public function __construct(
\Magento\Framework\App\ResponseFactory $responseFactory,
\Magento\Framework\UrlInterface $url
) {
$this->_responseFactory = $responseFactory;
$this->_url = $url;
}
public function execute(\Magento\Framework\Event\Observer $observer)
{
$event = $observer->getEvent();
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$_checkoutSession = $objectManager->create('\Magento\Checkout\Model\Session');
$_quoteFactory = $objectManager->create('\Magento\Quote\Model\QuoteFactory');
//$quote = $block->getQuoteData();
/* $quote= $observer->getEvent()->getQuote();
$item = $quote->getAllVisibleItems();
foreach($item as $_item){
echo $_item->getProduct()->getId(); */
$event = $observer->getEvent();
//$item = $event->getQuoteItem();
foreach($event->getQuoteItem() as $_item){
$product = $objectManager->create('Magento\Catalog\Model\Product')->load($_item->getProductId());
$is_priscription = $product->getData('prescription');
if($is_priscription != '5431'){
return;
}
}
if ($quote->getId()) {
$quote->setIsActive(1)->setReservedOrderId(null)->save();
$_checkoutSession->replaceQuote($quote);
$url = $this->_url->getUrl('prescription/index'); //('[ModuleName]/[ModuleName]/[[Action]');
$this->_responseFactory->create()->setRedirect($url)->sendResponse();
die();
}
}
}
非常感谢任何帮助
提前致谢!
下一步
这是我更新的代码,我在此处获取产品 ID,现在我想如果产品属性选项 ID 不等于 5431,则重定向到成功页面,即(订单成功),如果 oroduct 选项 ID 等于 5431,则重定向到下面定义的 url (prescription/index)
<?php
namespace Softadroit\Prescription\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\Controller\ResultFactory;
use \Magento\Framework\Event\Observer as EventObserver;
use Magento\Framework\App\ObjectManager;
use Psr\Log\LoggerInterface;
class Orderplaceafter implements ObserverInterface
{
protected $_responseFactory;
protected $_url;
protected $_order;
public function __construct(
\Magento\Framework\App\ResponseFactory $responseFactory,
\Magento\Framework\UrlInterface $url,
\Magento\Sales\Api\Data\OrderInterface $order
) {
$this->_responseFactory = $responseFactory;
$this->_url = $url;
$this->_order = $order;
}
public function execute(\Magento\Framework\Event\Observer $observer)
{
$event = $observer->getEvent();
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$_checkoutSession = $objectManager->create('\Magento\Checkout\Model\Session');
$_quoteFactory = $objectManager->create('\Magento\Quote\Model\QuoteFactory');
$orderid = $observer->getEvent()->getOrderIds();
$order = $this->_order->load($orderid);
foreach($order->getItemsCollection() as $_item){
$product = $_item->getProductId();
//echo $_item->getName(); die();
$is_priscription = $_item->getProduct()->getMyCustomAttribute('prescription');
if($is_priscription != '5431'){
$resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
$resultRedirect->setPath('order-success');
return $resultRedirect;
}
}
$order = $_checkoutSession->getLastRealOrder();
$quote = $_quoteFactory->create()->loadByIdWithoutStore($order->getQuoteId());
if ($quote->getId()) {
$quote->setIsActive(1)->setReservedOrderId(null)->save();
$_checkoutSession->replaceQuote($quote);
$url = $this->_url->getUrl('prescription/index'); //('[ModuleName]/[ModuleName]/[[Action]');
$this->_responseFactory->create()->setRedirect($url)->sendResponse();
die();
}
}
}
如果您正在观察事件 checkout_onepage_controller_success_action
,则您无法直接访问报价。只到订单。而且您无法从 Checkout 会话实例中获取它,因为在调度事件之前引用已从会话中删除。
但您可以通过订单获取报价。
您首先需要将报价存储库添加为您的观察者的依赖项
private $quoteRepository;
public function __construct(
\Magento\Quote\Api\CartRepositoryInterface $quoteRepository,
....
) {
$this->quoteRepository = $quoteRepository;
....
}
然后,在execute
方法中你可以这样做
$order = $observer->getOrder();
$quoteId = $order->getQuoteId();
$quote = $this->qupteRepository->get($quoteId);
if ($quote && $quote->getId()) {
$items = $quote->getAllItems();
//loop through items ....
}
这会让你得到你想要做的事情。
但我认为更好的主意是不使用报价和产品来获得您需要的东西。
您应该在将报价添加到购物车时将产品属性值保存在报价上,然后将其传输到从报价项目创建的订单项目。
这样,在您的观察者中,您可以执行 $order = $observer->getOrder()
然后遍历订单项 $order->getAllItems()
并检查您需要什么。
请尝试以下操作:
<?php
namespace Softadroit\Prescription\Observer;
use Magento\Framework\Event\ObserverInterface;
use \Magento\Framework\Event\Observer as EventObserver;
use Psr\Log\LoggerInterface;
class Orderplaceafter implements ObserverInterface
{
protected $_responseFactory;
protected $_url;
public function __construct(
\Magento\Framework\App\ResponseFactory $responseFactory,
\Magento\Framework\UrlInterface $url,
\Magento\Quote\Model\QuoteRepository $quoteRepository,
\Magento\Sales\Model\OrderFactory $orderFactory,
\Magento\Checkout\Model\Session $checkoutSession
) {
$this->_responseFactory = $responseFactory;
$this->_url = $url;
$this->quoteRepository = $quoteRepository;
$this->orderFactory = $orderFactory;
$this->checkoutSession = $checkoutSession;
}
public function execute(\Magento\Framework\Event\Observer $observer)
{
$event = $observer->getEvent();
$orderIds = $observer->getEvent()->getOrderIds();
$order = $this->orderFactory->create()->load($orderIds[0]);
$quote = $this->quoteRepository->get($order->getQuoteId());
$item = $quote->getAllItems();
foreach($item as $_item){
$product = $_item->getProduct();
$is_priscription = $product->getData('prescription');
if($is_priscription != "" && $is_priscription == '5431'){
return;
}
}
if ($quote->getId()) {
$quote->setIsActive(1)->setReservedOrderId(null)->save();
$this->checkoutSession->replaceQuote($quote);
$url = $this->_url->getUrl('prescription/index');
$this->_responseFactory->create()->setRedirect($url)->sendResponse();
die();
}
}
}
之后请运行 php bin/magento setup:upgrade
产品 ID 未显示并通过此错误 **{"0": "警告:为 foreach() 提供的参数无效 ** 请帮我解决这个问题。
这里我要return如果属性码不等于5431
那怎么可能。
<?php
namespace Softadroit\Prescription\Observer;
use Magento\Framework\Event\ObserverInterface;
use \Magento\Framework\Event\Observer as EventObserver;
use Psr\Log\LoggerInterface;
class Orderplaceafter implements ObserverInterface
{
protected $_responseFactory;
protected $_url;
public function __construct(
\Magento\Framework\App\ResponseFactory $responseFactory,
\Magento\Framework\UrlInterface $url
) {
$this->_responseFactory = $responseFactory;
$this->_url = $url;
}
public function execute(\Magento\Framework\Event\Observer $observer)
{
$event = $observer->getEvent();
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$_checkoutSession = $objectManager->create('\Magento\Checkout\Model\Session');
$_quoteFactory = $objectManager->create('\Magento\Quote\Model\QuoteFactory');
//$quote = $block->getQuoteData();
/* $quote= $observer->getEvent()->getQuote();
$item = $quote->getAllVisibleItems();
foreach($item as $_item){
echo $_item->getProduct()->getId(); */
$event = $observer->getEvent();
//$item = $event->getQuoteItem();
foreach($event->getQuoteItem() as $_item){
$product = $objectManager->create('Magento\Catalog\Model\Product')->load($_item->getProductId());
$is_priscription = $product->getData('prescription');
if($is_priscription != '5431'){
return;
}
}
if ($quote->getId()) {
$quote->setIsActive(1)->setReservedOrderId(null)->save();
$_checkoutSession->replaceQuote($quote);
$url = $this->_url->getUrl('prescription/index'); //('[ModuleName]/[ModuleName]/[[Action]');
$this->_responseFactory->create()->setRedirect($url)->sendResponse();
die();
}
}
}
非常感谢任何帮助
提前致谢!
下一步
这是我更新的代码,我在此处获取产品 ID,现在我想如果产品属性选项 ID 不等于 5431,则重定向到成功页面,即(订单成功),如果 oroduct 选项 ID 等于 5431,则重定向到下面定义的 url (prescription/index)
<?php
namespace Softadroit\Prescription\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\Controller\ResultFactory;
use \Magento\Framework\Event\Observer as EventObserver;
use Magento\Framework\App\ObjectManager;
use Psr\Log\LoggerInterface;
class Orderplaceafter implements ObserverInterface
{
protected $_responseFactory;
protected $_url;
protected $_order;
public function __construct(
\Magento\Framework\App\ResponseFactory $responseFactory,
\Magento\Framework\UrlInterface $url,
\Magento\Sales\Api\Data\OrderInterface $order
) {
$this->_responseFactory = $responseFactory;
$this->_url = $url;
$this->_order = $order;
}
public function execute(\Magento\Framework\Event\Observer $observer)
{
$event = $observer->getEvent();
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$_checkoutSession = $objectManager->create('\Magento\Checkout\Model\Session');
$_quoteFactory = $objectManager->create('\Magento\Quote\Model\QuoteFactory');
$orderid = $observer->getEvent()->getOrderIds();
$order = $this->_order->load($orderid);
foreach($order->getItemsCollection() as $_item){
$product = $_item->getProductId();
//echo $_item->getName(); die();
$is_priscription = $_item->getProduct()->getMyCustomAttribute('prescription');
if($is_priscription != '5431'){
$resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
$resultRedirect->setPath('order-success');
return $resultRedirect;
}
}
$order = $_checkoutSession->getLastRealOrder();
$quote = $_quoteFactory->create()->loadByIdWithoutStore($order->getQuoteId());
if ($quote->getId()) {
$quote->setIsActive(1)->setReservedOrderId(null)->save();
$_checkoutSession->replaceQuote($quote);
$url = $this->_url->getUrl('prescription/index'); //('[ModuleName]/[ModuleName]/[[Action]');
$this->_responseFactory->create()->setRedirect($url)->sendResponse();
die();
}
}
}
如果您正在观察事件 checkout_onepage_controller_success_action
,则您无法直接访问报价。只到订单。而且您无法从 Checkout 会话实例中获取它,因为在调度事件之前引用已从会话中删除。
但您可以通过订单获取报价。
您首先需要将报价存储库添加为您的观察者的依赖项
private $quoteRepository;
public function __construct(
\Magento\Quote\Api\CartRepositoryInterface $quoteRepository,
....
) {
$this->quoteRepository = $quoteRepository;
....
}
然后,在execute
方法中你可以这样做
$order = $observer->getOrder();
$quoteId = $order->getQuoteId();
$quote = $this->qupteRepository->get($quoteId);
if ($quote && $quote->getId()) {
$items = $quote->getAllItems();
//loop through items ....
}
这会让你得到你想要做的事情。
但我认为更好的主意是不使用报价和产品来获得您需要的东西。
您应该在将报价添加到购物车时将产品属性值保存在报价上,然后将其传输到从报价项目创建的订单项目。
这样,在您的观察者中,您可以执行 $order = $observer->getOrder()
然后遍历订单项 $order->getAllItems()
并检查您需要什么。
请尝试以下操作:
<?php
namespace Softadroit\Prescription\Observer;
use Magento\Framework\Event\ObserverInterface;
use \Magento\Framework\Event\Observer as EventObserver;
use Psr\Log\LoggerInterface;
class Orderplaceafter implements ObserverInterface
{
protected $_responseFactory;
protected $_url;
public function __construct(
\Magento\Framework\App\ResponseFactory $responseFactory,
\Magento\Framework\UrlInterface $url,
\Magento\Quote\Model\QuoteRepository $quoteRepository,
\Magento\Sales\Model\OrderFactory $orderFactory,
\Magento\Checkout\Model\Session $checkoutSession
) {
$this->_responseFactory = $responseFactory;
$this->_url = $url;
$this->quoteRepository = $quoteRepository;
$this->orderFactory = $orderFactory;
$this->checkoutSession = $checkoutSession;
}
public function execute(\Magento\Framework\Event\Observer $observer)
{
$event = $observer->getEvent();
$orderIds = $observer->getEvent()->getOrderIds();
$order = $this->orderFactory->create()->load($orderIds[0]);
$quote = $this->quoteRepository->get($order->getQuoteId());
$item = $quote->getAllItems();
foreach($item as $_item){
$product = $_item->getProduct();
$is_priscription = $product->getData('prescription');
if($is_priscription != "" && $is_priscription == '5431'){
return;
}
}
if ($quote->getId()) {
$quote->setIsActive(1)->setReservedOrderId(null)->save();
$this->checkoutSession->replaceQuote($quote);
$url = $this->_url->getUrl('prescription/index');
$this->_responseFactory->create()->setRedirect($url)->sendResponse();
die();
}
}
}
之后请运行 php bin/magento setup:upgrade