/** @return string|NULL */
private function resolveEntityClass($entity, $recursive = [])
{
$entity = $this->normalizeEntity($entity instanceof Statement ? $entity->getEntity() : $entity);
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())) {
$name = array_slice(array_keys($recursive), -1);
throw new ServiceCreationException(sprintf("Factory '%s' used in service '%s' is not callable.", Nette\Utils\Callback::toString($entity), $name[0]));
}
return PhpReflection::getReturnType($reflection);
} elseif ($service = $this->getServiceName($entity)) {
// alias or factory
if (Strings::contains($service, '\\')) {
// @\Class
return ltrim($service, '\\');
}
return $this->definitions[$service]->getImplement() ?: $this->resolveServiceClass($service, $recursive);
} elseif (is_string($entity)) {
if (!class_exists($entity) || !(new ReflectionClass($entity))->isInstantiable()) {
$name = array_slice(array_keys($recursive), -1);
throw new ServiceCreationException("Class {$entity} used in service '{$name['0']}' not found or is not instantiable.");
}
return ltrim($entity, '\\');
}
}