how to override services image
2 February 2021

 

This article demonstrates how to override a Contrib module service in Drupal 8 and 9.

Why override Drupal Service:
 
Because it is not advisable to make changes in Core/Contrib modules code directly. We will extend Core/Contrib Service in our Custom module and add the extra code to override it. In a nutshell, we are overriding the Drupal service. Overriding the Private Message Contrib Module:
 
As an example, I’m overriding the Private Message service named PrivateMessageService
 
The steps mentioned below will override the “PrivateMessageService”

Image removed.

Step 1: Create a new module
 
First of all, we will Prepare a Module skeleton by creating folder name
example_service_override and create info file in it example_service_override.info.yml 

file:

/example_service_override
   example_service_override.info.yml
name: Example Service Override
description: This is used to override the contrib private message module.
package: Custom
type: module
version: 1.0
core: 8.x

 

Step 2: Create Src folder and ExampleServiceOverrideServiceProvider.php 

 

Creating an src file is required and the Eventsubscriber folder is optional, Creating a Service provider file we need to follow the below rules. 

Note: Module_name in camel case added a prefix to ServiceProvider.php. So in our case, our service provider file name will be 

ExampleServiceOverrideServiceProvider.php 

otherwise, it won’t be recognized automatically.
We will place this file in the src folder as shown below


/example_service_override
   example_service_override.info.yml
   /src
   ExampleServiceOverrideServiceProvider.php
   /EventSubscriber
      MyPrivateService.php

 

Step 3: Now we will add Service ID
 
Now we will follow the below namespace and uses.

<?php
namespace Drupal\example_service_override;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\DependencyInjection\ServiceProviderBase;
use Drupal\Core\DependencyInjection\ServiceModifierInterface;
class ExampleServiceOverrideServiceProvider implements ServiceModifierInterface {
 public function alter(ContainerBuilder $container) {
   if ($container->hasDefinition('private_message.service')) {
     $definition = $container->getDefinition('private_message.service');
     $definition->setClass('Drupal\example_service_override \EventSubscriber\MyPrivateService');
   }
 }
}

 

First of all, we will need to implement the ServiceModifierInterface, and using the alter method I have used optional $container->hasDefinition(‘service_id’) which will give us an error if we have given the wrong service id.

Note: Remember when overriding the service we need the service id. We can find the service id of the private message from private_message.services.yml

/ private_message
   private_message.services.yml

 

In the below picture, we can check the highlighted services.

Image removed.

So we are targeting the 'private_message.service' id and assigning the MyPrivateService class.

 

Step 4: Now we are extending PrivateMessageService add our custom code to it.

 

/ example_service_override
   example_service_override.info.yml
   /src
   ExampleServiceOverrideServiceProvider.php
   /EventSubscriber
      MyPrivateService.php
<?php
namespace Drupal\example_service_override\EventSubscriber;
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Entity\EntityInterface; 
use Drupal\private_message\Service\PrivateMessageService;
use Drupal\user\UserInterface;
class MyPrivateService extends PrivateMessageService {
  /**
   * {@inheritdoc}
   */
  public function createRenderablePrivateMessageThreadLink(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
    $result = parent::createRenderablePrivateMessageThreadLink($build, $entity, $display, $view_mode);
// You can paste the original code and make changes here 
// So your custom code comes here
        return $result;
  }
}
 

In the above method “createRenderablePrivateMessageThreadLink” two additional things we need to do, Firstly

$result = parent::createRenderablePrivateMessage

ThreadLink($build, $entity, $display, $view_mode); Secondly we need to return the $result. Due to which the contrib module method createRenderablePrivateMessageThreadLink will not call the contrib module instead it will call the custom module method. After that, you can enable the example_service_override module,

Thanks, Riaz

riaz
Sr. Drupal Developer/ Module Developer

comments

5 June 2023

The note: "Note: Module_name in camel case added a prefix to ServiceProvider.php.", this is no longer required, you can give the name you want.

5 June 2023

Yes Agree with you, Thanks for the corrections.

Add new comment