|
1 | 1 | <?php
|
2 | 2 |
|
3 |
| -collect(glob(base_path('**/Models/*.php')))->each(fn ($file) => include_once($file)); |
| 3 | +collect(glob(base_path('**/Models/*.php')))->each(fn($file) => include_once($file)); |
4 | 4 |
|
5 | 5 | if (class_exists('\phpDocumentor\Reflection\DocBlockFactory')) {
|
6 | 6 | $factory = \phpDocumentor\Reflection\DocBlockFactory::createInstance();
|
7 | 7 | } else {
|
8 | 8 | $factory = null;
|
9 | 9 | }
|
10 | 10 |
|
11 |
| -$reflection = new \ReflectionClass(\Illuminate\Database\Query\Builder::class); |
12 |
| -$builderMethods = collect($reflection->getMethods(\ReflectionMethod::IS_PUBLIC)) |
13 |
| - ->filter(function (ReflectionMethod $method) { |
14 |
| - return !str_starts_with($method->getName(), "__"); |
15 |
| - }) |
16 |
| - ->map(function (\ReflectionMethod $method) use ($factory) { |
17 |
| - if ($factory === null) { |
18 |
| - $params = collect($method->getParameters()) |
19 |
| - ->map(function (\ReflectionParameter $param) { |
20 |
| - $types = match ($param?->getType()) { |
21 |
| - null => [], |
22 |
| - default => method_exists($param->getType(), "getTypes") |
23 |
| - ? $param->getType()->getTypes() |
24 |
| - : [$param->getType()] |
25 |
| - }; |
26 |
| - |
27 |
| - $types = collect($types) |
28 |
| - ->filter() |
29 |
| - ->values() |
30 |
| - ->map(fn ($t) => $t->getName()); |
31 |
| - |
32 |
| - return trim($types->join("|") . " $" . $param->getName()); |
33 |
| - }) |
34 |
| - ->all(); |
35 |
| - |
36 |
| - $return = $method->getReturnType()?->getName(); |
37 |
| - } else { |
| 11 | +function getMethodDocblocks($method, $factory) |
| 12 | +{ |
| 13 | + if ($factory !== null) { |
38 | 14 | $docblock = $factory->create($method->getDocComment());
|
39 | 15 | $params = collect($docblock->getTagsByName("param"))->map(fn($p) => (string) $p)->all();
|
40 | 16 | $return = (string) $docblock->getTagsByName("return")[0] ?? null;
|
| 17 | + |
| 18 | + return [$params, $return]; |
| 19 | + } |
| 20 | + |
| 21 | + |
| 22 | + $params = collect($method->getParameters()) |
| 23 | + ->map(function (\ReflectionParameter $param) { |
| 24 | + $types = match ($param?->getType()) { |
| 25 | + null => [], |
| 26 | + default => method_exists($param->getType(), "getTypes") |
| 27 | + ? $param->getType()->getTypes() |
| 28 | + : [$param->getType()] |
| 29 | + }; |
| 30 | + |
| 31 | + $types = collect($types) |
| 32 | + ->filter() |
| 33 | + ->values() |
| 34 | + ->map(fn($t) => $t->getName()); |
| 35 | + |
| 36 | + return trim($types->join("|") . " $" . $param->getName()); |
| 37 | + }) |
| 38 | + ->all(); |
| 39 | + |
| 40 | + $return = $method->getReturnType()?->getName(); |
| 41 | + |
| 42 | + return [$params, $return]; |
| 43 | +} |
| 44 | + |
| 45 | +function getBuilderMethod($method, $factory) |
| 46 | +{ |
| 47 | + [$params, $return] = getMethodDocblocks($method, $factory); |
| 48 | + |
| 49 | + return [ |
| 50 | + "name" => $method->getName(), |
| 51 | + "parameters" => $params, |
| 52 | + "return" => $return, |
| 53 | + ]; |
| 54 | +}; |
| 55 | + |
| 56 | +function getModelInfo($className, $factory) |
| 57 | +{ |
| 58 | + $output = new \Symfony\Component\Console\Output\BufferedOutput(); |
| 59 | + |
| 60 | + try { |
| 61 | + \Illuminate\Support\Facades\Artisan::call( |
| 62 | + "model:show", |
| 63 | + [ |
| 64 | + "model" => $className, |
| 65 | + "--json" => true, |
| 66 | + ], |
| 67 | + $output |
| 68 | + ); |
| 69 | + } catch (\Exception | \Throwable $e) { |
| 70 | + return null; |
| 71 | + } |
| 72 | + |
| 73 | + $data = json_decode($output->fetch(), true); |
| 74 | + |
| 75 | + if ($data === null) { |
| 76 | + return null; |
| 77 | + } |
| 78 | + |
| 79 | + $reflection = (new \ReflectionClass($className)); |
| 80 | + |
| 81 | + if ($factory !== null && ($comment = $reflection->getDocComment())) { |
| 82 | + $docblock = $factory->create($comment); |
| 83 | + $existingProperties = collect($docblock->getTagsByName("property"))->map(fn($p) => $p->getVariableName()); |
| 84 | + $existingReadProperties = collect($docblock->getTagsByName("property-read"))->map(fn($p) => $p->getVariableName()); |
| 85 | + $existingProperties = $existingProperties->merge($existingReadProperties); |
| 86 | + } else { |
| 87 | + $existingProperties = collect(); |
41 | 88 | }
|
42 | 89 |
|
| 90 | + $data['attributes'] = collect($data['attributes']) |
| 91 | + ->map(fn($attrs) => array_merge($attrs, [ |
| 92 | + 'title_case' => str_replace('_', '', \Illuminate\Support\Str::title($attrs['name'])), |
| 93 | + 'documented' => $existingProperties->contains($attrs['name']), |
| 94 | + ])) |
| 95 | + ->toArray(); |
| 96 | + |
| 97 | + $data['scopes'] = collect($reflection->getMethods()) |
| 98 | + ->filter(fn($method) => $method->isPublic() && !$method->isStatic() && $method->name !== '__construct') |
| 99 | + ->filter(fn($method) => str_starts_with($method->name, 'scope')) |
| 100 | + ->map(fn($method) => str_replace('scope', '', $method->name)) |
| 101 | + ->map(fn($method) => strtolower(substr($method, 0, 1)) . substr($method, 1)) |
| 102 | + ->values() |
| 103 | + ->toArray(); |
| 104 | + |
| 105 | + $data['uri'] = $reflection->getFileName(); |
| 106 | + |
43 | 107 | return [
|
44 |
| - "name" => $method->getName(), |
45 |
| - "parameters" => $params, |
46 |
| - "return" => $return, |
| 108 | + $className => $data, |
47 | 109 | ];
|
48 |
| - }) |
49 |
| - ->filter() |
50 |
| - ->values(); |
| 110 | +} |
| 111 | + |
| 112 | +$reflection = new \ReflectionClass(\Illuminate\Database\Query\Builder::class); |
| 113 | +$builderMethods = collect($reflection->getMethods(\ReflectionMethod::IS_PUBLIC)) |
| 114 | + ->filter(fn(ReflectionMethod $method) => !str_starts_with($method->getName(), "__")) |
| 115 | + ->map(fn(\ReflectionMethod $method) => getBuilderMethod($method, $factory)) |
| 116 | + ->filter() |
| 117 | + ->values(); |
51 | 118 |
|
52 | 119 | echo collect([
|
53 |
| -'builderMethods' => $builderMethods, |
54 |
| -'models' => collect(get_declared_classes()) |
55 |
| - ->filter(function ($class) { |
56 |
| - return is_subclass_of($class, \Illuminate\Database\Eloquent\Model::class); |
57 |
| - }) |
58 |
| - ->filter(function ($class) { |
59 |
| - return !in_array($class, [\Illuminate\Database\Eloquent\Relations\Pivot::class, \Illuminate\Foundation\Auth\User::class]); |
60 |
| - }) |
61 |
| - ->values() |
62 |
| - ->flatMap(function (string $className) { |
63 |
| - $output = new \Symfony\Component\Console\Output\BufferedOutput(); |
64 |
| - |
65 |
| - try { |
66 |
| - \Illuminate\Support\Facades\Artisan::call( |
67 |
| - "model:show", |
68 |
| - [ |
69 |
| - "model" => $className, |
70 |
| - "--json" => true, |
71 |
| - ], |
72 |
| - $output |
73 |
| - ); |
74 |
| - } catch (\Exception | \Throwable $e) { |
75 |
| - return null; |
76 |
| - } |
77 |
| - |
78 |
| - $data = json_decode($output->fetch(), true); |
79 |
| - |
80 |
| - if ($data === null) { |
81 |
| - return null; |
82 |
| - } |
83 |
| - |
84 |
| - $data['attributes'] = collect($data['attributes']) |
85 |
| - ->map(function ($attrs) { |
86 |
| - return array_merge($attrs, [ |
87 |
| - 'title_case' => str_replace('_', '', \Illuminate\Support\Str::title($attrs['name'])), |
88 |
| - ]); |
89 |
| - }) |
90 |
| - ->toArray(); |
91 |
| - |
92 |
| - $reflection = (new \ReflectionClass($className)); |
93 |
| - |
94 |
| - $data['scopes'] = collect($reflection->getMethods()) |
95 |
| - ->filter(function ($method) { |
96 |
| - return $method->isPublic() && !$method->isStatic() && $method->name !== '__construct'; |
97 |
| - }) |
98 |
| - ->filter(function ($method) { |
99 |
| - return str_starts_with($method->name, 'scope'); |
100 |
| - }) |
101 |
| - ->map(function ($method) { |
102 |
| - return str_replace('scope', '', $method->name); |
103 |
| - }) |
104 |
| - ->map(function ($method) { |
105 |
| - return strtolower(substr($method, 0, 1)) . substr($method, 1); |
106 |
| - }) |
107 |
| - ->values() |
108 |
| - ->toArray(); |
109 |
| - |
110 |
| - $data['uri'] = $reflection->getFileName(); |
111 |
| - |
112 |
| - return [ |
113 |
| - $className => $data, |
114 |
| - ]; |
115 |
| - }) |
116 |
| - ->filter(), |
| 120 | + 'builderMethods' => $builderMethods, |
| 121 | + 'models' => collect(get_declared_classes()) |
| 122 | + ->filter(fn($class) => is_subclass_of($class, \Illuminate\Database\Eloquent\Model::class)) |
| 123 | + ->filter(fn($class) => !in_array($class, [\Illuminate\Database\Eloquent\Relations\Pivot::class, \Illuminate\Foundation\Auth\User::class])) |
| 124 | + ->values() |
| 125 | + ->flatMap(fn(string $className) => getModelInfo($className, $factory)) |
| 126 | + ->filter(), |
117 | 127 | ])->toJson();
|
0 commit comments