welcome back to dyb-tech

This commit is contained in:
Daniel Guzman
2024-05-18 02:28:01 +02:00
parent 9513cdba09
commit 9f30bc98c7
6149 changed files with 668407 additions and 0 deletions
@@ -0,0 +1,13 @@
<?php
declare(strict_types=1);
namespace Nelmio\ApiDocBundle\RouteDescriber\RouteArgumentDescriber;
use OpenApi\Annotations as OA;
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
interface RouteArgumentDescriberInterface
{
public function describe(ArgumentMetadata $argumentMetadata, OA\Operation $operation): void;
}
@@ -0,0 +1,132 @@
<?php
declare(strict_types=1);
namespace Nelmio\ApiDocBundle\RouteDescriber\RouteArgumentDescriber;
use Nelmio\ApiDocBundle\OpenApiPhp\Util;
use OpenApi\Annotations as OA;
use OpenApi\Generator;
use OpenApi\Processors\Concerns\TypesTrait;
use Symfony\Component\HttpKernel\Attribute\MapQueryParameter;
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
final class SymfonyMapQueryParameterDescriber implements RouteArgumentDescriberInterface
{
use TypesTrait;
public function describe(ArgumentMetadata $argumentMetadata, OA\Operation $operation): void
{
/** @var MapQueryParameter $attribute */
if (!$attribute = $argumentMetadata->getAttributes(MapQueryParameter::class, ArgumentMetadata::IS_INSTANCEOF)[0] ?? null) {
return;
}
$name = $attribute->name ?? $argumentMetadata->getName();
$name = 'array' === $argumentMetadata->getType()
? $name.'[]'
: $name;
$operationParameter = Util::getOperationParameter($operation, $name, 'query');
Util::modifyAnnotationValue($operationParameter, 'required', !($argumentMetadata->hasDefaultValue() || $argumentMetadata->isNullable()));
/** @var OA\Schema $schema */
$schema = Util::getChild($operationParameter, OA\Schema::class);
if ($argumentMetadata->hasDefaultValue()) {
Util::modifyAnnotationValue($schema, 'default', $argumentMetadata->getDefaultValue());
}
if (Generator::UNDEFINED === $schema->nullable && $argumentMetadata->isNullable()) {
Util::modifyAnnotationValue($schema, 'nullable', true);
}
$defaultFilter = match ($argumentMetadata->getType()) {
'array' => null,
'string' => \FILTER_DEFAULT,
'int' => \FILTER_VALIDATE_INT,
'float' => \FILTER_VALIDATE_FLOAT,
'bool' => \FILTER_VALIDATE_BOOL,
default => null,
};
$properties = $this->describeValidateFilter($attribute->filter ?? $defaultFilter, $attribute->flags, $attribute->options);
if ('array' === $argumentMetadata->getType()) {
$schema->type = 'array';
Util::getChild($schema, OA\Items::class, $properties);
} else {
foreach ($properties as $key => $value) {
Util::modifyAnnotationValue($schema, $key, $value);
}
}
}
/**
* @see https://www.php.net/manual/en/filter.filters.validate.php
*/
private function describeValidateFilter(?int $filter, int $flags, array $options): array
{
if (null === $filter) {
return [];
}
if (FILTER_VALIDATE_BOOLEAN === $filter) {
return ['type' => 'boolean'];
}
if (FILTER_VALIDATE_DOMAIN === $filter) {
return ['type' => 'string', 'format' => 'hostname'];
}
if (FILTER_VALIDATE_EMAIL === $filter) {
return ['type' => 'string', 'format' => 'email'];
}
if (FILTER_VALIDATE_FLOAT === $filter) {
return ['type' => 'number', 'format' => 'float'];
}
if (FILTER_VALIDATE_INT === $filter) {
$props = [];
if ($options['min_range'] ?? false) {
$props['minimum'] = $options['min_range'];
}
if ($options['max_range'] ?? false) {
$props['maximum'] = $options['max_range'];
}
return ['type' => 'integer', ...$props];
}
if (FILTER_VALIDATE_IP === $filter) {
$format = match ($flags) {
FILTER_FLAG_IPV4 => 'ipv4',
FILTER_FLAG_IPV6 => 'ipv6',
default => 'ip',
};
return ['type' => 'string', 'format' => $format];
}
if (FILTER_VALIDATE_MAC === $filter) {
return ['type' => 'string', 'format' => 'mac'];
}
if (FILTER_VALIDATE_REGEXP === $filter) {
return ['type' => 'string', 'pattern' => $options['regexp']];
}
if (FILTER_VALIDATE_URL === $filter) {
return ['type' => 'string', 'format' => 'uri'];
}
if (FILTER_DEFAULT === $filter) {
return ['type' => 'string'];
}
return [];
}
}
@@ -0,0 +1,72 @@
<?php
declare(strict_types=1);
namespace Nelmio\ApiDocBundle\RouteDescriber\RouteArgumentDescriber;
use Nelmio\ApiDocBundle\Describer\ModelRegistryAwareInterface;
use Nelmio\ApiDocBundle\Describer\ModelRegistryAwareTrait;
use Nelmio\ApiDocBundle\Model\Model;
use OpenApi\Annotations as OA;
use Symfony\Component\HttpKernel\Attribute\MapQueryString;
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
use Symfony\Component\PropertyInfo\Type;
use Symfony\Component\Validator\Constraints\GroupSequence;
final class SymfonyMapQueryStringDescriber implements RouteArgumentDescriberInterface, ModelRegistryAwareInterface
{
public const CONTEXT_KEY = 'nelmio_api_doc_bundle.map_query_string.'.self::class;
public const CONTEXT_ARGUMENT_METADATA = 'nelmio_api_doc_bundle.argument_metadata.'.self::class;
public const CONTEXT_MODEL_REF = 'nelmio_api_doc_bundle.model_ref.'.self::class;
use ModelRegistryAwareTrait;
public function describe(ArgumentMetadata $argumentMetadata, OA\Operation $operation): void
{
/** @var MapQueryString $attribute */
if (!$attribute = $argumentMetadata->getAttributes(MapQueryString::class, ArgumentMetadata::IS_INSTANCEOF)[0] ?? null) {
return;
}
$modelRef = $this->modelRegistry->register(new Model(
new Type(Type::BUILTIN_TYPE_OBJECT, $argumentMetadata->isNullable(), $argumentMetadata->getType()),
groups: $this->getGroups($attribute),
serializationContext: $attribute->serializationContext,
));
if (!isset($operation->_context->{self::CONTEXT_KEY})) {
$operation->_context->{self::CONTEXT_KEY} = [];
}
$data = [
self::CONTEXT_ARGUMENT_METADATA => $argumentMetadata,
self::CONTEXT_MODEL_REF => $modelRef,
];
$operation->_context->{self::CONTEXT_KEY}[] = $data;
}
/**
* @return string[]|null
*/
private function getGroups(MapQueryString $attribute): ?array
{
if (null === $attribute->validationGroups) {
return null;
}
if (is_string($attribute->validationGroups)) {
return [$attribute->validationGroups];
}
if (is_array($attribute->validationGroups)) {
return $attribute->validationGroups;
}
if ($attribute->validationGroups instanceof GroupSequence) {
return $attribute->validationGroups->groups;
}
return null;
}
}
@@ -0,0 +1,63 @@
<?php
declare(strict_types=1);
namespace Nelmio\ApiDocBundle\RouteDescriber\RouteArgumentDescriber;
use Nelmio\ApiDocBundle\Describer\ModelRegistryAwareInterface;
use Nelmio\ApiDocBundle\Describer\ModelRegistryAwareTrait;
use Nelmio\ApiDocBundle\Model\Model;
use OpenApi\Annotations as OA;
use Symfony\Component\HttpKernel\Attribute\MapRequestPayload;
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
use Symfony\Component\PropertyInfo\Type;
use Symfony\Component\Validator\Constraints\GroupSequence;
final class SymfonyMapRequestPayloadDescriber implements RouteArgumentDescriberInterface, ModelRegistryAwareInterface
{
public const CONTEXT_ARGUMENT_METADATA = 'nelmio_api_doc_bundle.argument_metadata.'.self::class;
public const CONTEXT_MODEL_REF = 'nelmio_api_doc_bundle.model_ref.'.self::class;
use ModelRegistryAwareTrait;
public function describe(ArgumentMetadata $argumentMetadata, OA\Operation $operation): void
{
/** @var MapRequestPayload $attribute */
if (!$attribute = $argumentMetadata->getAttributes(MapRequestPayload::class, ArgumentMetadata::IS_INSTANCEOF)[0] ?? null) {
return;
}
$modelRef = $this->modelRegistry->register(new Model(
new Type(Type::BUILTIN_TYPE_OBJECT, false, $argumentMetadata->getType()),
groups: $this->getGroups($attribute),
serializationContext: $attribute->serializationContext,
));
$operation->_context->{self::CONTEXT_ARGUMENT_METADATA} = $argumentMetadata;
$operation->_context->{self::CONTEXT_MODEL_REF} = $modelRef;
}
/**
* @return string[]|null
*/
private function getGroups(MapRequestPayload $attribute): ?array
{
if (null === $attribute->validationGroups) {
return null;
}
if (is_string($attribute->validationGroups)) {
return [$attribute->validationGroups];
}
if (is_array($attribute->validationGroups)) {
return $attribute->validationGroups;
}
if ($attribute->validationGroups instanceof GroupSequence) {
return $attribute->validationGroups->groups;
}
return null;
}
}