2

Hello I have created admin grid for my custom module, I have a form where it is possible to add new product comments. The thing is that I have Product id field, where u can enter id for which product to post comment. So if non-existent id is entered and saved the page breaks.

This is my save controller:

<?php namespace Vendor\Module\Controller\Adminhtml\Comments; use Magento\Backend\App\Action; use Magebit\ProductComments\Model\Comments; use Magento\Catalog\Api\ProductRepositoryInterface; class Save extends Action { private $productRepository; protected $_model; /** * @param Action\Context $context */ public function __construct( Action\Context $context, Comments $model, ProductRepositoryInterface $productRepository ) { parent::__construct($context); $this->_model = $model; $this->productRepository = $productRepository; } /** * {@inheritdoc} */ /** * Save action * * @return \Magento\Framework\Controller\ResultInterface */ public function execute() { $data = $this->getRequest()->getPostValue(); /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */ $resultRedirect = $this->resultRedirectFactory->create(); if ($data) { /** @var \Vendor\Module\Model\Comments $model */ $model = $this->_model; $id = $this->getRequest()->getParam('id'); if ($id) { $model->load($id); } $model->setData($data); $this->_eventManager->dispatch( 'productcomments_comments_prepare_save', ['comments' => $model, 'request' => $this->getRequest()] ); try { $model->save(); $this->messageManager->addSuccess(__('Comment successfully saved')); $this->_getSession()->setFormData(false); if ($this->getRequest()->getParam('back')) { return $resultRedirect->setPath('*/*/edit', ['id' => $model->getId(), '_current' => true]); } return $resultRedirect->setPath('*/*/'); } catch (\Magento\Framework\Exception\LocalizedException $e) { $this->messageManager->addError($e->getMessage()); } catch (\RuntimeException $e) { $this->messageManager->addError($e->getMessage()); } catch (\Exception $e) { $this->messageManager->addException($e, __('Something went wrong while saving the comment')); } $this->_getSession()->setFormData($data); return $resultRedirect->setPath('*/*/edit', ['comment_id' => $this->getRequest()->getParam('id')]); } return $resultRedirect->setPath('*/*/'); } } 

I was thinking about using productrepository getByID function, but haven't yet figured it out. Hope someone will have answers for me, thanks!

Error:

[error] 997#997: *2510 FastCGI sent in stderr: "PHP message: PHP Notice: Undefined variable: mageRunCode in /var/www/magento/public/pub/index.php on line 45 PHP message: PHP Notice: Undefined variable: mageRunType in /var/www/magento/public/pub/index.php on line 46" while reading response header from upstream, client: 127.0.0.1, server: magento.test, request: "GET /admin_1c63d9/mui/index/render/key/d4e9ab2bc3f8dae59f5c2d8d7d9c810149e8b2cbe127f209f27a92a316f958ae/?namespace=notification_area&sorting%5Bfield%5D=created_at&sorting%5Bdirection%5D=asc&isAjax=true HTTP/1.1", upstream: "fastcgi://unix:/var/run/php/php7.0-fpm.sock:", host: "magento.test", referrer: "http://magento.test/admin_1c63d9/admin_comments/comments/edit/id/24/key/897a6e8fe837ce25195df20fa34bd77ee1be78c70e2e7e2f592f97e33de5fb7f/" 

3 Answers 3

3

Try this code to detect is product exist or not:

$productId = $this->getRequest()->getParam('product_id'); // change to your product id real param name $productExists = true; try { $product = $this->productRepository->getById($productId); } catch (\Magento\Framework\Exception\NoSuchEntityException $e) { $productExists = false; } 

PS: it requires the product id (from the request). Do not forget to replace the 'product_id parameter name to the real one you are using in the form.


Here is a full code with a modification:

<?php /** * Created by PhpStorm. * User: magebit * Date: 18.4.1 * Time: 16:05 */ namespace Magebit\ProductComments\Controller\Adminhtml\Comments; use Magento\Backend\App\Action; use Magebit\ProductComments\Model\Comments; use Magento\Catalog\Api\ProductRepositoryInterface; class Save extends Action { /** * @var \Magento\Catalog\Api\ProductRepositoryInterface */ private $productRepository; protected $_model; /** * Save constructor. * * @param Action\Context $context * @param Comments $model * @param ProductRepositoryInterface $productRepository */ public function __construct( Action\Context $context, Comments $model, ProductRepositoryInterface $productRepository ) { parent::__construct($context); $this->_model = $model; $this->productRepository = $productRepository; } /** * Save action * * @return \Magento\Framework\Controller\ResultInterface * @throws \Magento\Framework\Exception\NoSuchEntityException */ public function execute() { $data = $this->getRequest()->getPostValue(); /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */ $resultRedirect = $this->resultRedirectFactory->create(); if ($data) { $productId = $this->getRequest()->getParam('product_id'); // change to your product id real param name try { $this->productRepository->getById($productId); } catch (\Magento\Framework\Exception\NoSuchEntityException $e) { // In case there is no product: display error message and redirect back $this->messageManager->addError($e->getMessage()); $this->_getSession()->setFormData($data); return $resultRedirect->setPath('*/*/edit', ['comment_id' => $this->getRequest()->getParam('id')]); } /** @var \Magebit\ProductComments\Model\Comments $model */ $model = $this->_model; $id = $this->getRequest()->getParam('id'); if ($id) { $model->load($id); } $model->setData($data); $this->_eventManager->dispatch( 'productcomments_comments_prepare_save', ['comments' => $model, 'request' => $this->getRequest()] ); var_dump($productId); try { $model->save(); $this->messageManager->addSuccess(__('Comment successfully saved')); $this->_getSession()->setFormData(false); if ($this->getRequest()->getParam('back')) { return $resultRedirect->setPath('*/*/edit', ['id' => $model->getId(), '_current' => true]); } return $resultRedirect->setPath('*/*/'); } catch (\Magento\Framework\Exception\LocalizedException $e) { $this->messageManager->addError($e->getMessage()); } catch (\RuntimeException $e) { $this->messageManager->addError($e->getMessage()); } catch (\Exception $e) { $this->messageManager->addException($e, __('Something went wrong while saving the comment')); } $this->_getSession()->setFormData($data); return $resultRedirect->setPath('*/*/edit', ['comment_id' => $this->getRequest()->getParam('id')]); } return $resultRedirect->setPath('*/*/'); } } 

Before we doing something with a model we try to load corresponding product from the repository. In case there was no product, the NoSuchEntityException exception throws and we redirecting the customer to the previous page and displaying the error message, like "There was no product with id ...".

10
  • I couldn't implement it into my code, maybe you can add it to my code? Commented Jan 26, 2018 at 12:57
  • @RihardsRepels Sure. Which result is desired when your entity saving with a nonexistent product? Commented Jan 26, 2018 at 13:01
  • Well I mean if non-existent product id is inserted first of all it doesn't save it in database and also displays error message. Commented Jan 26, 2018 at 13:07
  • @RihardsRepels I've updated my answer. As I understood you editing and saving this model from the grid (listing), so I wrote a redirect back to this page, not to the edit page (because there is no such page for not saved entity). If you have any question, feel free to ask. Commented Jan 26, 2018 at 14:06
  • I dont know, after pressing save button, it gives me HTTP ERROR 500. If I understand correctly, parameter name should be the same as field name in ui components file right? <field name="product_id"> Commented Jan 26, 2018 at 14:14
2

You should use ProductRepositoryInterface::getById($id) for retrieving the product by id, this will return a NoSuchEntityException if there is no product with the given id. Catch that exception and add your custom desired behaviour.

You should use the ProductRepositoryInterface::save(Product $product) for saving the product. If you try to save a product with a non-existing id set this will throw a CouldNotSaveException you can catch that and add your custom behaviour.

Using $model->save() in Magento2 is deprecated.

0

since using model is deprecated we use this to load with specific field and save data.

we need these 4 classes to load and update or add new data

1. `\vendor\module\Model\testFactory $ModeltestFactor` 2. `\vendor\module\Model\ResourceModel\test $ResourceModelytest 3.`\vendor\module\Model\testRepository $ModelRepositorytest` 4.`\vendor\module\Api\Data\testInterfaceFactory $InterfaceFactorytest` 

and in class

 $model = $this->ModeltestFactor->create(); $this->ResourceModeltest->load($model,'123456','column_name'); if ($model->getData()){ $model->setBinTo('Bin_Code'); }else { $model = $this->InterfaceFactorytest->create(); $model->setNumber('No'); $model->setMoveBy('jjjjj'); $model->setItem('Item_No'); } $this->ModelRepositorytest->save($model); 

EDIT or you can use only two classes

1. `\vendor\module\Model\testFactory $ModeltestFactor` 2. `\vendor\module\Model\ResourceModel\test $ResourceModelytest 

and in class

 $model = $this->ModeltestFactor->create(); $this->ResourceModeltest->load($model,'123456','column_name'); if ($model->getData()){ $model->setBinTo('Bin_Code'); }else { $model->setNumber('No'); $model->setMoveBy('jjjjj'); $model->setItem('Item_No'); } $this->ModelRepositorytest->save($model); 

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.