* * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Nelmio\ApiDocBundle\Extractor\Handler; use FOS\RestBundle\Controller\Annotations\QueryParam; use FOS\RestBundle\Controller\Annotations\RequestParam; use Nelmio\ApiDocBundle\Annotation\ApiDoc; use Nelmio\ApiDocBundle\DataTypes; use Nelmio\ApiDocBundle\Extractor\HandlerInterface; use Symfony\Component\Routing\Route; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\Constraints\Regex; class FosRestHandler implements HandlerInterface { public function handle(ApiDoc $annotation, array $annotations, Route $route, \ReflectionMethod $method): void { foreach ($annotations as $annot) { if ($annot instanceof RequestParam) { $requirements = $this->handleRequirements($annot->requirements); $data = [ 'required' => $annot->strict && false === $annot->nullable && null === $annot->default, 'dataType' => $requirements . ((property_exists($annot, 'map') ? $annot->map : $annot->array) ? '[]' : ''), 'actualType' => $this->inferType($requirements), 'subType' => null, 'description' => $annot->description, 'readonly' => false, ]; if (false === $annot->strict) { $data['default'] = $annot->default; } $annotation->addParameter($annot->name, $data); } elseif ($annot instanceof QueryParam) { if ($annot->strict && false === $annot->nullable && null === $annot->default) { $annotation->addRequirement($annot->name, [ 'requirement' => $this->handleRequirements($annot->requirements) . ((property_exists($annot, 'map') ? $annot->map : $annot->array) ? '[]' : ''), 'dataType' => '', 'description' => $annot->description, ]); } elseif (null !== $annot->default) { $annotation->addFilter($annot->name, [ 'requirement' => $this->handleRequirements($annot->requirements) . ((property_exists($annot, 'map') ? $annot->map : $annot->array) ? '[]' : ''), 'description' => $annot->description, 'default' => $annot->default, ]); } elseif (null !== $annot->requirements) { $annotation->addFilter($annot->name, [ 'requirement' => $this->handleRequirements($annot->requirements) . ((property_exists($annot, 'map') ? $annot->map : $annot->array) ? '[]' : ''), 'description' => $annot->description, ]); } else { $annotation->addFilter($annot->name, [ 'description' => $annot->description, ]); } } } } /** * Handle FOSRestBundle requirements in order to return a string. * * @return string */ private function handleRequirements($requirements) { if (is_object($requirements) && $requirements instanceof Constraint) { if ($requirements instanceof Regex) { return $requirements->getHtmlPattern(); } $class = $requirements::class; return substr($class, strrpos($class, '\\') + 1); } if (is_array($requirements) && isset($requirements['rule'])) { return (string) $requirements['rule']; } if (is_array($requirements) && array_key_exists(0, $requirements)) { $output = []; foreach ($requirements as $req) { if (is_object($req) && $req instanceof Constraint) { if ($req instanceof Regex) { $output[] = $req->getHtmlPattern(); } else { $class = $req::class; $output[] = substr($class, strrpos($class, '\\') + 1); } } if (is_array($req)) { if (array_key_exists('_format', $req)) { $output[] = 'Format: ' . $req['_format']; } elseif (isset($req['rule'])) { $output[] = $req['rule']; } } } return implode(', ', $output); } return (string) $requirements; } public function inferType($requirement) { if (DataTypes::isPrimitive($requirement)) { return $requirement; } return DataTypes::STRING; } }