private function resolveEntityClass($entity, $recursive = [])
{
$entity = $this->normalizeEntity($entity instanceof Statement ? $entity->getEntity() : $entity);
$serviceName = current(array_slice(array_keys($recursive), -1));
if (is_array($entity)) {
if (($service = $this->getServiceName($entity[0])) || $entity[0] instanceof Statement) {
$entity[0] = $this->resolveEntityClass($entity[0], $recursive);
if (!$entity[0]) {
return;
} elseif (isset($this->definitions[$service]) && $this->definitions[$service]->getImplement()) {
// @Implement::create
return $entity[1] === 'create' ? $this->resolveServiceClass($service, $recursive) : NULL;
}
}
try {
$reflection = Nette\Utils\Callback::toReflection($entity[0] === '' ? $entity[1] : $entity);
$refClass = $reflection instanceof \ReflectionMethod ? $reflection->getDeclaringClass() : NULL;
} catch (\ReflectionException $e) {
}
if (isset($e) || $refClass && (!$reflection->isPublic() || $refClass->isTrait() && !$reflection->isStatic())) {
throw new ServiceCreationException(sprintf("Method %s() used in service '%s' is not callable.", Nette\Utils\Callback::toString($entity), $serviceName));
}
$this->addDependency($reflection);
$type = PhpReflection::getReturnType($reflection);
if ($type && !class_exists($type) && !interface_exists($type)) {
throw new ServiceCreationException(sprintf("Class or interface '%s' not found. Is return type of %s() used in service '%s' correct?", $type, Nette\Utils\Callback::toString($entity), $serviceName));
}
return $type;
} elseif ($service = $this->getServiceName($entity)) {
// alias or factory
if (Strings::contains($service, '\\')) {
// @\Class
return ltrim($service, '\\');
}
return $this->definitions[$service]->getImplement() ?: $this->definitions[$service]->getClass() ?: $this->resolveServiceClass($service, $recursive);
} elseif (is_string($entity)) {
// class
if (!class_exists($entity)) {
throw new ServiceCreationException("Class {$entity} used in service '{$serviceName}' not found.");
}
return ltrim($entity, '\\');
}
}