692 lines
14 KiB
PHP
Raw Normal View History

2012-04-11 20:00:21 +02:00
<?php
2012-04-13 11:03:05 +02:00
/*
* This file is part of the NelmioApiDocBundle.
*
* (c) Nelmio <hello@nelm.io>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
2012-04-12 18:37:42 +02:00
namespace Nelmio\ApiDocBundle\Annotation;
2012-04-11 20:00:21 +02:00
use Symfony\Component\Routing\Route;
2012-04-11 20:00:21 +02:00
/**
* @Annotation
*/
class ApiDoc
{
2024-10-01 15:54:04 +03:00
public const DEFAULT_VIEW = 'default';
2012-04-11 20:00:21 +02:00
/**
* Requirements are mandatory parameters in a route.
*
* @var array
*/
2024-10-01 15:54:04 +03:00
private $requirements = [];
/**
* Which views is this route used. Defaults to "Default"
*
* @var array
*/
2024-10-01 15:54:04 +03:00
private $views = [];
/**
* Filters are optional parameters in the query string.
*
2012-04-11 20:00:21 +02:00
* @var array
*/
2024-10-01 15:54:04 +03:00
private $filters = [];
2012-04-11 20:00:21 +02:00
/**
* Parameters are data a client can send.
*
* @var array
*/
2024-10-01 15:54:04 +03:00
private $parameters = [];
2016-05-19 14:28:32 +03:00
/**
* Headers that client can send.
*
* @var array
*/
2024-10-01 15:54:04 +03:00
private $headers = [];
2012-04-11 20:00:21 +02:00
/**
* @var string
*/
2024-10-01 15:54:04 +03:00
private $input;
2012-08-27 13:25:03 -04:00
/**
* @var string
*/
2024-10-01 15:54:04 +03:00
private $inputs;
2012-08-27 12:56:19 -04:00
/**
* @var string
*/
2024-10-01 15:54:04 +03:00
private $output;
2012-04-11 20:00:21 +02:00
2013-08-16 19:18:05 +02:00
/**
* @var string
*/
2024-10-01 15:54:04 +03:00
private $link;
2013-08-16 19:18:05 +02:00
2012-04-11 20:00:21 +02:00
/**
* Most of the time, a single line of text describing the action.
*
2012-04-11 20:00:21 +02:00
* @var string
*/
2024-10-01 15:54:04 +03:00
private $description;
/**
* Section to group actions together.
*
* @var string
*/
2024-10-01 15:54:04 +03:00
private $section;
/**
* Extended documentation.
*
* @var string
*/
2024-10-01 15:54:04 +03:00
private $documentation;
/**
2024-10-01 15:54:04 +03:00
* @var bool
*/
2013-10-11 15:44:31 +02:00
private $resource = false;
2012-04-11 20:00:21 +02:00
/**
* @var string
*/
private $method;
2013-04-11 22:03:40 +02:00
/**
* @var string
*/
private $host;
/**
* @var string
*/
private $uri;
2012-08-27 12:56:19 -04:00
/**
* @var array
*/
2024-10-01 15:54:04 +03:00
private $response = [];
/**
* @var Route
*/
private $route;
2013-03-18 08:40:03 +01:00
/**
2024-10-01 15:54:04 +03:00
* @var bool
2013-03-18 08:40:03 +01:00
*/
private $deprecated = false;
2012-11-13 04:45:07 +00:00
/**
* @var array
*/
2024-10-01 15:54:04 +03:00
private $statusCodes = [];
2012-11-13 04:45:07 +00:00
/**
* @var string|null
*/
2024-10-01 15:54:04 +03:00
private $resourceDescription;
/**
* @var array
*/
2024-10-01 15:54:04 +03:00
private $responseMap = [];
/**
* @var array
*/
2024-10-01 15:54:04 +03:00
private $parsedResponseMap = [];
2014-05-27 13:33:50 +02:00
/**
* @var array
*/
2024-10-01 15:54:04 +03:00
private $tags = [];
2014-05-27 13:33:50 +02:00
2024-10-01 16:11:23 +03:00
private ?string $scope = null;
2012-04-11 20:00:21 +02:00
public function __construct(array $data)
{
2013-10-11 15:44:31 +02:00
$this->resource = !empty($data['resource']) ? $data['resource'] : false;
if (isset($data['description'])) {
$this->description = $data['description'];
}
if (isset($data['input'])) {
$this->input = $data['input'];
}
if (isset($data['inputs'])) {
$this->inputs = $data['inputs'];
}
if (isset($data['filters'])) {
2012-04-11 20:00:21 +02:00
foreach ($data['filters'] as $filter) {
if (!isset($filter['name'])) {
throw new \InvalidArgumentException('A "filter" element has to contain a "name" attribute');
}
$name = $filter['name'];
unset($filter['name']);
$this->addFilter($name, $filter);
2012-04-11 20:00:21 +02:00
}
}
if (isset($data['requirements'])) {
foreach ($data['requirements'] as $requirement) {
if (!isset($requirement['name'])) {
throw new \InvalidArgumentException('A "requirement" element has to contain a "name" attribute');
}
$name = $requirement['name'];
unset($requirement['name']);
$this->addRequirement($name, $requirement);
}
}
if (isset($data['views'])) {
2024-10-01 15:54:04 +03:00
if (!is_array($data['views'])) {
$data['views'] = [$data['views']];
}
foreach ($data['views'] as $view) {
$this->addView($view);
}
}
if (isset($data['parameters'])) {
foreach ($data['parameters'] as $parameter) {
if (!isset($parameter['name'])) {
throw new \InvalidArgumentException('A "parameter" element has to contain a "name" attribute');
}
if (!isset($parameter['dataType'])) {
throw new \InvalidArgumentException(sprintf(
'"%s" parameter element has to contain a "dataType" attribute',
$parameter['name']
));
}
$name = $parameter['name'];
unset($parameter['name']);
$this->addParameter($name, $parameter);
}
}
2016-05-19 14:28:32 +03:00
if (isset($data['headers'])) {
foreach ($data['headers'] as $header) {
if (!isset($header['name'])) {
throw new \InvalidArgumentException('A "header" element has to contain a "name" attribute');
}
$name = $header['name'];
unset($header['name']);
$this->addHeader($name, $header);
}
}
if (isset($data['output'])) {
$this->output = $data['output'];
2012-08-27 12:56:19 -04:00
}
2012-11-13 04:45:07 +00:00
if (isset($data['statusCodes'])) {
foreach ($data['statusCodes'] as $statusCode => $description) {
$this->addStatusCode($statusCode, $description);
}
2012-11-13 04:45:07 +00:00
}
2012-12-26 12:23:28 +01:00
if (isset($data['section'])) {
$this->section = $data['section'];
}
2013-03-18 08:40:03 +01:00
if (isset($data['deprecated'])) {
$this->deprecated = $data['deprecated'];
}
2014-02-06 09:27:30 -08:00
2014-06-25 08:46:01 +02:00
if (isset($data['tags'])) {
if (is_array($data['tags'])) {
foreach ($data['tags'] as $tag => $colorCode) {
if (is_numeric($tag)) {
$this->addTag($colorCode);
} else {
$this->addTag($tag, $colorCode);
}
}
} else {
$this->tags[] = $data['tags'];
2014-06-25 08:46:01 +02:00
}
}
2014-05-27 13:33:50 +02:00
if (isset($data['resourceDescription'])) {
$this->resourceDescription = $data['resourceDescription'];
}
if (isset($data['responseMap'])) {
$this->responseMap = $data['responseMap'];
if (isset($this->responseMap[200])) {
$this->output = $this->responseMap[200];
}
}
2012-04-11 20:00:21 +02:00
}
2012-04-12 17:48:21 +02:00
/**
* @param string $name
2012-04-12 17:48:21 +02:00
*/
2024-10-01 15:54:04 +03:00
public function addFilter($name, array $filter): void
2012-04-11 20:00:21 +02:00
{
$this->filters[$name] = $filter;
2012-04-11 20:00:21 +02:00
}
/**
* @param string $statusCode
*/
2024-10-01 15:54:04 +03:00
public function addStatusCode($statusCode, $description): void
{
2024-10-01 15:54:04 +03:00
$this->statusCodes[$statusCode] = !is_array($description) ? [$description] : $description;
}
/**
* @param string $tag
* @param string $colorCode
*/
2024-10-01 15:54:04 +03:00
public function addTag($tag, $colorCode = '#d9534f'): void
{
$this->tags[$tag] = $colorCode;
}
/**
* @param string $name
*/
2024-10-01 15:54:04 +03:00
public function addRequirement($name, array $requirement): void
{
$this->requirements[$name] = $requirement;
}
2024-10-01 15:54:04 +03:00
public function setRequirements(array $requirements): void
{
$this->requirements = array_merge($this->requirements, $requirements);
}
2012-04-12 17:48:21 +02:00
/**
* @return string|null
*/
public function getInput()
2012-04-11 20:00:21 +02:00
{
return $this->input;
2012-04-11 20:00:21 +02:00
}
/**
* @return array|null
*/
public function getInputs()
{
return $this->inputs;
}
2012-08-27 12:56:19 -04:00
/**
* @return string|null
*/
public function getOutput()
2012-08-27 12:56:19 -04:00
{
return $this->output;
2012-08-27 12:56:19 -04:00
}
2012-04-12 17:48:21 +02:00
/**
* @return string
2012-04-12 17:48:21 +02:00
*/
public function getDescription()
{
return $this->description;
}
/**
* @param string $description
*/
2024-10-01 15:54:04 +03:00
public function setDescription($description): void
{
$this->description = $description;
}
2013-08-16 19:18:05 +02:00
/**
* @param string $link
*/
2024-10-01 15:54:04 +03:00
public function setLink($link): void
2013-08-16 19:18:05 +02:00
{
$this->link = $link;
}
/**
* @param string $section
*/
2024-10-01 15:54:04 +03:00
public function setSection($section): void
{
$this->section = $section;
}
/**
* @return string
*/
public function getSection()
{
return $this->section;
}
/**
* @return array
*/
public function addView($view)
{
$this->views[] = $view;
}
/**
* @return array
*/
public function getViews()
{
return $this->views;
}
/**
* @param string $documentation
*/
2024-10-01 15:54:04 +03:00
public function setDocumentation($documentation): void
{
$this->documentation = $documentation;
}
/**
* @return string
*/
public function getDocumentation()
{
return $this->documentation;
}
2012-04-12 17:48:21 +02:00
/**
2024-10-01 15:54:04 +03:00
* @return bool
2012-04-12 17:48:21 +02:00
*/
public function isResource()
2012-04-11 20:00:21 +02:00
{
2013-10-11 15:44:31 +02:00
return (bool) $this->resource;
}
public function getResource()
{
return $this->resource && is_string($this->resource) ? $this->resource : false;
2012-04-11 20:00:21 +02:00
}
/**
* @param string $name
*/
2024-10-01 15:54:04 +03:00
public function addParameter($name, array $parameter): void
{
$this->parameters[$name] = $parameter;
}
2024-10-01 15:54:04 +03:00
public function setParameters(array $parameters): void
{
$this->parameters = $parameters;
}
2012-08-27 13:25:03 -04:00
2024-10-01 15:54:04 +03:00
public function addHeader($name, array $header): void
2016-05-19 14:28:32 +03:00
{
$this->headers[$name] = $header;
}
2012-08-27 12:56:19 -04:00
/**
2014-03-27 19:49:59 +00:00
* Sets the response data as processed by the parsers - same format as parameters
2012-08-27 12:56:19 -04:00
*/
2024-10-01 15:54:04 +03:00
public function setResponse(array $response): void
2012-08-27 12:56:19 -04:00
{
$this->response = $response;
}
2012-08-27 13:25:03 -04:00
2024-10-01 15:54:04 +03:00
public function setRoute(Route $route): void
{
2024-10-01 15:54:04 +03:00
$this->route = $route;
if (method_exists($route, 'getHost')) {
2024-10-01 15:54:04 +03:00
$this->host = $route->getHost() ?: null;
2015-11-10 01:51:26 +01:00
2024-10-01 15:54:04 +03:00
// replace route placeholders
foreach ($route->getDefaults() as $key => $value) {
if (null !== $this->host && is_string($value)) {
$this->host = str_replace('{' . $key . '}', $value, $this->host);
}
2015-11-10 01:51:26 +01:00
}
} else {
$this->host = null;
}
2024-10-01 15:54:04 +03:00
$this->uri = $route->getPath();
2015-04-30 15:34:19 +02:00
$this->method = $route->getMethods() ? implode('|', $route->getMethods()) : 'ANY';
}
/**
* @return Route
*/
public function getRoute()
{
return $this->route;
}
2013-04-11 22:03:40 +02:00
/**
* @return string
*/
public function getHost()
{
return $this->host;
}
/**
* @param string $host
*/
2024-10-01 15:54:04 +03:00
public function setHost($host): void
2013-04-11 22:03:40 +02:00
{
$this->host = $host;
}
2013-03-18 08:40:03 +01:00
/**
2024-10-01 15:54:04 +03:00
* @return bool
2013-03-18 08:40:03 +01:00
*/
public function getDeprecated()
{
return $this->deprecated;
}
2013-04-30 16:21:12 +04:00
/**
* @return array
*/
public function getFilters()
{
return $this->filters;
}
/**
* @return array
*/
public function getRequirements()
{
return $this->requirements;
}
/**
* @return array
*/
public function getParameters()
{
return $this->parameters;
}
2016-05-19 14:28:32 +03:00
/**
* @return array
*/
public function getHeaders()
{
return $this->headers;
}
2013-03-18 08:40:03 +01:00
/**
2024-10-01 15:54:04 +03:00
* @param bool $deprecated
*
2016-05-19 14:28:32 +03:00
* @return $this
2013-03-18 08:40:03 +01:00
*/
public function setDeprecated($deprecated)
{
$this->deprecated = (bool) $deprecated;
2013-11-14 10:28:42 +01:00
2013-03-18 08:40:03 +01:00
return $this;
}
2014-09-29 16:17:36 +02:00
/**
* @return string
*/
public function getMethod()
{
return $this->method;
}
2024-10-01 16:11:23 +03:00
public function setScope(string $scope): void
{
$this->scope = $scope;
}
public function getScope(): ?string
{
return $this->scope;
}
/**
* @return array
*/
public function toArray()
{
2024-10-01 15:54:04 +03:00
$data = [
'method' => $this->method,
2024-10-01 15:54:04 +03:00
'uri' => $this->uri,
];
2013-04-11 22:03:40 +02:00
if ($host = $this->host) {
$data['host'] = $host;
}
if ($description = $this->description) {
$data['description'] = $description;
}
2013-08-16 19:18:05 +02:00
if ($link = $this->link) {
$data['link'] = $link;
}
if ($documentation = $this->documentation) {
$data['documentation'] = $documentation;
}
if ($filters = $this->filters) {
$data['filters'] = $filters;
}
if ($parameters = $this->parameters) {
$data['parameters'] = $parameters;
}
2016-05-19 14:28:32 +03:00
if ($headers = $this->headers) {
$data['headers'] = $headers;
}
if ($requirements = $this->requirements) {
$data['requirements'] = $requirements;
}
2012-08-27 13:25:03 -04:00
if ($views = $this->views) {
$data['views'] = $views;
}
2012-08-27 12:56:19 -04:00
if ($response = $this->response) {
$data['response'] = $response;
}
2016-01-26 04:21:08 +01:00
if ($parsedResponseMap = $this->parsedResponseMap) {
$data['parsedResponseMap'] = $parsedResponseMap;
}
2012-11-13 04:45:07 +00:00
if ($statusCodes = $this->statusCodes) {
$data['statusCodes'] = $statusCodes;
}
if ($section = $this->section) {
$data['section'] = $section;
}
2014-05-27 13:33:50 +02:00
if ($tags = $this->tags) {
$data['tags'] = $tags;
}
if ($resourceDescription = $this->resourceDescription) {
$data['resourceDescription'] = $resourceDescription;
}
2013-03-18 08:40:03 +01:00
$data['deprecated'] = $this->deprecated;
2024-10-01 16:11:23 +03:00
$data['scope'] = $this->scope;
return $data;
}
/**
2024-10-01 15:54:04 +03:00
* @return string|null
*/
public function getResourceDescription()
{
return $this->resourceDescription;
}
/**
* @return array
*/
public function getResponseMap()
{
if (!isset($this->responseMap[200]) && null !== $this->output) {
$this->responseMap[200] = $this->output;
}
return $this->responseMap;
}
/**
* @return array
*/
public function getParsedResponseMap()
{
return $this->parsedResponseMap;
}
/**
* @param int $statusCode
*/
2024-10-01 15:54:04 +03:00
public function setResponseForStatusCode($model, $type, $statusCode = 200): void
{
2024-10-01 15:54:04 +03:00
$this->parsedResponseMap[$statusCode] = ['type' => $type, 'model' => $model];
if (200 == $statusCode && $this->response !== $model) {
$this->response = $model;
}
}
2012-04-11 20:00:21 +02:00
}