Feature request from leoquijano, posted on GitHub May 18, 2016
While implementing a custom theme using Magento 2, I found out that there's currently no support for easy customization of Add to Cart message texts.
In the Magento\Checkout\Controller\Cart\Add
class, the following method is called to add a product to the cart:
/**
* Add product to shopping cart action
*
* @return \Magento\Framework\Controller\Result\Redirect
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/
public function execute()
{
if (!$this->_formKeyValidator->validate($this->getRequest())) {
return $this->resultRedirectFactory->create()->setPath('*/*/');
}
$params = $this->getRequest()->getParams();
try {
if (isset($params['qty'])) {
$filter = new \Zend_Filter_LocalizedToNormalized(
['locale' => $this->_objectManager->get('Magento\Framework\Locale\ResolverInterface')->getLocale()]
);
$params['qty'] = $filter->filter($params['qty']);
}
$product = $this->_initProduct();
$related = $this->getRequest()->getParam('related_product');
/**
* Check product availability
*/
if (!$product) {
return $this->goBack();
}
$this->cart->addProduct($product, $params);
if (!empty($related)) {
$this->cart->addProductsByIds(explode(',', $related));
}
$this->cart->save();
/**
* @todo remove wishlist observer \Magento\Wishlist\Observer\AddToCart
*/
$this->_eventManager->dispatch(
'checkout_cart_add_product_complete',
['product' => $product, 'request' => $this->getRequest(), 'response' => $this->getResponse()]
);
if (!$this->_checkoutSession->getNoCartRedirect(true)) {
if (!$this->cart->getQuote()->getHasError()) {
$message = __(
'You added %1 to your shopping cart.',
$product->getName()
);
$this->messageManager->addSuccessMessage($message);
}
return $this->goBack(null, $product);
}
} catch (\Magento\Framework\Exception\LocalizedException $e) {
if ($this->_checkoutSession->getUseNotice(true)) {
$this->messageManager->addNotice(
$this->_objectManager->get('Magento\Framework\Escaper')->escapeHtml($e->getMessage())
);
} else {
$messages = array_unique(explode("\n", $e->getMessage()));
foreach ($messages as $message) {
$this->messageManager->addError(
$this->_objectManager->get('Magento\Framework\Escaper')->escapeHtml($message)
);
}
}
$url = $this->_checkoutSession->getRedirectUrl(true);
if (!$url) {
$cartUrl = $this->_objectManager->get('Magento\Checkout\Helper\Cart')->getCartUrl();
$url = $this->_redirect->getRedirectUrl($cartUrl);
}
return $this->goBack($url);
} catch (\Exception $e) {
$this->messageManager->addException($e, __('We can\'t add this item to your shopping cart right now.'));
$this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
return $this->goBack();
}
}
It can be seen here two particular places where messages are hardwired. The first one is the success message:
$message = __(
'You added %1 to your shopping cart.',
$product->getName()
);
$this->messageManager->addSuccessMessage($message);
The second one is the error message:
} catch (\Exception $e) {
$this->messageManager->addException($e, __('We can\'t add this item to your shopping cart right now.'));
$this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
return $this->goBack();
}
Some websites require different copy for the Add to Cart behavior (both for success and error messages), so ideally theme developers should be able to customize that behavior. While the optimal approach would be to configure this in layout or template files, I think that a relatively simple solution is refactoring the Controller code, like this:
if (!$this->cart->getQuote()->getHasError()) {
$message = $this->getSuccessMessage($product);
$this->messageManager->addSuccessMessage($message);
}
} catch (\Exception $e) {
$this->messageManager->addException($e, $this->getErrorMessage());
$this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
return $this->goBack();
}
/**
* Gets the message used when a product is successfully added to the cart.
* @param $product
* @return \Magento\Framework\Phrase
*/
protected function getSuccessMessage($product)
{
return __(
'You added %1 to your shopping cart.',
$product->getName()
);
}
/**
* Gets the message used when there's a problem adding an item to the cart.
* @return \Magento\Framework\Phrase
*/
protected function getErrorMessage()
{
return __('We can\'t add this item to your shopping cart right now.');
}
This would allow theme developers to override this controller without overriding the main execute
method, which can be risky and has a higher maintenance cost.