├── README.md ├── test_decorator_a ├── src │ └── TestDecoratorA.php ├── test_decorator_a.info.yml └── test_decorator_a.services.yml ├── test_decorator_chain ├── src │ └── TestDecoratorChain.php ├── test_decorator_chain.info.yml └── test_decorator_chain.services.yml ├── test_decorator_core ├── src │ ├── TestDecoratorCore.php │ └── TestDecoratorInterface.php ├── test_decorator_core.info.yml ├── test_decorator_core.module └── test_decorator_core.services.yml ├── test_decorator_higher ├── src │ └── TestDecoratorHigher.php ├── test_decorator_higher.info.yml └── test_decorator_higher.services.yml ├── test_decorator_inter ├── src │ └── TestDecoratorInter.php ├── test_decorator_inter.info.yml └── test_decorator_inter.services.yml ├── test_decorator_lower ├── src │ └── TestDecoratorLower.php ├── test_decorator_lower.info.yml └── test_decorator_lower.services.yml └── test_decorator_protect ├── src └── TestDecoratorProtect.php ├── test_decorator_protect.info.yml └── test_decorator_protect.services.yml /README.md: -------------------------------------------------------------------------------- 1 | This gives several examples of using Symfony decorators in Drupal 8. 2 | 3 | See the Phase2 blog for details. 4 | 5 | To play with this, first enable the `test_decorator_core` module, which 6 | provides the core service being overridden. 7 | 8 | Then, enable different combination of the other decorator modules and run 9 | the `drush php-eval "test_decorator_core()"` command to see which order the 10 | different services run. 11 | 12 | For example, enable `test_decorator_a` and run `drush php-eval "test_decorator_core()"` and you should see: 13 | ``` 14 | Decorator A Public 15 | Core Protected 16 | Core Public 17 | ``` 18 | which shows that the test_decorator_a ran first followed by the normal 19 | core service. 20 | 21 | ## test_decorator_a 22 | A simple decorator that extends the core service. 23 | 24 | ## test_decorator_inter 25 | Implements the core service interface rather than subclassing. 26 | 27 | ## test_decorator_lower 28 | A subclass decorator with a lower priority than decorator_a. 29 | 30 | ## test_decorator_higher 31 | A subclass decorator with a higher priorty than decorator_a. 32 | 33 | ## test_decorator_chain 34 | Yet another subclass decorator with the same priority as decorator_a. 35 | 36 | ## test_decorator_protect 37 | A subclass decorator that overrides a protected method. -------------------------------------------------------------------------------- /test_decorator_a/src/TestDecoratorA.php: -------------------------------------------------------------------------------- 1 | testDecorator = $test_decorator; 20 | parent::__construct(); 21 | } 22 | 23 | /** 24 | * {@inheritdoc} 25 | */ 26 | public function publicFunction() { 27 | print "Decorator A Public\n"; 28 | $this->testDecorator->publicFunction(); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /test_decorator_a/test_decorator_a.info.yml: -------------------------------------------------------------------------------- 1 | name: Test DecoratorA 2 | type: module 3 | description: 'Single Decorator.' 4 | package: Development 5 | core: 8.x 6 | dependencies: 7 | - test_decorator_core 8 | -------------------------------------------------------------------------------- /test_decorator_a/test_decorator_a.services.yml: -------------------------------------------------------------------------------- 1 | services: 2 | test_decorator.decoratorA: 3 | class: Drupal\test_decorator_a\TestDecoratorA 4 | public: false 5 | decorates: test_decorator.core 6 | decoration_priority: 5 7 | arguments: ['@test_decorator.decoratorA.inner'] 8 | -------------------------------------------------------------------------------- /test_decorator_chain/src/TestDecoratorChain.php: -------------------------------------------------------------------------------- 1 | testDecorator = $test_decorator; 20 | parent::__construct(); 21 | } 22 | 23 | /** 24 | * {@inheritdoc} 25 | */ 26 | public function publicFunction() { 27 | print "Decorator CHAIN Public\n"; 28 | $this->testDecorator->protectedFunction(); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /test_decorator_chain/test_decorator_chain.info.yml: -------------------------------------------------------------------------------- 1 | name: Test Decorator Chain 2 | type: module 3 | description: 'A decorator that chains onto another.' 4 | package: Development 5 | core: 8.x 6 | dependencies: 7 | - test_decorator_core 8 | -------------------------------------------------------------------------------- /test_decorator_chain/test_decorator_chain.services.yml: -------------------------------------------------------------------------------- 1 | services: 2 | test_decorator.decoratorChain: 3 | class: Drupal\test_decorator_chain\TestDecoratorChain 4 | public: false 5 | decorates: test_decorator.core 6 | decoration_priority: 3 7 | arguments: ['@test_decorator.decoratorChain.inner'] 8 | 9 | -------------------------------------------------------------------------------- /test_decorator_core/src/TestDecoratorCore.php: -------------------------------------------------------------------------------- 1 | protectedFunction(); 24 | print "Core Public\n"; 25 | } 26 | 27 | /** 28 | * {@inheritdoc} 29 | */ 30 | public function runService() { 31 | $this->publicFunction(); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /test_decorator_core/src/TestDecoratorInterface.php: -------------------------------------------------------------------------------- 1 | runService(); 19 | } 20 | -------------------------------------------------------------------------------- /test_decorator_core/test_decorator_core.services.yml: -------------------------------------------------------------------------------- 1 | services: 2 | test_decorator.core: 3 | class: Drupal\test_decorator_core\TestDecoratorCore 4 | arguments: [] 5 | -------------------------------------------------------------------------------- /test_decorator_higher/src/TestDecoratorHigher.php: -------------------------------------------------------------------------------- 1 | testDecorator = $test_decorator; 20 | parent::__construct(); 21 | } 22 | 23 | /** 24 | * {@inheritdoc} 25 | */ 26 | public function publicFunction() { 27 | print "Decorator HIGHER Public\n"; 28 | $this->testDecorator->publicFunction(); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /test_decorator_higher/test_decorator_higher.info.yml: -------------------------------------------------------------------------------- 1 | name: Test Decorator Higher 2 | type: module 3 | description: 'Decorator with higher priority.' 4 | package: Development 5 | core: 8.x 6 | dependencies: 7 | - test_decorator_core 8 | -------------------------------------------------------------------------------- /test_decorator_higher/test_decorator_higher.services.yml: -------------------------------------------------------------------------------- 1 | services: 2 | test_decorator.decoratorHigher: 3 | class: Drupal\test_decorator_higher\TestDecoratorHigher 4 | public: false 5 | decorates: test_decorator.core 6 | decoration_priority: 9 7 | arguments: ['@test_decorator.decoratorHigher.inner'] 8 | -------------------------------------------------------------------------------- /test_decorator_inter/src/TestDecoratorInter.php: -------------------------------------------------------------------------------- 1 | testDecorator = $test_decorator; 20 | } 21 | 22 | /** 23 | * {@inheritdoc} 24 | */ 25 | public function publicFunction() { 26 | print "Decorator INTERFACE injection Public\n"; 27 | $this->testDecorator->publicFunction(); 28 | } 29 | 30 | /** 31 | * {@inheritdoc} 32 | */ 33 | public function runService() { 34 | $this->publicFunction(); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /test_decorator_inter/test_decorator_inter.info.yml: -------------------------------------------------------------------------------- 1 | name: Test Decorator Inter 2 | type: module 3 | description: 'Test decorator with object interface instead of extend.' 4 | package: Development 5 | core: 8.x 6 | dependencies: 7 | - test_decorator_core 8 | -------------------------------------------------------------------------------- /test_decorator_inter/test_decorator_inter.services.yml: -------------------------------------------------------------------------------- 1 | services: 2 | test_decorator.decoratorInter: 3 | class: Drupal\test_decorator_inter\TestDecoratorInter 4 | public: false 5 | decorates: test_decorator.core 6 | decoration_priority: 4 7 | arguments: ['@test_decorator.decoratorInter.inner'] 8 | -------------------------------------------------------------------------------- /test_decorator_lower/src/TestDecoratorLower.php: -------------------------------------------------------------------------------- 1 | testDecorator = $test_decorator; 20 | parent::__construct(); 21 | } 22 | 23 | /** 24 | * {@inheritdoc} 25 | */ 26 | public function publicFunction() { 27 | print "Decorator LOWER Public\n"; 28 | $this->testDecorator->publicFunction(); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /test_decorator_lower/test_decorator_lower.info.yml: -------------------------------------------------------------------------------- 1 | name: Test Decorator Lower 2 | type: module 3 | description: 'Test decorator with lower priority.' 4 | package: Development 5 | core: 8.x 6 | dependencies: 7 | - test_decorator_core 8 | -------------------------------------------------------------------------------- /test_decorator_lower/test_decorator_lower.services.yml: -------------------------------------------------------------------------------- 1 | services: 2 | test_decorator.decoratorLower: 3 | class: Drupal\test_decorator_lower\TestDecoratorLower 4 | public: false 5 | decorates: test_decorator.core 6 | decoration_priority: 3 7 | arguments: ['@test_decorator.decoratorLower.inner'] 8 | -------------------------------------------------------------------------------- /test_decorator_protect/src/TestDecoratorProtect.php: -------------------------------------------------------------------------------- 1 | testDecorator = $test_decorator; 20 | parent::__construct(); 21 | } 22 | 23 | /** 24 | * {@inheritdoc} 25 | */ 26 | public function publicFunction() { 27 | print "Decorator PROTECT Public\n"; 28 | // NOTE: We need to call parent::public here to get our overridden 29 | // protected function to be called. 30 | parent::publicFunction(); 31 | // NOTE: You should NOT do the following: 32 | // $this->testDecorator->publicFunction() 33 | // because then it will call the protected function of the inner service 34 | // rather than calling our override below. 35 | } 36 | 37 | protected function protectedFunction() { 38 | print "Decorator PROTECT Protected\n"; 39 | // You can still call the parent protected function if you don't need 40 | // to completely replace it. 41 | parent::protectedFunction(); 42 | // NOTE: You CANNOT do the following: 43 | // $this->testDecorator->protectedFunction() 44 | // Because you can only call public methods of the inner decorator. 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /test_decorator_protect/test_decorator_protect.info.yml: -------------------------------------------------------------------------------- 1 | name: Test Decorator Protect 2 | type: module 3 | description: 'Override protected method via decorator.' 4 | package: Development 5 | core: 8.x 6 | dependencies: 7 | - test_decorator_core 8 | -------------------------------------------------------------------------------- /test_decorator_protect/test_decorator_protect.services.yml: -------------------------------------------------------------------------------- 1 | services: 2 | test_decorator.decoratorProtect: 3 | class: Drupal\test_decorator_protect\TestDecoratorProtect 4 | public: false 5 | decorates: test_decorator.core 6 | decoration_priority: 10 7 | arguments: ['@test_decorator.decoratorProtect.inner'] 8 | --------------------------------------------------------------------------------