1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Mpociot\ApiDoc\Extracting; |
4
|
|
|
|
5
|
|
|
use Exception; |
6
|
|
|
use Illuminate\Database\Eloquent\Model; |
7
|
|
|
use Illuminate\Database\Eloquent\Model as IlluminateModel; |
8
|
|
|
use Illuminate\Support\Arr; |
9
|
|
|
use Mpociot\ApiDoc\Tools\Flags; |
10
|
|
|
use Mpociot\Reflection\DocBlock\Tag; |
11
|
|
|
use ReflectionMethod; |
12
|
|
|
|
13
|
|
|
trait TransformerHelpers |
14
|
|
|
{ |
15
|
|
|
/** |
16
|
|
|
* @param Tag $tag |
17
|
|
|
* |
18
|
|
|
* @return array |
19
|
|
|
*/ |
20
|
|
View Code Duplication |
private function getStatusCodeAndTransformerClass($tag): array |
|
|
|
|
21
|
|
|
{ |
22
|
|
|
$content = $tag->getContent(); |
23
|
|
|
preg_match('/^(\d{3})?\s?([\s\S]*)$/', $content, $result); |
24
|
|
|
$status = $result[1] ?: 200; |
25
|
|
|
$transformerClass = $result[2]; |
26
|
|
|
|
27
|
|
|
return [$status, $transformerClass]; |
28
|
|
|
} |
29
|
|
|
|
30
|
|
|
/** |
31
|
|
|
* @param array $tags |
32
|
|
|
* @param ReflectionMethod $transformerMethod |
33
|
|
|
* |
34
|
|
|
* @throws Exception |
35
|
|
|
* |
36
|
|
|
* @return string |
37
|
|
|
*/ |
38
|
|
|
private function getClassToBeTransformed(array $tags, ReflectionMethod $transformerMethod): string |
39
|
|
|
{ |
40
|
|
|
$modelTag = Arr::first(array_filter($tags, function ($tag) { |
41
|
|
|
return ($tag instanceof Tag) && strtolower($tag->getName()) == 'transformermodel'; |
|
|
|
|
42
|
|
|
})); |
43
|
|
|
|
44
|
|
|
$type = null; |
45
|
|
|
if ($modelTag) { |
46
|
|
|
$type = $modelTag->getContent(); |
47
|
|
|
} else { |
48
|
|
|
$parameter = Arr::first($transformerMethod->getParameters()); |
49
|
|
|
if ($parameter->hasType() && ! $parameter->getType()->isBuiltin() && class_exists($parameter->getType()->getName())) { |
50
|
|
|
// Ladies and gentlemen, we have a type! |
51
|
|
|
$type = $parameter->getType()->getName(); |
52
|
|
|
} |
53
|
|
|
} |
54
|
|
|
|
55
|
|
|
if ($type == null) { |
56
|
|
|
throw new Exception('Failed to detect a transformer model. Please specify a model using @transformerModel.'); |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
return $type; |
60
|
|
|
} |
61
|
|
|
|
62
|
|
|
/** |
63
|
|
|
* @param string $type |
64
|
|
|
* |
65
|
|
|
* @return Model|object |
66
|
|
|
*/ |
67
|
|
View Code Duplication |
protected function instantiateTransformerModel(string $type) |
|
|
|
|
68
|
|
|
{ |
69
|
|
|
try { |
70
|
|
|
// try Eloquent model factory |
71
|
|
|
|
72
|
|
|
// Factories are usually defined without the leading \ in the class name, |
73
|
|
|
// but the user might write it that way in a comment. Let's be safe. |
74
|
|
|
$type = ltrim($type, '\\'); |
75
|
|
|
|
76
|
|
|
return factory($type)->make(); |
77
|
|
|
} catch (Exception $e) { |
78
|
|
|
if (Flags::$shouldBeVerbose) { |
79
|
|
|
echo "Eloquent model factory failed to instantiate {$type}; trying to fetch from database.\n"; |
80
|
|
|
} |
81
|
|
|
|
82
|
|
|
$instance = new $type(); |
83
|
|
|
if ($instance instanceof IlluminateModel) { |
|
|
|
|
84
|
|
|
try { |
85
|
|
|
// we can't use a factory but can try to get one from the database |
86
|
|
|
$firstInstance = $type::first(); |
87
|
|
|
if ($firstInstance) { |
88
|
|
|
return $firstInstance; |
89
|
|
|
} |
90
|
|
|
} catch (Exception $e) { |
91
|
|
|
// okay, we'll stick with `new` |
92
|
|
|
if (Flags::$shouldBeVerbose) { |
93
|
|
|
echo "Failed to fetch first {$type} from database; using `new` to instantiate.\n"; |
94
|
|
|
} |
95
|
|
|
} |
96
|
|
|
} |
97
|
|
|
} |
98
|
|
|
|
99
|
|
|
return $instance; |
100
|
|
|
} |
101
|
|
|
|
102
|
|
|
/** |
103
|
|
|
* @param array $tags |
104
|
|
|
* |
105
|
|
|
* @return Tag|null |
106
|
|
|
*/ |
107
|
|
View Code Duplication |
private function getTransformerTag(array $tags) |
|
|
|
|
108
|
|
|
{ |
109
|
|
|
$transformerTags = array_values( |
110
|
|
|
array_filter($tags, function ($tag) { |
111
|
|
|
return ($tag instanceof Tag) && in_array(strtolower($tag->getName()), ['transformer', 'transformercollection']); |
|
|
|
|
112
|
|
|
}) |
113
|
|
|
); |
114
|
|
|
|
115
|
|
|
return Arr::first($transformerTags); |
116
|
|
|
} |
117
|
|
|
} |
118
|
|
|
|
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.