protected function findFirstEligibleTypeConverterInObjectHierarchy($source, $sourceType, $targetType)
{
$targetClass = TypeHandling::truncateElementType($targetType);
if (!class_exists($targetClass) && !interface_exists($targetClass)) {
throw new Exception\InvalidTargetException(sprintf('Could not find a suitable type converter for "%s" because no such the class/interface "%s" does not exist.', $targetType, $targetClass), 1297948764);
}
if (!isset($this->typeConverters[$sourceType])) {
return null;
}
$convertersForSource = $this->typeConverters[$sourceType];
if (isset($convertersForSource[$targetClass])) {
$converter = $this->findEligibleConverterWithHighestPriority($convertersForSource[$targetClass], $source, $targetType);
if ($converter !== null) {
return $converter;
}
}
foreach (class_parents($targetClass) as $parentClass) {
if (!isset($convertersForSource[$parentClass])) {
continue;
}
$converter = $this->findEligibleConverterWithHighestPriority($convertersForSource[$parentClass], $source, $targetType);
if ($converter !== null) {
return $converter;
}
}
$converters = $this->getConvertersForInterfaces($convertersForSource, class_implements($targetClass));
$converter = $this->findEligibleConverterWithHighestPriority($converters, $source, $targetType);
if ($converter !== null) {
return $converter;
}
if (isset($convertersForSource['object'])) {
return $this->findEligibleConverterWithHighestPriority($convertersForSource['object'], $source, $targetType);
} else {
return null;
}
}