Skip to content

Commit 123e228

Browse files
committed
fix(OCS): Fix route vs Controller differences
Signed-off-by: provokateurin <[email protected]>
1 parent 2587f18 commit 123e228

File tree

3 files changed

+184
-18
lines changed

3 files changed

+184
-18
lines changed

generate-spec

+18-12
Original file line numberDiff line numberDiff line change
@@ -334,12 +334,11 @@ if (count($parsedRoutes) === 0) {
334334
$operationIds = [];
335335

336336
foreach ($parsedRoutes as $key => $value) {
337-
$isOCS = $key === 'ocs';
338-
$isIndex = $key === 'routes';
339-
340-
if (!$isOCS && !$isIndex) {
341-
continue;
342-
}
337+
$pathPrefix = match ($key) {
338+
'ocs' => '/ocs/v2.php',
339+
'routes' => '/index.php',
340+
default => throw new \InvalidArgumentException('Unknown routes key "' . $key . '"'),
341+
};
343342

344343
foreach ($value as $route) {
345344
$routeName = $route['name'];
@@ -356,12 +355,7 @@ foreach ($parsedRoutes as $key => $value) {
356355
if (str_ends_with($url, '/')) {
357356
$url = substr($url, 0, -1);
358357
}
359-
if ($isIndex) {
360-
$url = '/index.php' . $root . $url;
361-
}
362-
if ($isOCS) {
363-
$url = '/ocs/v2.php' . $root . $url;
364-
}
358+
$url = $pathPrefix . $root . $url;
365359

366360
$methodName = lcfirst(str_replace('_', '', ucwords(explode('#', $routeName)[1], '_')));
367361
if ($methodName == 'preflightedCors') {
@@ -382,6 +376,18 @@ foreach ($parsedRoutes as $key => $value) {
382376
continue;
383377
}
384378

379+
$parentControllerClass = $controllerClass->extends?->name ?? '';
380+
$parentControllerClass = explode('\\', $parentControllerClass);
381+
$parentControllerClass = end($parentControllerClass);
382+
// This is very ugly, but since we do not parse the entire source code we can not say with certainty which controller type is used.
383+
// To still allow apps to use custom controllers that extend OCSController, we only check the suffix and have the warning if the controller type can not be detected.
384+
$isOCS = str_ends_with($parentControllerClass, 'OCSController');
385+
if ($parentControllerClass !== 'Controller' && $parentControllerClass !== 'ApiController' && $parentControllerClass !== 'OCSController' && !$isOCS) {
386+
Logger::warning($routeName, 'You are extending a custom controller class. Make sure that it ends with "OCSController" if it extends "OCSController" itself.');
387+
} elseif ($isOCS !== ($pathPrefix === '/ocs/v2.php')) {
388+
Logger::warning($routeName, 'Do not mix OCS/non-OCS routes and non-OCS/OCS controllers!');
389+
}
390+
385391
$controllerScopes = Helpers::getOpenAPIAttributeScopes($controllerClass, $routeName);
386392
if (Helpers::classMethodHasAnnotationOrAttribute($controllerClass, 'IgnoreOpenAPI')) {
387393
if (count($controllerScopes) === 0 || (in_array('ignore', $controllerScopes, true) && count($controllerScopes) === 1)) {

tests/openapi-administration.json

+83-3
Original file line numberDiff line numberDiff line change
@@ -4625,14 +4625,44 @@
46254625
"pattern": "^[a-z]+$",
46264626
"default": "abc"
46274627
}
4628+
},
4629+
{
4630+
"name": "OCS-APIRequest",
4631+
"in": "header",
4632+
"description": "Required to be true for the API request to pass",
4633+
"required": true,
4634+
"schema": {
4635+
"type": "boolean",
4636+
"default": true
4637+
}
46284638
}
46294639
],
46304640
"responses": {
46314641
"200": {
46324642
"description": "Success",
46334643
"content": {
46344644
"application/json": {
4635-
"schema": {}
4645+
"schema": {
4646+
"type": "object",
4647+
"required": [
4648+
"ocs"
4649+
],
4650+
"properties": {
4651+
"ocs": {
4652+
"type": "object",
4653+
"required": [
4654+
"meta",
4655+
"data"
4656+
],
4657+
"properties": {
4658+
"meta": {
4659+
"$ref": "#/components/schemas/OCSMeta"
4660+
},
4661+
"data": {}
4662+
}
4663+
}
4664+
}
4665+
}
46364666
}
46374667
}
46384668
}
@@ -4663,14 +4693,44 @@
46634693
"pattern": "^[a-z]+$",
46644694
"default": "abc"
46654695
}
4696+
},
4697+
{
4698+
"name": "OCS-APIRequest",
4699+
"in": "header",
4700+
"description": "Required to be true for the API request to pass",
4701+
"required": true,
4702+
"schema": {
4703+
"type": "boolean",
4704+
"default": true
4705+
}
46664706
}
46674707
],
46684708
"responses": {
46694709
"200": {
46704710
"description": "Success",
46714711
"content": {
46724712
"application/json": {
4673-
"schema": {}
4713+
"schema": {
4714+
"type": "object",
4715+
"required": [
4716+
"ocs"
4717+
],
4718+
"properties": {
4719+
"ocs": {
4720+
"type": "object",
4721+
"required": [
4722+
"meta",
4723+
"data"
4724+
],
4725+
"properties": {
4726+
"meta": {
4727+
"$ref": "#/components/schemas/OCSMeta"
4728+
},
4729+
"data": {}
4730+
}
4731+
}
4732+
}
4733+
}
46744734
}
46754735
}
46764736
}
@@ -4718,7 +4778,27 @@
47184778
"description": "Success",
47194779
"content": {
47204780
"application/json": {
4721-
"schema": {}
4781+
"schema": {
4782+
"type": "object",
4783+
"required": [
4784+
"ocs"
4785+
],
4786+
"properties": {
4787+
"ocs": {
4788+
"type": "object",
4789+
"required": [
4790+
"meta",
4791+
"data"
4792+
],
4793+
"properties": {
4794+
"meta": {
4795+
"$ref": "#/components/schemas/OCSMeta"
4796+
},
4797+
"data": {}
4798+
}
4799+
}
4800+
}
4801+
}
47224802
}
47234803
}
47244804
}

tests/openapi-full.json

+83-3
Original file line numberDiff line numberDiff line change
@@ -4775,14 +4775,44 @@
47754775
"pattern": "^[a-z]+$",
47764776
"default": "abc"
47774777
}
4778+
},
4779+
{
4780+
"name": "OCS-APIRequest",
4781+
"in": "header",
4782+
"description": "Required to be true for the API request to pass",
4783+
"required": true,
4784+
"schema": {
4785+
"type": "boolean",
4786+
"default": true
4787+
}
47784788
}
47794789
],
47804790
"responses": {
47814791
"200": {
47824792
"description": "Success",
47834793
"content": {
47844794
"application/json": {
4785-
"schema": {}
4795+
"schema": {
4796+
"type": "object",
4797+
"required": [
4798+
"ocs"
4799+
],
4800+
"properties": {
4801+
"ocs": {
4802+
"type": "object",
4803+
"required": [
4804+
"meta",
4805+
"data"
4806+
],
4807+
"properties": {
4808+
"meta": {
4809+
"$ref": "#/components/schemas/OCSMeta"
4810+
},
4811+
"data": {}
4812+
}
4813+
}
4814+
}
4815+
}
47864816
}
47874817
}
47884818
}
@@ -4813,14 +4843,44 @@
48134843
"pattern": "^[a-z]+$",
48144844
"default": "abc"
48154845
}
4846+
},
4847+
{
4848+
"name": "OCS-APIRequest",
4849+
"in": "header",
4850+
"description": "Required to be true for the API request to pass",
4851+
"required": true,
4852+
"schema": {
4853+
"type": "boolean",
4854+
"default": true
4855+
}
48164856
}
48174857
],
48184858
"responses": {
48194859
"200": {
48204860
"description": "Success",
48214861
"content": {
48224862
"application/json": {
4823-
"schema": {}
4863+
"schema": {
4864+
"type": "object",
4865+
"required": [
4866+
"ocs"
4867+
],
4868+
"properties": {
4869+
"ocs": {
4870+
"type": "object",
4871+
"required": [
4872+
"meta",
4873+
"data"
4874+
],
4875+
"properties": {
4876+
"meta": {
4877+
"$ref": "#/components/schemas/OCSMeta"
4878+
},
4879+
"data": {}
4880+
}
4881+
}
4882+
}
4883+
}
48244884
}
48254885
}
48264886
}
@@ -4868,7 +4928,27 @@
48684928
"description": "Success",
48694929
"content": {
48704930
"application/json": {
4871-
"schema": {}
4931+
"schema": {
4932+
"type": "object",
4933+
"required": [
4934+
"ocs"
4935+
],
4936+
"properties": {
4937+
"ocs": {
4938+
"type": "object",
4939+
"required": [
4940+
"meta",
4941+
"data"
4942+
],
4943+
"properties": {
4944+
"meta": {
4945+
"$ref": "#/components/schemas/OCSMeta"
4946+
},
4947+
"data": {}
4948+
}
4949+
}
4950+
}
4951+
}
48724952
}
48734953
}
48744954
}

0 commit comments

Comments
 (0)