1: <?php
2:
3: 4: 5: 6:
7:
8: namespace Nette\DI;
9:
10: use Nette;
11:
12:
13: 14: 15: 16: 17:
18: class Helpers
19: {
20:
21: 22: 23: 24: 25: 26: 27: 28:
29: public static function expand($var, array $params, $recursive = FALSE)
30: {
31: if (is_array($var)) {
32: $res = array();
33: foreach ($var as $key => $val) {
34: $res[$key] = self::expand($val, $params, $recursive);
35: }
36: return $res;
37:
38: } elseif ($var instanceof Statement) {
39: return new Statement(self::expand($var->entity, $params, $recursive), self::expand($var->arguments, $params, $recursive));
40:
41: } elseif (!is_string($var)) {
42: return $var;
43: }
44:
45: $parts = preg_split('#%([\w.-]*)%#i', $var, -1, PREG_SPLIT_DELIM_CAPTURE);
46: $res = '';
47: foreach ($parts as $n => $part) {
48: if ($n % 2 === 0) {
49: $res .= $part;
50:
51: } elseif ($part === '') {
52: $res .= '%';
53:
54: } elseif (isset($recursive[$part])) {
55: throw new Nette\InvalidArgumentException('Circular reference detected for variables: ' . implode(', ', array_keys($recursive)) . '.');
56:
57: } else {
58: $val = Nette\Utils\Arrays::get($params, explode('.', $part));
59: if ($recursive) {
60: $val = self::expand($val, $params, (is_array($recursive) ? $recursive : array()) + array($part => 1));
61: }
62: if (strlen($part) + 2 === strlen($var)) {
63: return $val;
64: }
65: if (!is_scalar($val)) {
66: throw new Nette\InvalidArgumentException("Unable to concatenate non-scalar parameter '$part' into '$var'.");
67: }
68: $res .= $val;
69: }
70: }
71: return $res;
72: }
73:
74:
75: 76: 77: 78: 79:
80: public static function escape($value)
81: {
82: if (is_array($value)) {
83: array_walk_recursive($value, function(&$val) {
84: $val = is_string($val) ? str_replace('%', '%%', $val) : $val;
85: });
86: } elseif (is_string($value)) {
87: $value = str_replace('%', '%%', $value);
88: }
89: return $value;
90: }
91:
92:
93: 94: 95: 96: 97:
98: public static function autowireArguments(\ReflectionFunctionAbstract $method, array $arguments, $container)
99: {
100: $optCount = 0;
101: $num = -1;
102: $res = array();
103:
104: foreach ($method->getParameters() as $num => $parameter) {
105: if (array_key_exists($num, $arguments)) {
106: $res[$num] = $arguments[$num];
107: unset($arguments[$num]);
108: $optCount = 0;
109:
110: } elseif (array_key_exists($parameter->getName(), $arguments)) {
111: $res[$num] = $arguments[$parameter->getName()];
112: unset($arguments[$parameter->getName()]);
113: $optCount = 0;
114:
115: } elseif ($class = $parameter->getClassName()) {
116: $res[$num] = $container->getByType($class, FALSE);
117: if ($res[$num] === NULL) {
118: if ($parameter->allowsNull()) {
119: $optCount++;
120: } else {
121: throw new ServiceCreationException("No service of type {$class} found. Make sure the type hint in $method is written correctly and service of this type is registered.");
122: }
123: } else {
124: if ($container instanceof ContainerBuilder) {
125: $res[$num] = '@' . $res[$num];
126: }
127: $optCount = 0;
128: }
129:
130: } elseif ($parameter->isOptional()) {
131:
132: $res[$num] = $parameter->isDefaultValueAvailable() ? $parameter->getDefaultValue() : NULL;
133: $optCount++;
134:
135: } else {
136: throw new ServiceCreationException("$parameter has no type hint, so its value must be specified.");
137: }
138: }
139:
140:
141: while (array_key_exists(++$num, $arguments)) {
142: $res[$num] = $arguments[$num];
143: unset($arguments[$num]);
144: $optCount = 0;
145: }
146: if ($arguments) {
147: throw new ServiceCreationException("Unable to pass specified arguments to $method.");
148: }
149:
150: return $optCount ? array_slice($res, 0, -$optCount) : $res;
151: }
152:
153: }
154: