‪TYPO3CMS  ‪main
TypeConverterRegistry.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
21 
28 {
32  protected array ‪$typeConverters = [];
33 
41  public function ‪add(‪TypeConverterInterface $converter, int $priority, array $sources, string $target): void
42  {
43  foreach ($sources as $source) {
44  if (isset($this->typeConverters[$source][$target][$priority])) {
45  throw new Exception\DuplicateTypeConverterException(
46  sprintf(
47  'There exist at least two type converters which handle the conversion from "%s" to "%s" with priority "%d": %s and %s',
48  $source,
49  $target,
50  $priority,
51  get_class($this->typeConverters[$source][$target][$priority]),
52  get_class($converter)
53  ),
54  1297951378
55  );
56  }
57 
58  $this->typeConverters[$source][$target][$priority] = $converter;
59  }
60  }
61 
67  public function ‪findTypeConverter(string $sourceType, string $targetType): ‪TypeConverterInterface
68  {
69  $converter = null;
70  if (‪TypeHandlingUtility::isSimpleType($targetType)) {
71  if (isset($this->typeConverters[$sourceType][$targetType])) {
72  $converter = $this->‪findEligibleConverterWithHighestPriority($this->typeConverters[$sourceType][$targetType]);
73  }
74  } else {
75  $converter = $this->‪findFirstEligibleTypeConverterInObjectHierarchy($sourceType, $targetType);
76  }
77 
78  if ($converter === null) {
79  throw new Exception\TypeConverterException(
80  'No converter found which can be used to convert from "' . $sourceType . '" to "' . $targetType . '".',
81  1476044883
82  );
83  }
84 
85  return $converter;
86  }
87 
98  protected function ‪findFirstEligibleTypeConverterInObjectHierarchy(string $sourceType, string $targetClass): ?‪TypeConverterInterface
99  {
100  if (!class_exists($targetClass) && !interface_exists($targetClass)) {
101  throw new Exception\InvalidTargetException('Could not find a suitable type converter for "' . $targetClass . '" because no such class or interface exists.', 1297948764);
102  }
103 
104  if (!isset($this->typeConverters[$sourceType])) {
105  return null;
106  }
107 
108  $convertersForSource = $this->typeConverters[$sourceType];
109  if (isset($convertersForSource[$targetClass])) {
110  $converter = $this->‪findEligibleConverterWithHighestPriority($convertersForSource[$targetClass]);
111  if ($converter !== null) {
112  return $converter;
113  }
114  }
115 
116  foreach (class_parents($targetClass) as $parentClass) {
117  if (!isset($convertersForSource[$parentClass])) {
118  continue;
119  }
120 
121  $converter = $this->‪findEligibleConverterWithHighestPriority($convertersForSource[$parentClass]);
122  if ($converter !== null) {
123  return $converter;
124  }
125  }
126 
127  $implementedInterface = class_implements($targetClass);
129  $implementedInterface = $implementedInterface === false ? [] : $implementedInterface;
130  $implementedInterface = array_keys($implementedInterface);
131 
132  $converters = $this->‪getConvertersForInterfaces($convertersForSource, $implementedInterface);
133  $converter = $this->‪findEligibleConverterWithHighestPriority($converters);
134 
135  if ($converter !== null) {
136  return $converter;
137  }
138  if (isset($convertersForSource['object'])) {
139  return $this->‪findEligibleConverterWithHighestPriority($convertersForSource['object']);
140  }
141  return null;
142  }
143 
148  {
149  if ($converters === []) {
150  return null;
151  }
152 
153  krsort($converters, SORT_NUMERIC);
154  reset($converters);
155  return current($converters);
156  }
157 
166  protected function ‪getConvertersForInterfaces(array $convertersForSource, array $interfaceNames): array
167  {
168  $convertersForInterface = [];
169  foreach ($interfaceNames as $implementedInterface) {
170  if (isset($convertersForSource[$implementedInterface])) {
171  foreach ($convertersForSource[$implementedInterface] as $priority => $converter) {
172  if (isset($convertersForInterface[$priority])) {
173  throw new Exception\DuplicateTypeConverterException(
174  sprintf(
175  'There exist at least two converters which handle the conversion to an interface with priority "%d". %s and %s',
176  $priority,
177  get_class($convertersForInterface[$priority]),
178  get_class($converter)
179  ),
180  1297951338
181  );
182  }
183  $convertersForInterface[$priority] = $converter;
184  }
185  }
186  }
187  return $convertersForInterface;
188  }
189 }
‪TYPO3\CMS\Extbase\Utility\TypeHandlingUtility\isSimpleType
‪static isSimpleType(string $type)
Definition: TypeHandlingUtility.php:107
‪TYPO3\CMS\Extbase\Property\TypeConverterInterface
Definition: TypeConverterInterface.php:26
‪TYPO3\CMS\Extbase\Property\TypeConverterRegistry\$typeConverters
‪array $typeConverters
Definition: TypeConverterRegistry.php:32
‪TYPO3\CMS\Extbase\Property\TypeConverterRegistry\findTypeConverter
‪findTypeConverter(string $sourceType, string $targetType)
Definition: TypeConverterRegistry.php:67
‪TYPO3\CMS\Extbase\Property
‪TYPO3\CMS\Extbase\Property\TypeConverterRegistry
Definition: TypeConverterRegistry.php:28
‪TYPO3\CMS\Extbase\Utility\TypeHandlingUtility
Definition: TypeHandlingUtility.php:29
‪TYPO3\CMS\Extbase\Property\TypeConverterRegistry\findFirstEligibleTypeConverterInObjectHierarchy
‪findFirstEligibleTypeConverterInObjectHierarchy(string $sourceType, string $targetClass)
Definition: TypeConverterRegistry.php:98
‪TYPO3\CMS\Extbase\Property\TypeConverterRegistry\getConvertersForInterfaces
‪TypeConverterInterface[] getConvertersForInterfaces(array $convertersForSource, array $interfaceNames)
Definition: TypeConverterRegistry.php:166
‪TYPO3\CMS\Extbase\Property\TypeConverterRegistry\findEligibleConverterWithHighestPriority
‪findEligibleConverterWithHighestPriority(array $converters)
Definition: TypeConverterRegistry.php:147
‪TYPO3\CMS\Extbase\Property\TypeConverterRegistry\add
‪add(TypeConverterInterface $converter, int $priority, array $sources, string $target)
Definition: TypeConverterRegistry.php:41