/** * @param string $route * @param array $constraints * @return array * @throws \RuntimeException */ protected function tokens($route, array $constraints = []) { $currentPos = 0; $length = strlen($route); $level = 0; $token = '(\\G(?P<literal>[^{}\\[\\]]*)(?P<token>[{}\\[\\]]|$))'; $tokens = []; $variable = '(\\G\\s*(?P<name>[a-zA-Z0-9_]++)?\\s*(?(1):)?\\s*(?P<constraint>[^{}]*(?:\\{(?-1)\\}[^{}]*)*)?)'; while ($currentPos < $length) { preg_match($token, $route, $match, 0, $currentPos); $currentPos += strlen($match[0]); '' !== $match['literal'] && ($tokens[] = ['literal', $match['literal']]); if ('{' === $match['token']) { preg_match($variable, $route, $match, 0, $currentPos); $currentPos += strlen($match[0]); $tokens[] = ['param', $match['name'], $this->expression($this->constraint($match['name'], $match['constraint'], $constraints))]; continue; } if ('[' === $match['token']) { $tokens[] = ['optional-start']; $level++; continue; } if (']' === $match['token']) { $tokens[] = ['optional-end']; --$level < 0 && Exception::runtime('Found closing bracket without matching opening bracket'); continue; } } $level > 0 && Exception::runtime('Found unbalanced brackets'); return $tokens; }
/** * */ function test_runtime_exception() { try { Exception::runtime('foo'); } catch (\Exception $exception) { } $this->assertEquals('foo', $exception->getMessage()); $this->assertEquals(__FILE__, $exception->getFile()); $this->assertEquals(22, $exception->getLine()); $this->assertInstanceOf(Runtime::class, $exception); }
/** * @param Route $parent * @param array|Route $route * @param array $path * @param bool $start * @return array|Route * @throws \RuntimeException */ function __invoke(Route $parent, $route, array $path, $start = false) { if ($root = $parent->child($path[0])) { return $this($root, $route, array_slice($path, 1)); } isset($path[1]) && Exception::runtime('Parent route not found: ' . $route[Arg::NAME]); $route[Arg::NAME] = $path[0]; $start && empty($route[Arg::ROUTE]) && isset($route[Arg::NAME]) && ($route[Arg::ROUTE] = $route[Arg::NAME]); !$start && empty($route[Arg::ROUTE]) && ($route[Arg::ROUTE] = Arg::SEPARATOR . $path[0]); $route = $this->definition($route); $parent->add($path[0], $route); return $route; }
/** * @param callable|object $config * @param array $args * @param callable $callback * @return mixed */ protected static function signal(callable $config, array $args = [], callable $callback = null) { if ($args && !is_string(key($args))) { return call_user_func_array($config, $args); } $function = null; $matched = []; $method = '__invoke'; $params = []; if (is_string($config)) { $static = explode('::', $config); if (isset($static[1])) { list($config, $method) = $static; } else { $params = (new ReflectionFunction($config))->getParameters(); $function = $config; } } is_array($config) && (list($config, $method) = $config); !$function && ($params = (new ReflectionMethod($config, $method))->getParameters()); foreach ($params as $param) { if (isset($args[$param->name])) { $matched[] = $args[$param->name]; continue; } if (Arg::ARGS === $param->name) { $matched[] = $param->isVariadic() ? new Plugin\SignalArgs($args) : $args; continue; } if ($param->isOptional()) { $param->isDefaultValueAvailable() && ($matched[] = $param->getDefaultValue()); continue; } if ($callback && null !== ($match = $callback($param->name))) { $matched[] = $match; continue; } if ($callback && ($hint = $param->getClass())) { $matched[] = $callback($hint->name); continue; } Exception::runtime('Missing required parameter $' . $param->name . ' for ' . ($function ?: (is_string($config) ? $config : get_class($config)))); } return call_user_func_array($function ?: [$config, $method], $params ? $matched : $args); }
/** * */ function test_runtime() { $this->setExpectedException(Runtime::class, 'foo'); Exception::runtime('foo'); }
/** * @param string $name * @return null */ protected function initializing($name) { !empty($this->pending[$name]) && Exception::runtime('Circular dependency: ' . $name); $this->pending[$name] = true; return null; }
/** * @return callable|Manager|Service */ static function service() { return static::$service ?: Exception::runtime('Service does not exist'); }
/** * @param string $name * @param null $config * @return null|object|callable */ protected function initialize($name, $config = null) { !empty($this->pending[$name]) && Exception::runtime('Circular dependency: ' . $name); $this->pending[$name] = true; return $this->initialized($name, $this->plugin($config ?: $name)); }
/** * @param string $name * @param array $args * @return callable|object */ protected function make($name, array $args = []) { $class = new \ReflectionClass($name); if (!$class->hasMethod('__construct')) { return $class->newInstanceWithoutConstructor(); } if ($args && !is_string(key($args))) { return $class->newInstanceArgs($args); } $matched = []; $params = $class->getConstructor()->getParameters(); foreach ($params as $param) { if (isset($args[$param->name])) { $matched[] = $args[$param->name]; continue; } if ($param->isOptional()) { $param->isDefaultValueAvailable() && ($matched[] = $param->getDefaultValue()); continue; } if (null !== ($hint = $param->getClass()) && null !== ($match = $this($hint->name))) { $matched[] = $match; continue; } if (null !== ($match = $this($param->name))) { $matched[] = $match; continue; } Exception::runtime('Missing required parameter $' . $param->name . ' for ' . $name); } return $class->newInstanceArgs($params ? $matched : $args); }