Keeping Kittens Safe

While Altering Drupal Core

Drupalcon Nashville

Presented By
Geoff Appleby
https://gapple.github.io/presentation-kittens-safe/

Service Container

Service Container

                                  my_module.my_service:
                                    class: Drupal\my_module\MyService
                                    arguments: [ '@config.factory' ]
							    
my_module/my_module.services.yml
Service Container

                                    class MyService {

                                      /**
                                       * The Config Factory Service.
                                       *
                                       * @var \Drupal\Core\Config\ConfigFactoryInterface
                                       */
                                      private $configFactory;

                                      /**
                                       * Constructs the Example service.
                                       *
                                       * @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
                                       */
                                      public function __construct(ConfigFactoryInterface $configFactory) {
                                        $this->configFactory = $configFactory;
                                      }

                                    }
							    
my_module/src/MyService.php
Service Container

                                    function my_module_example() {
                                        $myService = \Drupal::service('my_module.my_service');
                                    }
							    
my_module/my_module.module
Service Container

Benefits

  • Testing
  • Lazy Loading
  • Overriding

Altering Services

Altering Services

                                    namespace Drupal\my_module;

                                    class MyModuleServiceProvider extends ServiceProviderBase {

                                      /**
                                       * {@inheritdoc}
                                       */
                                      public function alter(ContainerBuilder $container) {
                                        $definition = $container->getDefinition('some_core_service');
                                        $definition->setClass('Drupal\my_module\MyCoreOverrideService');
                                      }

                                    }
							    
my_module/src/MyModuleServiceProvider.php
Altering Services

                                    namespace Drupal\my_module;

                                    class MyCoreOverrideService implements SomeCoreServiceInterface {

                                      public function reimplement() {
                                        // ...
                                      }

                                      public function every() {
                                        // ...
                                      }

                                      public function interface() {
                                        // ...
                                      }

                                      public function method() {
                                        // ...
                                      }

                                    }
							    
my_module/src/MyModuleServiceProvider.php
Altering Services

                                    namespace Drupal\my_module;

                                    class MyCoreOverrideService extends SomeCoreService {

                                      public function onlyTheOverriddenMethod() {
                                        // ...

                                        $someDataFromTheOriginalService =
                                          parent::methodFromTheOrginalService();
                                      }

                                    }
							    
my_module/src/MyModuleServiceProvider.php
Altering Services
  • CoreService
  • ContribModuleService extends CoreService
  • CustomModuleService extends CoreService

Decorating Services

Decorating Services

                                    services:
                                      my_module.core_service_decorator:
                                        class: Drupal\my_module\CoreServiceDecorator
                                        arguments: [ '@my_module.core_service_decorator.inner', '@config.factory']
                                        decorates: core_service
							    
my_module/my_module.services.yml
Decorating Services

                                    namespace Drupal\my_module;

                                    class CoreServiceDecorator implements SomeCoreServiceInterface {

                                      public function __construct(
                                        CoreServiceInterface $coreService,
                                        ConfigFactoryInterface $configFactory
                                      ) {
                                        $this->coreService = $coreService;
                                        $this->configFactory = $configFactory;
                                      }

                                      public function method() {
                                        $coreServiceData = $this->coreService->method();

                                        return $data;
                                      }

                                    }
							    
my_module/src/MyModuleServiceProvider.php
Decorating Services

                                    namespace Drupal\my_module;

                                    class CoreServiceDecorator implements SomeCoreServiceInterface {

                                      public function proxy() {
                                        return $this->coreService->proxy();
                                      }

                                      public function every() {
                                        return $this->coreService->every();
                                      }

                                      public function interface() {
                                        return $this->coreService->interface();
                                      }

                                      public function method() {
                                        return $this->coreService->method();
                                      }

                                    }
							    
my_module/src/MyModuleServiceProvider.php
Decorating Services
  • CoreService
    • ContribModuleServiceDecorator
      • CustomModuleServiceDecorator
Decorating Services

                                    services:
                                      my_module.core_service_decorator:
                                        class: Drupal\my_module\CoreServiceDecorator
                                        arguments: [ '@my_module.core_service_decorator.inner', '@config.factory']
                                        decorates: core_service
                                        decoration_priority: 5
							    
my_module/my_module.services.yml
Decorating Services
  • CoreService
    • CustomModuleServiceDecorator (priority 5)
      • ContribModuleServiceDecorator (priority 0)
IE9 Compatibility

                                    services:
                                      ie9.css.collection_renderer:
                                        class: Drupal\ie9\Asset\CssCollectionRenderer
                                        arguments: [ '@state' , '@ie9.css.collection_renderer.inner' ]
                                        decorates: asset.css.collection_renderer
							    
ie9/ie9.services.yml
IE9 Compatibility

                                    namespace Drupal\ie9\Asset;

                                    class CssCollectionRenderer implements AssetCollectionRendererInterface {

                                      public function __construct(StateInterface $state, AssetCollectionRendererInterface $cssCollectionRenderer) {
                                        $this->state = $state;
                                        $this->originalCssCollectionRenderer = $cssCollectionRenderer;
                                      }

                                      public function render(array $css_assets) {
                                        if (count($css_assets) <= 31) {
                                          return $this->originalCssCollectionRenderer->render($css_assets);
                                        }

                                        // Render for IE9...

                                        return $elements;
                                      }
                                    }
							    
ie9/src/Asset/CssCollectionRenderer.php

Join us for contribution sprints

Friday, April 13, 2018

Mentored
Core Sprint

9:00 - 18:00
Room: 103

First time
sprinter workshop

9:00 - 12:00
Room: 101

General
Sprint

9:00 - 18:00
Room: 104

#drupalsprint

What did you think?

Locate this session at the DrupalCon Nashville Website:

https://nashville2018.drupal.org/schedule

Take the Survey!

https://www.surveymonkey.com/r/DrupalConNashville