vendor/nelmio/api-doc-bundle/ApiDocGenerator.php line 55

Open in your IDE?
  1. <?php
  2. /*
  3. * This file is part of the NelmioApiDocBundle package.
  4. *
  5. * (c) Nelmio
  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 Nelmio\ApiDocBundle;
  11. use Nelmio\ApiDocBundle\Describer\DescriberInterface;
  12. use Nelmio\ApiDocBundle\Describer\ModelRegistryAwareInterface;
  13. use Nelmio\ApiDocBundle\Model\ModelRegistry;
  14. use Nelmio\ApiDocBundle\ModelDescriber\ModelDescriberInterface;
  15. use Nelmio\ApiDocBundle\OpenApiPhp\ModelRegister;
  16. use Nelmio\ApiDocBundle\OpenApiPhp\Util;
  17. use OpenApi\Analysis;
  18. use OpenApi\Annotations\OpenApi;
  19. use OpenApi\Generator;
  20. use Psr\Cache\CacheItemPoolInterface;
  21. use Psr\Log\LoggerAwareTrait;
  22. final class ApiDocGenerator
  23. {
  24. use LoggerAwareTrait;
  25. /** @var OpenApi */
  26. private $openApi;
  27. /** @var iterable|DescriberInterface[] */
  28. private $describers;
  29. /** @var iterable|ModelDescriberInterface[] */
  30. private $modelDescribers;
  31. /** @var CacheItemPoolInterface|null */
  32. private $cacheItemPool;
  33. /** @var string|null */
  34. private $cacheItemId;
  35. /** @var string[] */
  36. private $alternativeNames = [];
  37. /** @var string[] */
  38. private $mediaTypes = ['json'];
  39. /**
  40. * @param DescriberInterface[]|iterable $describers
  41. * @param ModelDescriberInterface[]|iterable $modelDescribers
  42. */
  43. public function __construct($describers, $modelDescribers, CacheItemPoolInterface $cacheItemPool = null, string $cacheItemId = null)
  44. {
  45. $this->describers = $describers;
  46. $this->modelDescribers = $modelDescribers;
  47. $this->cacheItemPool = $cacheItemPool;
  48. $this->cacheItemId = $cacheItemId;
  49. }
  50. public function setAlternativeNames(array $alternativeNames)
  51. {
  52. $this->alternativeNames = $alternativeNames;
  53. }
  54. public function setMediaTypes(array $mediaTypes)
  55. {
  56. $this->mediaTypes = $mediaTypes;
  57. }
  58. public function generate(): OpenApi
  59. {
  60. if (null !== $this->openApi) {
  61. return $this->openApi;
  62. }
  63. if ($this->cacheItemPool) {
  64. $item = $this->cacheItemPool->getItem($this->cacheItemId ?? 'openapi_doc');
  65. if ($item->isHit()) {
  66. return $this->openApi = $item->get();
  67. }
  68. }
  69. $generator = new Generator();
  70. // Remove OperationId processor as we use a lot of generated annotations which do not have enough information in their context
  71. // to generate these ids properly.
  72. // @see https://github.com/zircote/swagger-php/issues/1153
  73. $generator->setProcessors(array_filter($generator->getProcessors(), function ($processor) {
  74. return !$processor instanceof \OpenApi\Processors\OperationId;
  75. }));
  76. $context = Util::createContext(['version' => $generator->getVersion()]);
  77. $this->openApi = new OpenApi(['_context' => $context]);
  78. $modelRegistry = new ModelRegistry($this->modelDescribers, $this->openApi, $this->alternativeNames);
  79. if (null !== $this->logger) {
  80. $modelRegistry->setLogger($this->logger);
  81. }
  82. foreach ($this->describers as $describer) {
  83. if ($describer instanceof ModelRegistryAwareInterface) {
  84. $describer->setModelRegistry($modelRegistry);
  85. }
  86. $describer->describe($this->openApi);
  87. }
  88. $analysis = new Analysis([], $context);
  89. $analysis->addAnnotation($this->openApi, $context);
  90. // Register model annotations
  91. $modelRegister = new ModelRegister($modelRegistry, $this->mediaTypes);
  92. $modelRegister($analysis);
  93. // Calculate the associated schemas
  94. $modelRegistry->registerSchemas();
  95. $analysis->process($generator->getProcessors());
  96. $analysis->validate();
  97. if (isset($item)) {
  98. $this->cacheItemPool->save($item->set($this->openApi));
  99. }
  100. return $this->openApi;
  101. }
  102. }