-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpimple.module
114 lines (95 loc) · 2.88 KB
/
pimple.module
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
<?php
/**
* @file
* The Pimple module.
*/
use Pimple\Container;
/**
* Implements hook_hook_info().
*/
function pimple_hook_info() {
$hooks['pimple_info'] = [
'group' => 'pimple',
];
$hooks['pimple_info_alter'] = [
'group' => 'pimple',
];
return $hooks;
}
/**
* Function builds and returns the container requested.
*
* @param $name
*
* @return Container
*/
function pimple_get_container($name = 'default') {
$containers = &drupal_static(__FUNCTION__, NULL);
// Either a definition or an actual container is stored here.
if (is_null($containers)) {
// Ordinary Drupal info hook.
$info = module_invoke_all('pimple_info');
drupal_alter('pimple_info', $info);
// Object definitions with class, arguments, and method calls.
$containers = array_map('_pimple_get_definition', $info);
}
// If the container doesn't exist, it's best to fail.
if (!isset($containers[$name])) {
throw new RuntimeException('Pimple module found no definition for container "' . $name . '"');
}
if (is_array($containers[$name])) {
$definition = $containers[$name];
$containers[$name] = pimple_object_factory($definition['class'], $definition['arguments'], $definition['calls']);
}
return $containers[$name];
}
/**
* Convert Drupal module hook info into calls to pimple_object_factory().
*
* @param $info
* @return array
*/
function _pimple_get_definition($info) {
// Default object factory parameters for any container.
$defaults = [
'class' => Container::class,
'arguments' => [[]],
'calls' => [],
];
// Merge defaults and keep only keys defined in defaults.
$definition = array_intersect_key(array_merge($defaults, $info), $defaults);
// Merge container values into first constructor argument.
if (isset($info['values'])) {
$definition['arguments'][0] = array_merge($definition['arguments'][0], $info['values']);
}
// Create calls for each provider and optional values.
if (isset($info['providers'])) {
// Convert provider info to object factory calls to container's register
// method.
$definition['calls'] = array_merge($definition['calls'], array_map(function ($info) {
$info = array_merge(['values' => []], $info);
return [
'register',
[pimple_object_factory($info['class']), $info['values']],
];
}, $info['providers']));
}
return $definition;
}
/**
* Create an object and call methods on it.
*
* @see \Symfony\Component\DependencyInjection\ContainerBuilder::createService
* @param $class
* @param array $arguments
* @param array $calls
* @return object
*/
function pimple_object_factory($class, array $arguments = [], array $calls = []) {
$r = new ReflectionClass($class);
$object = $r->getConstructor() ? $r->newInstanceArgs($arguments) : $r->newInstance();
foreach ($calls as $call) {
call_user_func_array([$object, $call[0]], $call[1]);
}
return $object;
}