|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
namespace Mpociot\ApiDoc\Extracting\Strategies\Responses; |
|
4
|
|
|
|
|
5
|
|
|
use Illuminate\Routing\Route; |
|
6
|
|
|
use Mpociot\ApiDoc\Extracting\RouteDocBlocker; |
|
7
|
|
|
use Mpociot\ApiDoc\Extracting\Strategies\Strategy; |
|
8
|
|
|
use Mpociot\Reflection\DocBlock; |
|
9
|
|
|
use Mpociot\Reflection\DocBlock\Tag; |
|
10
|
|
|
|
|
11
|
|
|
/** |
|
12
|
|
|
* Get a response from from a file in the docblock ( @responseFile ). |
|
13
|
|
|
*/ |
|
14
|
|
|
class UseResponseFileTag extends Strategy |
|
15
|
|
|
{ |
|
16
|
|
|
/** |
|
17
|
|
|
* @param Route $route |
|
18
|
|
|
* @param \ReflectionClass $controller |
|
19
|
|
|
* @param \ReflectionMethod $method |
|
20
|
|
|
* @param array $routeRules |
|
21
|
|
|
* @param array $context |
|
22
|
|
|
* |
|
23
|
|
|
* @throws \Exception If the response file does not exist |
|
24
|
|
|
* |
|
25
|
|
|
* @return array|null |
|
26
|
|
|
*/ |
|
27
|
|
View Code Duplication |
public function __invoke(Route $route, \ReflectionClass $controller, \ReflectionMethod $method, array $routeRules, array $context = []) |
|
|
|
|
|
|
28
|
|
|
{ |
|
29
|
|
|
$docBlocks = RouteDocBlocker::getDocBlocksFromRoute($route); |
|
30
|
|
|
/** @var DocBlock $methodDocBlock */ |
|
31
|
|
|
$methodDocBlock = $docBlocks['method']; |
|
32
|
|
|
|
|
33
|
|
|
return $this->getFileResponses($methodDocBlock->getTags()); |
|
34
|
|
|
} |
|
35
|
|
|
|
|
36
|
|
|
/** |
|
37
|
|
|
* Get the response from the file if available. |
|
38
|
|
|
* |
|
39
|
|
|
* @param array $tags |
|
40
|
|
|
* |
|
41
|
|
|
* @return array|null |
|
42
|
|
|
*/ |
|
43
|
|
|
protected function getFileResponses(array $tags) |
|
44
|
|
|
{ |
|
45
|
|
|
// Avoid "holes" in the keys of the filtered array, by using array_values on the filtered array |
|
46
|
|
|
$responseFileTags = array_values( |
|
47
|
|
|
array_filter($tags, function ($tag) { |
|
48
|
|
|
return $tag instanceof Tag && strtolower($tag->getName()) === 'responsefile'; |
|
|
|
|
|
|
49
|
|
|
}) |
|
50
|
|
|
); |
|
51
|
|
|
|
|
52
|
|
|
if (empty($responseFileTags)) { |
|
53
|
|
|
return null; |
|
54
|
|
|
} |
|
55
|
|
|
|
|
56
|
|
|
$responses = array_map(function (Tag $responseFileTag) { |
|
57
|
|
|
preg_match('/^(\d{3})?\s?([\S]*[\s]*?)(\{.*\})?$/', $responseFileTag->getContent(), $result); |
|
58
|
|
|
$relativeFilePath = trim($result[2]); |
|
59
|
|
|
$filePath = storage_path($relativeFilePath); |
|
60
|
|
|
if (! file_exists($filePath)) { |
|
61
|
|
|
throw new \Exception('@responseFile ' . $relativeFilePath . ' does not exist'); |
|
62
|
|
|
} |
|
63
|
|
|
$status = $result[1] ?: 200; |
|
64
|
|
|
$content = $result[2] ? file_get_contents($filePath, true) : '{}'; |
|
65
|
|
|
$json = ! empty($result[3]) ? str_replace("'", '"', $result[3]) : '{}'; |
|
66
|
|
|
$merged = array_merge(json_decode($content, true), json_decode($json, true)); |
|
67
|
|
|
|
|
68
|
|
|
return ['content' => json_encode($merged), 'status' => (int) $status]; |
|
69
|
|
|
}, $responseFileTags); |
|
70
|
|
|
|
|
71
|
|
|
return $responses; |
|
72
|
|
|
} |
|
73
|
|
|
} |
|
74
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.