GetFromQueryParamTag.php 3.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. <?php
  2. namespace Mpociot\ApiDoc\Strategies\QueryParameters;
  3. use ReflectionClass;
  4. use ReflectionMethod;
  5. use Illuminate\Support\Str;
  6. use Illuminate\Routing\Route;
  7. use Mpociot\Reflection\DocBlock;
  8. use Mpociot\Reflection\DocBlock\Tag;
  9. use Mpociot\ApiDoc\Strategies\Strategy;
  10. use Mpociot\ApiDoc\Tools\RouteDocBlocker;
  11. use Dingo\Api\Http\FormRequest as DingoFormRequest;
  12. use Mpociot\ApiDoc\Tools\Traits\DocBlockParamHelpers;
  13. use Illuminate\Foundation\Http\FormRequest as LaravelFormRequest;
  14. class GetFromQueryParamTag extends Strategy
  15. {
  16. use DocBlockParamHelpers;
  17. public function __invoke(Route $route, ReflectionClass $controller, ReflectionMethod $method, array $routeRules, array $context = [])
  18. {
  19. foreach ($method->getParameters() as $param) {
  20. $paramType = $param->getType();
  21. if ($paramType === null) {
  22. continue;
  23. }
  24. $parameterClassName = $paramType->getName();
  25. try {
  26. $parameterClass = new ReflectionClass($parameterClassName);
  27. } catch (\ReflectionException $e) {
  28. continue;
  29. }
  30. // If there's a FormRequest, we check there for @queryParam tags.
  31. if (class_exists(LaravelFormRequest::class) && $parameterClass->isSubclassOf(LaravelFormRequest::class)
  32. || class_exists(DingoFormRequest::class) && $parameterClass->isSubclassOf(DingoFormRequest::class)) {
  33. $formRequestDocBlock = new DocBlock($parameterClass->getDocComment());
  34. $queryParametersFromDocBlock = $this->getQueryParametersFromDocBlock($formRequestDocBlock->getTags());
  35. if (count($queryParametersFromDocBlock)) {
  36. return $queryParametersFromDocBlock;
  37. }
  38. }
  39. }
  40. $methodDocBlock = RouteDocBlocker::getDocBlocksFromRoute($route)['method'];
  41. return $this->getQueryParametersFromDocBlock($methodDocBlock->getTags());
  42. }
  43. private function getQueryParametersFromDocBlock($tags)
  44. {
  45. $parameters = collect($tags)
  46. ->filter(function ($tag) {
  47. return $tag instanceof Tag && $tag->getName() === 'queryParam';
  48. })
  49. ->mapWithKeys(function ($tag) {
  50. // Format:
  51. // @queryParam <name> <"required" (optional)> <description>
  52. // Examples:
  53. // @queryParam text string required The text.
  54. // @queryParam user_id The ID of the user.
  55. preg_match('/(.+?)\s+(required\s+)?(.*)/', $tag->getContent(), $content);
  56. $content = preg_replace('/\s?No-example.?/', '', $content);
  57. if (empty($content)) {
  58. // this means only name was supplied
  59. list($name) = preg_split('/\s+/', $tag->getContent());
  60. $required = false;
  61. $description = '';
  62. } else {
  63. list($_, $name, $required, $description) = $content;
  64. $description = trim($description);
  65. if ($description == 'required' && empty(trim($required))) {
  66. $required = $description;
  67. $description = '';
  68. }
  69. $required = trim($required) == 'required' ? true : false;
  70. }
  71. list($description, $value) = $this->parseParamDescription($description, 'string');
  72. if (is_null($value) && ! $this->shouldExcludeExample($tag)) {
  73. $value = Str::contains($description, ['number', 'count', 'page'])
  74. ? $this->generateDummyValue('integer')
  75. : $this->generateDummyValue('string');
  76. }
  77. return [$name => compact('description', 'required', 'value')];
  78. })->toArray();
  79. return $parameters;
  80. }
  81. }