1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
|
4
|
|
|
namespace Mouf\Html\Renderer; |
5
|
|
|
|
6
|
|
|
use Interop\Container\ServiceProviderInterface; |
7
|
|
|
use Psr\Container\ContainerInterface; |
8
|
|
|
use Psr\SimpleCache\CacheInterface; |
9
|
|
|
|
10
|
|
|
/** |
11
|
|
|
* This class can be extended to implement easily a service provider that creates "package level" renderers. |
12
|
|
|
*/ |
13
|
|
|
abstract class AbstractPackageRendererServiceProvider implements ServiceProviderInterface |
14
|
|
|
{ |
15
|
|
|
/** |
16
|
|
|
* Returns the path to the templates directory. |
17
|
|
|
* |
18
|
|
|
* @return string |
19
|
|
|
*/ |
20
|
|
|
abstract public static function getTemplateDirectory(): string; |
21
|
|
|
|
22
|
|
|
public static function getPriority(): int |
23
|
|
|
{ |
24
|
|
|
return 0; |
25
|
|
|
} |
26
|
|
|
|
27
|
|
|
/** |
28
|
|
|
* Returns a list of all container entries registered by this service provider. |
29
|
|
|
* |
30
|
|
|
* - the key is the entry name |
31
|
|
|
* - the value is a callable that will return the entry, aka the **factory** |
32
|
|
|
* |
33
|
|
|
* Factories have the following signature: |
34
|
|
|
* function(\Psr\Container\ContainerInterface $container) |
35
|
|
|
* |
36
|
|
|
* @return callable[] |
37
|
|
|
*/ |
38
|
|
|
public function getFactories() |
39
|
|
|
{ |
40
|
|
|
return [ |
|
|
|
|
41
|
|
|
'packageRenderer_'.static::getTemplateDirectory() => [static::class, 'createRenderer'] |
42
|
|
|
]; |
43
|
|
|
} |
44
|
|
|
|
45
|
|
|
public static function createRenderer(ContainerInterface $container): FileBasedRenderer |
46
|
|
|
{ |
47
|
|
|
return new FileBasedRenderer(static::getTemplateDirectory(), $container->get(CacheInterface::class), $container, $container->get(\Twig_Environment::class)); |
48
|
|
|
} |
49
|
|
|
|
50
|
|
|
/** |
51
|
|
|
* Returns a list of all container entries extended by this service provider. |
52
|
|
|
* |
53
|
|
|
* - the key is the entry name |
54
|
|
|
* - the value is a callable that will return the modified entry |
55
|
|
|
* |
56
|
|
|
* Callables have the following signature: |
57
|
|
|
* function(Psr\Container\ContainerInterface $container, $previous) |
58
|
|
|
* or function(Psr\Container\ContainerInterface $container, $previous = null) |
59
|
|
|
* |
60
|
|
|
* About factories parameters: |
61
|
|
|
* |
62
|
|
|
* - the container (instance of `Psr\Container\ContainerInterface`) |
63
|
|
|
* - the entry to be extended. If the entry to be extended does not exist and the parameter is nullable, `null` will be passed. |
64
|
|
|
* |
65
|
|
|
* @return callable[] |
66
|
|
|
*/ |
67
|
|
|
public function getExtensions() |
68
|
|
|
{ |
69
|
|
|
return [ |
|
|
|
|
70
|
|
|
'packageRenderers' => [static::class, 'extendPackageRenderersList'] |
71
|
|
|
]; |
72
|
|
|
} |
73
|
|
|
|
74
|
|
|
public static function extendPackageRenderersList(ContainerInterface $container, \SplPriorityQueue $priorityQueue): \SplPriorityQueue |
|
|
|
|
75
|
|
|
{ |
76
|
|
|
$priorityQueue->insert('packageRenderer_'.static::getTemplateDirectory(), static::getPriority()); |
77
|
|
|
return $priorityQueue; |
78
|
|
|
} |
79
|
|
|
} |
80
|
|
|
|
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.
Let’s take a look at an example:
Our function
my_function
expects aPost
object, and outputs the author of the post. The base classPost
returns a simple string and outputting a simple string will work just fine. However, the child classBlogPost
which is a sub-type ofPost
instead decided to return anobject
, and is therefore violating the SOLID principles. If aBlogPost
were passed tomy_function
, PHP would not complain, but ultimately fail when executing thestrtoupper
call in its body.