mirror of
https://github.com/retailcrm/NelmioApiDocBundle.git
synced 2025-02-02 15:51:48 +03:00
Added a way to group API methods by 'resource' name
This commit is contained in:
parent
c4c7d14354
commit
bfaa0c6adf
@ -20,7 +20,12 @@ class ApiDoc
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $comment = null;
|
||||
private $description = null;
|
||||
|
||||
/**
|
||||
* @var Boolean
|
||||
*/
|
||||
private $isResource = false;
|
||||
|
||||
public function __construct(array $data)
|
||||
{
|
||||
@ -39,9 +44,11 @@ class ApiDoc
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($data['comment'])) {
|
||||
$this->comment = $data['comment'];
|
||||
if (isset($data['description'])) {
|
||||
$this->description = $data['description'];
|
||||
}
|
||||
|
||||
$this->isResource = isset($data['resource']);
|
||||
}
|
||||
|
||||
public function getFilters()
|
||||
@ -54,8 +61,13 @@ class ApiDoc
|
||||
return $this->formType;
|
||||
}
|
||||
|
||||
public function getComment()
|
||||
public function getDescription()
|
||||
{
|
||||
return $this->comment;
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
public function isResource()
|
||||
{
|
||||
return $this->isResource;
|
||||
}
|
||||
}
|
||||
|
@ -28,15 +28,51 @@ class ApiDocExtractor
|
||||
public function all()
|
||||
{
|
||||
$array = array();
|
||||
$resources = array();
|
||||
foreach ($this->router->getRouteCollection()->all() as $route) {
|
||||
preg_match('#(.+)::([\w]+)#', $route->getDefault('_controller'), $matches);
|
||||
$method = new \ReflectionMethod($matches[1], $matches[2]);
|
||||
|
||||
if ($annot = $this->reader->getMethodAnnotation($method, self::ANNOTATION_CLASS)) {
|
||||
if ($annot->isResource()) {
|
||||
$resources[] = $route->getPattern();
|
||||
}
|
||||
|
||||
$array[] = array('annotation' => $annot, 'route' => $route);
|
||||
}
|
||||
}
|
||||
|
||||
rsort($resources);
|
||||
foreach ($array as $index => $element) {
|
||||
$hasResource = false;
|
||||
$pattern = $element['route']->getPattern();
|
||||
|
||||
foreach ($resources as $resource) {
|
||||
if (0 === strpos($pattern, $resource)) {
|
||||
$array[$index]['resource'] = $resource;
|
||||
|
||||
$hasResource = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (false === $hasResource) {
|
||||
$array[$index]['resource'] = 'others';
|
||||
}
|
||||
}
|
||||
|
||||
usort($array, function($a, $b) {
|
||||
if ($a['resource'] === $b['resource']) {
|
||||
if ($a['route']->getPattern() === $b['route']->getPattern()) {
|
||||
return strcmp($a['route']->getRequirement('_method'), $b['route']->getRequirement('_method'));
|
||||
}
|
||||
|
||||
return strcmp($a['route']->getPattern(), $b['route']->getPattern());
|
||||
}
|
||||
|
||||
return strcmp($a['resource'], $b['resource']);
|
||||
});
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
|
@ -33,21 +33,52 @@ abstract class AbstractFormatter implements FormatterInterface
|
||||
{
|
||||
$array = array();
|
||||
foreach ($collection as $coll) {
|
||||
$array[] = $this->getData($coll['annotation'], $coll['route']);
|
||||
$resource = $coll['resource'];
|
||||
if (!isset($array[$resource])) {
|
||||
$array[$resource] = array();
|
||||
}
|
||||
|
||||
$array[$resource][] = $this->getData($coll['annotation'], $coll['route']);
|
||||
}
|
||||
|
||||
return $this->render($array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a single array of data
|
||||
*
|
||||
* @param array $data
|
||||
* @return string|array
|
||||
*/
|
||||
protected abstract function renderOne(array $data);
|
||||
|
||||
/**
|
||||
* Format a set of data for a given resource.
|
||||
*
|
||||
* @param string $resource A resource name.
|
||||
* @param array $arrayOfData A set of data.
|
||||
* @return string|array
|
||||
*/
|
||||
protected abstract function renderResourceSection($resource, array $arrayOfData);
|
||||
|
||||
/**
|
||||
* Format a set of resource sections.
|
||||
*
|
||||
* @param array $collection
|
||||
* @return string|array
|
||||
*/
|
||||
protected abstract function render(array $collection);
|
||||
|
||||
/**
|
||||
* @param ApiDoc $apiDoc
|
||||
* @param Route $route
|
||||
* @return array
|
||||
*/
|
||||
private function getData(ApiDoc $apiDoc, Route $route)
|
||||
{
|
||||
$method = $route->getRequirement('_method');
|
||||
$data = array(
|
||||
'method' => $method,
|
||||
'method' => $method ?: 'ANY',
|
||||
'uri' => $route->compile()->getPattern(),
|
||||
'requirements' => $route->compile()->getRequirements(),
|
||||
);
|
||||
@ -60,7 +91,7 @@ abstract class AbstractFormatter implements FormatterInterface
|
||||
if ('PUT' === $method) {
|
||||
// All parameters are optional with PUT (update)
|
||||
array_walk($data['parameters'], function($val, $key) use (&$data) {
|
||||
$data['parameters'][$key]['is_required'] = false;
|
||||
$data['parameters'][$key]['required'] = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -69,8 +100,8 @@ abstract class AbstractFormatter implements FormatterInterface
|
||||
$data['filters'] = $filters;
|
||||
}
|
||||
|
||||
if ($comment = $apiDoc->getComment()) {
|
||||
$data['comment'] = $comment;
|
||||
if ($description = $apiDoc->getDescription()) {
|
||||
$data['description'] = $description;
|
||||
}
|
||||
|
||||
return $data;
|
||||
|
@ -12,7 +12,12 @@ class HtmlFormatter extends AbstractFormatter
|
||||
*/
|
||||
public function formatOne(ApiDoc $apiDoc, Route $route)
|
||||
{
|
||||
return $this->renderWithLayout(parent::formatOne($apiDoc, $route));
|
||||
extract(array('content' => parent::formatOne($apiDoc, $route)));
|
||||
|
||||
ob_start();
|
||||
include __DIR__ . '/../Resources/views/formatter_resource_section.html.php';
|
||||
|
||||
return $this->renderWithLayout(ob_get_clean());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -28,14 +33,32 @@ class HtmlFormatter extends AbstractFormatter
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function renderResourceSection($resource, array $arrayOfData)
|
||||
{
|
||||
$content = '';
|
||||
foreach ($arrayOfData as $data) {
|
||||
$content .= $this->renderOne($data);
|
||||
}
|
||||
|
||||
extract(array('content' => $content));
|
||||
|
||||
ob_start();
|
||||
include __DIR__ . '/../Resources/views/formatter_resource_section.html.php';
|
||||
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function render(array $collection)
|
||||
{
|
||||
$content = '';
|
||||
foreach ($collection as $data) {
|
||||
$content .= $this->renderOne($data);
|
||||
foreach ($collection as $resource => $arrayOfData) {
|
||||
$content .= $this->renderResourceSection($resource, $arrayOfData);
|
||||
}
|
||||
|
||||
return $this->renderWithLayout($content);
|
||||
@ -43,8 +66,7 @@ class HtmlFormatter extends AbstractFormatter
|
||||
|
||||
private function renderWithLayout($content)
|
||||
{
|
||||
$array = array('content' => $content);
|
||||
extract($array);
|
||||
extract(array('content' => $content));
|
||||
|
||||
ob_start();
|
||||
include __DIR__ . '/../Resources/views/formatter_layout.html.php';
|
||||
|
@ -11,8 +11,8 @@ class MarkdownFormatter extends AbstractFormatter
|
||||
{
|
||||
$markdown = sprintf("### `%s` %s ###\n", $data['method'], $data['uri']);
|
||||
|
||||
if (isset($data['comment'])) {
|
||||
$markdown .= sprintf("\n_%s_", $data['comment']);
|
||||
if (isset($data['description'])) {
|
||||
$markdown .= sprintf("\n_%s_", $data['description']);
|
||||
}
|
||||
|
||||
$markdown .= "\n\n";
|
||||
@ -46,8 +46,8 @@ class MarkdownFormatter extends AbstractFormatter
|
||||
|
||||
foreach ($data['parameters'] as $name => $parameter) {
|
||||
$markdown .= sprintf("%s:\n\n", $name);
|
||||
$markdown .= sprintf(" * type: %s\n", $parameter['type']);
|
||||
$markdown .= sprintf(" * is_required: %s\n", $parameter['is_required'] ? 'true' : 'false');
|
||||
$markdown .= sprintf(" * type: %s\n", $parameter['dataType']);
|
||||
$markdown .= sprintf(" * is_required: %s\n", $parameter['required'] ? 'true' : 'false');
|
||||
$markdown .= "\n";
|
||||
}
|
||||
}
|
||||
@ -55,14 +55,29 @@ class MarkdownFormatter extends AbstractFormatter
|
||||
return $markdown;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function renderResourceSection($resource, array $arrayOfData)
|
||||
{
|
||||
$markdown = sprintf("# %s #\n\n", $resource);
|
||||
|
||||
foreach ($arrayOfData as $data) {
|
||||
$markdown .= $this->renderOne($data);
|
||||
$markdown .= "\n";
|
||||
}
|
||||
|
||||
return $markdown;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function render(array $collection)
|
||||
{
|
||||
$markdown = '';
|
||||
foreach ($collection as $data) {
|
||||
$markdown .= $this->renderOne($data);
|
||||
foreach ($collection as $resource => $arrayOfData) {
|
||||
$markdown .= $this->renderResourceSection($resource, $arrayOfData);
|
||||
$markdown .= "\n";
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,15 @@ class SimpleFormatter extends AbstractFormatter
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function renderOne(array $collection)
|
||||
protected function renderResourceSection($resource, array $arrayOfData)
|
||||
{
|
||||
return array($resource => $arrayOfData);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function render(array $collection)
|
||||
{
|
||||
return $collection;
|
||||
}
|
||||
|
@ -42,8 +42,8 @@ class FormTypeParser
|
||||
}
|
||||
|
||||
$parameters[$name] = array(
|
||||
'type' => $bestType,
|
||||
'is_required' => $b->getRequired()
|
||||
'dataType' => $bestType,
|
||||
'required' => $b->getRequired()
|
||||
);
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,94 +1,86 @@
|
||||
<li class="resource">
|
||||
<ul class="endpoints">
|
||||
<li class="endpoint">
|
||||
<ul class="operations">
|
||||
<li class="<?php echo strtolower($method); ?> operation">
|
||||
<div class="heading toggler">
|
||||
<h3>
|
||||
<span class="http_method">
|
||||
<a><?php echo $method; ?></a>
|
||||
</span>
|
||||
<span class="path">
|
||||
<?php echo $uri; ?>
|
||||
</span>
|
||||
</h3>
|
||||
<ul class="options">
|
||||
<?php if (isset($comment)) : ?>
|
||||
<li><?php echo $comment; ?></li>
|
||||
<?php endif; ?>
|
||||
<li class="<?php echo strtolower($method); ?> operation">
|
||||
<div class="heading toggler">
|
||||
<h3>
|
||||
<span class="http_method">
|
||||
<a><?php echo $method; ?></a>
|
||||
</span>
|
||||
<span class="path">
|
||||
<?php echo $uri; ?>
|
||||
</span>
|
||||
</h3>
|
||||
<ul class="options">
|
||||
<?php if (isset($description)) : ?>
|
||||
<li><?php echo $description; ?></li>
|
||||
<?php endif; ?>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="content" style="display: none;">
|
||||
<?php if (isset($requirements) && !empty($requirements)) : ?>
|
||||
<h4>Requirements</h4>
|
||||
<table class="fullwidth">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($requirements as $key => $value) : ?>
|
||||
<tr>
|
||||
<td><?php echo $key; ?></td>
|
||||
<td><?php echo $value; ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (isset($filters)) : ?>
|
||||
<h4>Filters</h4>
|
||||
<table class="fullwidth">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Information</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($filters as $name => $info) : ?>
|
||||
<tr>
|
||||
<td><?php echo $name; ?></td>
|
||||
<td>
|
||||
<ul>
|
||||
<?php foreach ($info as $key => $value) : ?>
|
||||
<li><em><?php echo $key; ?></em> : <?php echo $value; ?></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="content" style="display: none;">
|
||||
<?php if (isset($requirements) && !empty($requirements)) : ?>
|
||||
<h4>Requirements</h4>
|
||||
<table class="fullwidth">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($requirements as $key => $value) : ?>
|
||||
<tr>
|
||||
<td><?php echo $key; ?></td>
|
||||
<td><?php echo $value; ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (isset($filters)) : ?>
|
||||
<h4>Filters</h4>
|
||||
<table class="fullwidth">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Information</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($filters as $name => $info) : ?>
|
||||
<tr>
|
||||
<td><?php echo $name; ?></td>
|
||||
<td>
|
||||
<ul>
|
||||
<?php foreach ($info as $key => $value) : ?>
|
||||
<li><?php echo $key . ': ' . $value; ?></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (isset($parameters)) : ?>
|
||||
<h4>Parameters</h4>
|
||||
<table class='fullwidth'>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Parameter</th>
|
||||
<th>Type</th>
|
||||
<th>Required?</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($parameters as $name => $info) : ?>
|
||||
<tr>
|
||||
<td><?php echo $name; ?></td>
|
||||
<td><?php echo $info['type']; ?></td>
|
||||
<td><?php echo $info['is_required'] ? 'true' : 'false'; ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<?php if (isset($parameters)) : ?>
|
||||
<h4>Parameters</h4>
|
||||
<table class='fullwidth'>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Parameter</th>
|
||||
<th>Type</th>
|
||||
<th>Required?</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($parameters as $name => $info) : ?>
|
||||
<tr>
|
||||
<td><?php echo $name; ?></td>
|
||||
<td><?php echo $info['dataType']; ?></td>
|
||||
<td><?php echo $info['required'] ? 'true' : 'false'; ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</li>
|
||||
|
@ -10,14 +10,20 @@
|
||||
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="header">
|
||||
<h1>API documentation</h1>
|
||||
</div>
|
||||
<div class="container" id="resources_container">
|
||||
<ul id="resources">
|
||||
<?php echo $content; ?>
|
||||
</ul>
|
||||
</div>
|
||||
<p id="colophon">
|
||||
Documentation auto-generated on <?php echo date(DATE_RFC822); ?>
|
||||
</p>
|
||||
<script type="text/javascript">
|
||||
$('.toggler').click(function() {
|
||||
$(this).next().toggle();
|
||||
$(this).next().slideToggle('slow');
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
14
Resources/views/formatter_resource_section.html.php
Normal file
14
Resources/views/formatter_resource_section.html.php
Normal file
@ -0,0 +1,14 @@
|
||||
<li class="resource">
|
||||
<?php if (isset($resource)) : ?>
|
||||
<div class="heading">
|
||||
<h2><?php echo $resource; ?></h2>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<ul class="endpoints">
|
||||
<li class="endpoint">
|
||||
<ul class="operations">
|
||||
<?php echo $content; ?>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
Loading…
x
Reference in New Issue
Block a user