44
55use PSFS \base \exception \RouterException ;
66use PSFS \base \Router ;
7+ use PSFS \base \config \Config ;
78use PSFS \base \types \Controller ;
89use PSFS \base \types \helpers \attributes \Cacheable ;
910use PSFS \base \types \helpers \attributes \HttpMethod ;
2021class DocumentorController extends Controller
2122{
2223 const DOMAIN = 'ROOT ' ;
24+ /**
25+ * @var array<string, array{doc:array, expires:int}>
26+ */
27+ private static array $ docsCache = [];
2328
2429 /**
2530 * @Injectable
@@ -46,30 +51,56 @@ public function createApiDocs($domain)
4651 ini_set ('memory_limit ' , -1 );
4752 ini_set ('max_execution_time ' , -1 );
4853
49- $ type = $ this ->getRequest ()->get ('type ' ) ?: ApiController::PSFS_DOC ;
54+ $ type = strtolower (( string )( $ this ->getRequest ()->get ('type ' ) ?: ApiController::PSFS_DOC )) ;
5055 $ download = $ this ->getRequest ()->get ('download ' ) ?: false ;
56+ $ cacheVersion = (string )Config::getParam ('cache.var ' , 'v1 ' );
57+ $ cacheTtl = (int )Config::getParam ('api.doc.cache.ttl ' , 300 );
58+ $ cacheKey = implode (': ' , [$ domain , $ type , $ cacheVersion ]);
59+
60+ if ($ cacheTtl > 0 && !$ download && isset (self ::$ docsCache [$ cacheKey ])) {
61+ $ entry = self ::$ docsCache [$ cacheKey ];
62+ if ($ entry ['expires ' ] >= time ()) {
63+ return $ this ->json ($ entry ['doc ' ], 200 );
64+ }
65+ unset(self ::$ docsCache [$ cacheKey ]);
66+ }
5167
52- $ module = $ this ->srv ->getModules ($ domain );
68+ $ module = $ this ->srv ->getModules (( string ) $ domain );
5369 if (empty ($ module )) {
5470 return ResponseHelper::httpNotFound (null , true );
5571 }
56- $ doc = $ this ->srv ->extractApiEndpoints ($ module );
57- switch (strtolower ( $ type) ) {
72+ $ doc = $ this ->srv ->buildEndpointSpec ($ module );
73+ switch ($ type ) {
5874 case ApiController::SWAGGER_DOC :
5975 $ doc = $ this ->srv ->swaggerFormatter ($ module , $ doc );
6076 break ;
6177 case ApiController::POSTMAN_DOC :
6278 $ doc = $ this ->srv ->postmanFormatter ($ module , $ doc );
6379 break ;
80+ case ApiController::OPENAPI_DOC :
81+ $ doc = $ this ->srv ->openApiFormatter ($ module , $ doc );
82+ break ;
6483 }
6584
66- if ($ download && in_array ($ type , [ApiController::SWAGGER_DOC , ApiController::POSTMAN_DOC ], true )) {
67- $ filename = $ type === ApiController::POSTMAN_DOC ? 'postman.collection.json ' : 'swagger.json ' ;
85+ if ($ download && in_array ($ type , [ApiController::SWAGGER_DOC , ApiController::POSTMAN_DOC , ApiController::OPENAPI_DOC ], true )) {
86+ if ($ type === ApiController::POSTMAN_DOC ) {
87+ $ filename = 'postman.collection.json ' ;
88+ } elseif ($ type === ApiController::OPENAPI_DOC ) {
89+ $ filename = 'openapi.json ' ;
90+ } else {
91+ $ filename = 'swagger.json ' ;
92+ }
6893 return $ this ->download (json_encode ($ doc ), 'application/json ' , $ filename );
6994 }
7095 if ($ type === ApiController::HTML_DOC ) {
7196 return $ this ->render ('documentation.html.twig ' , ["data " => json_encode ($ doc )]);
7297 }
98+ if ($ cacheTtl > 0 && !in_array ($ type , [ApiController::PSFS_DOC , ApiController::HTML_DOC ], true )) {
99+ self ::$ docsCache [$ cacheKey ] = [
100+ 'doc ' => $ doc ,
101+ 'expires ' => time () + $ cacheTtl ,
102+ ];
103+ }
73104 return $ this ->json ($ doc , 200 );
74105 }
75106
0 commit comments