From cc0d445601dc34f6b4c83d352c89f99339e4a357 Mon Sep 17 00:00:00 2001 From: Bez Hermoso Date: Mon, 21 Jul 2014 10:26:06 -0700 Subject: [PATCH] Added caching layer with the controllers and routing files as resources. --- DependencyInjection/Configuration.php | 7 ++ DependencyInjection/NelmioApiDocExtension.php | 9 +++ Extractor/CachingApiDocExtractor.php | 75 +++++++++++++++++++ Tests/Extractor/ApiDocExtractorTest.php | 4 + Tests/Fixtures/app/config/default.yml | 2 + 5 files changed, 97 insertions(+) create mode 100644 Extractor/CachingApiDocExtractor.php diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 8c0676d..55cac15 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -152,6 +152,13 @@ class Configuration implements ConfigurationInterface ->end() ->end() ->end() + ->arrayNode('cache') + ->addDefaultsIfNotSet() + ->children() + ->booleanNode('enabled')->defaultValue(false)->end() + ->scalarNode('file')->defaultValue('%kernel.cache_dir%/api-doc.cache')->end() + ->end() + ->end() ->end(); return $treeBuilder; diff --git a/DependencyInjection/NelmioApiDocExtension.php b/DependencyInjection/NelmioApiDocExtension.php index 7734b98..fbe9317 100644 --- a/DependencyInjection/NelmioApiDocExtension.php +++ b/DependencyInjection/NelmioApiDocExtension.php @@ -12,6 +12,7 @@ namespace Nelmio\ApiDocBundle\DependencyInjection; use Symfony\Component\Config\FileLocator; +use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\HttpKernel\DependencyInjection\Extension; use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; use Symfony\Component\DependencyInjection\ContainerBuilder; @@ -63,6 +64,14 @@ class NelmioApiDocExtension extends Extension $container->setParameter('nelmio_api_doc.swagger.api_version', $config['swagger']['api_version']); $container->setParameter('nelmio_api_doc.swagger.info', $config['swagger']['info']); + if ($config['cache']['enabled'] === true) { + $arguments = $container->getDefinition('nelmio_api_doc.extractor.api_doc_extractor')->getArguments(); + $caching = new Definition('Nelmio\ApiDocBundle\Extractor\CachingApiDocExtractor'); + $arguments[] = $container->getParameterBag()->resolveValue($config['cache']['file']); + $arguments[] = $container->getParameter('kernel.debug'); + $caching->setArguments($arguments); + $container->setDefinition('nelmio_api_doc.extractor.api_doc_extractor', $caching); + } } /** diff --git a/Extractor/CachingApiDocExtractor.php b/Extractor/CachingApiDocExtractor.php new file mode 100644 index 0000000..a9c22d6 --- /dev/null +++ b/Extractor/CachingApiDocExtractor.php @@ -0,0 +1,75 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Nelmio\ApiDocBundle\Extractor; + +use Doctrine\Common\Annotations\Reader; +use Nelmio\ApiDocBundle\Util\DocCommentExtractor; +use Symfony\Component\Config\ConfigCache; +use Symfony\Component\Config\Resource\FileResource; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\Filesystem\Filesystem; +use Symfony\Component\Routing\RouterInterface; + +/** + * Class CachingApiDocExtractor + * + * @author Bez Hermoso + */ +class CachingApiDocExtractor extends ApiDocExtractor +{ + /** + * @var \Symfony\Component\Config\ConfigCache + */ + protected $cache; + + protected $cacheFile; + + public function __construct( + ContainerInterface $container, + RouterInterface $router, + Reader $reader, + DocCommentExtractor $commentExtractor, + array $handlers, + $cacheFile, + $debug = false + ) { + parent::__construct($container, $router, $reader, $commentExtractor, $handlers); + $this->cacheFile = $cacheFile; + $this->cache = new ConfigCache($this->cacheFile, $debug); + } + + public function all() + { + if ($this->cache->isFresh() === false) { + + $resources = array(); + + foreach ($this->getRoutes() as $route) { + if ( null !== ($method = $this->getReflectionMethod($route->getDefault('_controller'))) + && null !== ($annotation = $this->reader->getMethodAnnotation($method, self::ANNOTATION_CLASS))) { + $file = $method->getDeclaringClass()->getFileName(); + $resources[] = new FileResource($file); + } + } + + $resources = array_merge($resources, $this->router->getRouteCollection()->getResources()); + + $data = parent::all(); + $this->cache->write(serialize($data), $resources); + + return $data; + } + + return unserialize(file_get_contents($this->cacheFile)); + + } +} diff --git a/Tests/Extractor/ApiDocExtractorTest.php b/Tests/Extractor/ApiDocExtractorTest.php index abd969f..0c0e561 100644 --- a/Tests/Extractor/ApiDocExtractorTest.php +++ b/Tests/Extractor/ApiDocExtractorTest.php @@ -28,6 +28,10 @@ class ApiDocExtractorTest extends WebTestCase $this->assertTrue(is_array($data)); $this->assertCount(self::ROUTES_QUANTITY, $data); + $cacheFile = $container->getParameter('kernel.cache_dir') . '/api-doc.cache'; + $this->assertFileExists($cacheFile); + $this->assertEquals(file_get_contents($cacheFile), serialize($data)); + foreach ($data as $d) { $this->assertTrue(is_array($d)); $this->assertArrayHasKey('annotation', $d); diff --git a/Tests/Fixtures/app/config/default.yml b/Tests/Fixtures/app/config/default.yml index d7f4ac6..727293a 100644 --- a/Tests/Fixtures/app/config/default.yml +++ b/Tests/Fixtures/app/config/default.yml @@ -53,6 +53,8 @@ jms_serializer: auto_detection: true nelmio_api_doc: + cache: + enabled: true exclude_sections: ["private", "exclusive"] swagger: api_base_path: /api