
How to Override Drupal 8/9 Contrib Module Service with Example:
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”
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.
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
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.