Permalink
Browse files

Added two new parameters to the ApiDoc Annotation

- 'responseCodes' allows to define the HTTP response codes and the situations when they are returned. (Think of Docblocks and Exceptions).
- 'include' allows to include a Markdown file with a long description.
- Minor tweaks: Made the Filters actually display as Markdown as well.
- When 'default' is included in filters, use this instead of the description for the sandbox.
  • Loading branch information...
1 parent cbdddfe commit bcd37d5ee1203b63674349f2f97bf19b057cc6f3 @baldurrensch committed with Baldur Rensch Aug 27, 2012
View
@@ -12,6 +12,7 @@
namespace Nelmio\ApiDocBundle\Annotation;
use Symfony\Component\Routing\Route;
+use dflydev\markdown\MarkdownParser;
/**
* @Annotation
@@ -78,6 +79,18 @@ class ApiDoc
*/
private $route;
+ /**
+ * Stores HTTP Response Codes and a description
+ * @var array
+ */
+ private $responseCodes;
+
+ /**
+ * An optional Markdown file to include with a long description.
+ * @var String
+ */
+ private $fileToInclude;
+
public function __construct(array $data)
{
if (isset($data['input'])) {
@@ -103,6 +116,14 @@ public function __construct(array $data)
$this->return = $data['return'];
}
+ if (isset($data['responseCodes'])) {
+ $this->responseCodes = $data['responseCodes'];
+ }
+
+ if (isset($data['include'])) {
+ $this->fileToInclude = $data['include'];
+ }
+
$this->isResource = isset($data['resource']) && $data['resource'];
}
@@ -241,6 +262,39 @@ public function getRoute()
/**
* @return array
*/
+ public function getResponseCodes()
+ {
+ return $this->responseCodes;
+ }
+
+ /**
+ * @param array
+ */
+ public function addResponseCode($c)
+ {
+ $this->responseCodes = array_merge($this->responseCodes, $c);
+ }
+
+ /**
+ * @return String
+ */
+ public function getFileToInclude()
+ {
+ return $this->fileToInclude;
+ }
+
+ /**
+ * @param String $newFileToInclude
+ */
+ public function setFileToInclude($newFileToInclude)
+ {
+ $this->fileToInclude = $newFileToInclude;
+ }
+
+ /**
+ * @return array
+ * @throws \InvalidArgumentException if the file to be included is not readable
+ */
public function toArray()
{
$data = array(
@@ -272,6 +326,20 @@ public function toArray()
$data['response'] = $response;
}
+ if ($responseCodes = $this->responseCodes) {
+ $data['responseCodes'] = $responseCodes;
+ }
+
+ if ($fileToInclude = $this->fileToInclude) {
+ if (!is_readable($fileToInclude)) {
+ throw new \InvalidArgumentException("Could not open: {$fileToInclude}");
+ }
+
+ $mdParser = new MarkdownParser();
+ $fileContents = file_get_contents($fileToInclude);
+ $data['fileToInclude'] = $mdParser->transform($fileContents);
+ }
+
return $data;
}
}
@@ -43,6 +43,12 @@ public function getConfigTreeBuilder()
->end()
->end()
->end()
+ ->arrayNode('include')
+ ->addDefaultsIfNotSet()
+ ->children()
+ ->scalarNode('location')->defaultValue('%kernel.root_dir%')->end()
+ ->end()
+ ->end()
->end();
return $treeBuilder;
@@ -31,6 +31,7 @@ public function load(array $configs, ContainerBuilder $container)
$container->setParameter('nelmio_api_doc.api_name', $config['name']);
$container->setParameter('nelmio_api_doc.sandbox.enabled', $config['sandbox']['enabled']);
$container->setParameter('nelmio_api_doc.sandbox.endpoint', $config['sandbox']['endpoint']);
+ $container->setParameter('nelmio_api_doc.include.location', $config['include']['location']);
$loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('formatters.xml');
@@ -305,6 +305,11 @@ protected function extractData(ApiDoc $annotation, Route $route, \ReflectionMeth
$annotation->setMethod($route->getRequirement('_method') ?: 'ANY');
$annotation->setUri($route->getPattern());
+ // Include File
+ if ("" != ($fileToInclude = $annotation->getFileToInclude())) {
+ $annotation->setFileToInclude($this->container->getParameter('nelmio_api_doc.include.location') . $fileToInclude);
+ }
+
return $annotation;
}
@@ -28,6 +28,26 @@
{% if data.documentation is defined and data.documentation is not empty %}
<h4>Documentation</h4>
<div>{{ data.documentation|extra_markdown }}</div>
+ <div>{{ data.fileToInclude|raw }}</div>
+ {% endif %}
+
+ {% if data.responseCodes is defined and data.responseCodes is not empty %}
+ <h4>Response Codes</h4>
+ <table class="fullwidth">
+ <thead>
+ <tr>
+ <th>Response Code</th>
+ <th>Description</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for response_code, description in data.responseCodes %}
+ <tr>
+ <td><a href="http://en.wikipedia.org/wiki/HTTP_{{ response_code }}" target="_blank">{{ response_code }}<a/></td>
+ <td>{{ description }}</td>
+ {% endfor %}
+ </tbody>
+ </table>
{% endif %}
{% if data.requirements is defined and data.requirements is not empty %}
@@ -71,8 +91,9 @@
<table>
{% for key, value in infos %}
<tr>
- <td>{{ key|title }}</td>
- <td>{{ value|json_encode|replace({'\\\\': '\\'})|trim('"') }}</td>
+ <td><strong>{{ key|title }}</strong></td>
+ <td>{{ value|replace({'*': ''})|extra_markdown }}</td>
+ {# <td>{{ value|json_encode|replace({'\\\\': '\\'})|trim('"') }}</td>#}
</tr>
{% endfor %}
</table>
@@ -136,7 +157,7 @@
<p class="tuple">
<input type="text" class="key" value="{{ name }}" placeholder="Key" />
<span>=</span>
- <input type="text" class="value" placeholder="{% if infos.description is defined %}{{ infos.description }}{% else %}Value{% endif %}" /> <span class="remove">-</span>
+ <input type="text" class="value" placeholder="{% if infos.default is defined %}{{ infos.default }}{% elseif infos.description is defined %}{{ infos.description }}{% else %}Value{% endif %}" /> <span class="remove">-</span>
</p>
{% endfor %}
{% endif %}

0 comments on commit bcd37d5

Please sign in to comment.