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