NelmioApiDocBundle/Extractor/ApiDocExtractor.php

110 lines
3.1 KiB
PHP
Raw Normal View History

<?php
2012-04-12 18:37:42 +02:00
namespace Nelmio\ApiDocBundle\Extractor;
use Doctrine\Common\Annotations\Reader;
use Symfony\Component\Routing\RouterInterface;
class ApiDocExtractor
{
2012-04-12 18:37:42 +02:00
const ANNOTATION_CLASS = 'Nelmio\\ApiDocBundle\\Annotation\\ApiDoc';
/**
2012-04-12 17:48:21 +02:00
* @var \ymfony\Component\Routing\RouterInterface
*/
private $router;
/**
* @var \Doctrine\Common\Annotations\Reader
*/
private $reader;
public function __construct(RouterInterface $router, Reader $reader)
{
$this->router = $router;
$this->reader = $reader;
}
2012-04-12 17:48:21 +02:00
/**
* Returns an array of data where each data is an array with the following keys:
* - annotation
* - route
* - resource
*
* @return array
*/
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;
}
2012-04-12 17:48:21 +02:00
/**
* Returns an array containing two values with the following keys:
* - annotation
* - route
*
* @param string $controller
* @param Route $route
* @return array|null
*/
public function get($controller, $route)
{
preg_match('#(.+)::([\w]+)#', $controller, $matches);
$method = new \ReflectionMethod($matches[1], $matches[2]);
if ($annot = $this->reader->getMethodAnnotation($method, self::ANNOTATION_CLASS)) {
if ($route = $this->router->getRouteCollection()->get($route)) {
return array('annotation' => $annot, 'route' => $route);
}
}
return null;
}
}