PropertyInfoExtractor.php 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\PropertyInfo;
  11. use Symfony\Component\PropertyInfo\Util\LegacyTypeConverter;
  12. use Symfony\Component\TypeInfo\Type;
  13. /**
  14. * Default {@see PropertyInfoExtractorInterface} implementation.
  15. *
  16. * @author Kévin Dunglas <dunglas@gmail.com>
  17. *
  18. * @final
  19. */
  20. class PropertyInfoExtractor implements PropertyInfoExtractorInterface, PropertyInitializableExtractorInterface
  21. {
  22. /**
  23. * @param iterable<mixed, PropertyListExtractorInterface> $listExtractors
  24. * @param iterable<mixed, PropertyTypeExtractorInterface> $typeExtractors
  25. * @param iterable<mixed, PropertyDescriptionExtractorInterface> $descriptionExtractors
  26. * @param iterable<mixed, PropertyAccessExtractorInterface> $accessExtractors
  27. * @param iterable<mixed, PropertyInitializableExtractorInterface> $initializableExtractors
  28. */
  29. public function __construct(
  30. private readonly iterable $listExtractors = [],
  31. private readonly iterable $typeExtractors = [],
  32. private readonly iterable $descriptionExtractors = [],
  33. private readonly iterable $accessExtractors = [],
  34. private readonly iterable $initializableExtractors = [],
  35. ) {
  36. }
  37. public function getProperties(string $class, array $context = []): ?array
  38. {
  39. return $this->extract($this->listExtractors, 'getProperties', [$class, $context]);
  40. }
  41. public function getShortDescription(string $class, string $property, array $context = []): ?string
  42. {
  43. return $this->extract($this->descriptionExtractors, 'getShortDescription', [$class, $property, $context]);
  44. }
  45. public function getLongDescription(string $class, string $property, array $context = []): ?string
  46. {
  47. return $this->extract($this->descriptionExtractors, 'getLongDescription', [$class, $property, $context]);
  48. }
  49. public function getType(string $class, string $property, array $context = []): ?Type
  50. {
  51. foreach ($this->typeExtractors as $extractor) {
  52. if (!method_exists($extractor, 'getType')) {
  53. $legacyTypes = $extractor->getTypes($class, $property, $context);
  54. if (null !== $legacyTypes) {
  55. return LegacyTypeConverter::toTypeInfoType($legacyTypes);
  56. }
  57. continue;
  58. }
  59. if (null !== $value = $extractor->getType($class, $property, $context)) {
  60. return $value;
  61. }
  62. }
  63. return null;
  64. }
  65. public function getTypes(string $class, string $property, array $context = []): ?array
  66. {
  67. return $this->extract($this->typeExtractors, 'getTypes', [$class, $property, $context]);
  68. }
  69. public function isReadable(string $class, string $property, array $context = []): ?bool
  70. {
  71. return $this->extract($this->accessExtractors, 'isReadable', [$class, $property, $context]);
  72. }
  73. public function isWritable(string $class, string $property, array $context = []): ?bool
  74. {
  75. return $this->extract($this->accessExtractors, 'isWritable', [$class, $property, $context]);
  76. }
  77. public function isInitializable(string $class, string $property, array $context = []): ?bool
  78. {
  79. return $this->extract($this->initializableExtractors, 'isInitializable', [$class, $property, $context]);
  80. }
  81. /**
  82. * Iterates over registered extractors and return the first value found.
  83. *
  84. * @param iterable<mixed, object> $extractors
  85. * @param list<mixed> $arguments
  86. */
  87. private function extract(iterable $extractors, string $method, array $arguments): mixed
  88. {
  89. foreach ($extractors as $extractor) {
  90. if (null !== $value = $extractor->{$method}(...$arguments)) {
  91. return $value;
  92. }
  93. }
  94. return null;
  95. }
  96. }