How to safely override or extend other services' methods in Drupal 8
Two look-alike birds
Categories
Drupal

So you want to edit a specific piece of code provided by a class from Drupal's core or from a contrib module?

...

Example

Customize the message displayed when a product is added to Commerce Cart

Drupal Commerce displays a message when users add a product to their cart. By default, the message is composed of the entity's label and a link to the cart page. Editing this message seems to be fairly easy... but it is actually not possible. Unless you completely take over the EventSubscriber class - \Drupal\commerce_cart\EventSubscriber\CartEventSubscriber - there is no call to any hook_ nor any custom event triggered by Commerce Cart module.

In this case, service decoration method is your best friend :)

1) Create your own EventSubcriber inside mymodule/src/EventSubscriber/CartEventSubscriber.php as follow:

namespace Drupal\mymodule\EventSubscriber;

use Drupal\commerce_cart\Event\CartEntityAddEvent;
use Drupal\Core\Url;
use Drupal\commerce_cart\EventSubscriber\CartEventSubscriber as BaseSubscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class CartEventSubscriber extends BaseSubscriber implements EventSubscriberInterface {

  /**
   * {@inheritDoc}
   */
  public function displayAddToCartMessage(CartEntityAddEvent $event) {
    $this->messenger->addMessage($this->t('This is a custom message.'));
  }
}

2) Tell Drupal your class is actually a Decorator inside mymodule/mymodule.services.yml:

services:
  mymodule.commerce_cart.cart_subscriber.decorator:
    public: false
    class: Drupal\mymodule\EventSubscriber\CartEventSubscriber
    decorates: commerce_cart.cart_subscriber
    decoration_priority: 5
    arguments: ['@messenger', '@string_translation']

3) Clear caches and enjoy your own custom message!