Skip to content

Commit 727938f

Browse files
authored
Merge pull request #61 from php-api-clients/generate-unknown-schemas
Generate unknown schemas
2 parents 08e350b + b77651e commit 727938f

File tree

6 files changed

+160
-53
lines changed

6 files changed

+160
-53
lines changed

src/Generator.php

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ public function generate(string $namespace, string $destinationPath)
3737
}
3838
}
3939

40-
private function className(string $className): string
40+
public static function className(string $className): string
4141
{
42-
return str_replace(['{', '}', '-', '$', '_'], ['Cb', 'Rcb', 'Dash', '_', '\\'], (new Convert($className))->toPascal()) . ($this->isKeyword($className) ? '_' : '');
42+
return str_replace(['{', '}', '-', '$', '_'], ['Cb', 'Rcb', 'Dash', '_', '\\'], (new Convert($className))->toPascal()) . (self::isKeyword($className) ? '_' : '');
4343
}
4444

4545
private function cleanUpNamespace(string $namespace): string
@@ -57,17 +57,17 @@ private function cleanUpNamespace(string $namespace): string
5757
*/
5858
private function all(string $namespace): iterable
5959
{
60+
$schemaRegistry = new SchemaRegistry();
6061
if (count($this->spec->components->schemas ?? []) > 0) {
61-
$schemaClassNameMap = [];
6262
foreach ($this->spec->components->schemas as $name => $schema) {
63-
$schemaClassName = $this->className($name);
63+
$schemaClassName = self::className($name);
6464
if (strlen($schemaClassName) === 0) {
6565
continue;
6666
}
67-
$schemaClassNameMap[spl_object_hash($schema)] = $schemaClassName;
67+
$schemaRegistry->addClassName($schemaClassName, $schema);
6868
}
6969
foreach ($this->spec->components->schemas as $name => $schema) {
70-
$schemaClassName = $schemaClassNameMap[spl_object_hash($schema)];
70+
$schemaClassName = $schemaRegistry->get($schema);
7171
if (strlen($schemaClassName) === 0) {
7272
continue;
7373
}
@@ -77,7 +77,7 @@ private function all(string $namespace): iterable
7777
$this->dirname($namespace . 'Schema/' . $schemaClassName),
7878
$this->basename($namespace . 'Schema/' . $schemaClassName),
7979
$schema,
80-
$schemaClassNameMap,
80+
$schemaRegistry,
8181
$namespace . 'Schema'
8282
);
8383
}
@@ -86,7 +86,7 @@ private function all(string $namespace): iterable
8686
$clients = [];
8787
if (count($this->spec->paths ?? []) > 0) {
8888
foreach ($this->spec->paths as $path => $pathItem) {
89-
$pathClassName = $this->className($path);
89+
$pathClassName = self::className($path);
9090
if (strlen($pathClassName) === 0) {
9191
continue;
9292
}
@@ -100,7 +100,7 @@ private function all(string $namespace): iterable
100100
);
101101

102102
foreach ($pathItem->getOperations() as $method => $operation) {
103-
$operationClassName = $this->className((new Convert($operation->operationId))->fromTrain()->toPascal()) . '_';
103+
$operationClassName = self::className((new Convert($operation->operationId))->fromTrain()->toPascal()) . '_';
104104
$operations[$method] = $operationClassName;
105105
if (strlen($operationClassName) === 0) {
106106
continue;
@@ -113,7 +113,7 @@ private function all(string $namespace): iterable
113113
$namespace,
114114
$this->basename($namespace . 'Operation/' . $operationClassName),
115115
$operation,
116-
$schemaClassNameMap
116+
$schemaRegistry
117117
);
118118

119119
[$operationGroup, $operationOperation] = explode('/', $operationClassName);
@@ -128,7 +128,7 @@ private function all(string $namespace): iterable
128128
}
129129
}
130130

131-
yield from (function (array $clients, string $namespace, array $schemaClassNameMap): \Generator {
131+
yield from (function (array $clients, string $namespace, SchemaRegistry $schemaRegistry): \Generator {
132132
foreach ($clients as $operationGroup => $operations) {
133133
yield from Client::generate(
134134
$operationGroup,
@@ -141,14 +141,14 @@ private function all(string $namespace): iterable
141141
yield from Clients::generate(
142142
$namespace,
143143
$clients,
144-
$schemaClassNameMap,
144+
$schemaRegistry,
145145
);
146-
})($clients, $namespace, $schemaClassNameMap);
146+
})($clients, $namespace, $schemaRegistry);
147147

148148
if (count($this->spec->webhooks ?? []) > 0) {
149149
$pathClassNameMapping = [];
150150
foreach ($this->spec->webhooks as $path => $pathItem) {
151-
$webHookClassName = $this->className($path);
151+
$webHookClassName = self::className($path);
152152
$pathClassNameMapping[$path] = $this->fqcn($namespace . 'WebHook/' . $webHookClassName);
153153
if (strlen($webHookClassName) === 0) {
154154
continue;
@@ -160,7 +160,7 @@ private function all(string $namespace): iterable
160160
$namespace,
161161
$this->basename($namespace . 'WebHook/' . $webHookClassName),
162162
$pathItem,
163-
$schemaClassNameMap,
163+
$schemaRegistry,
164164
$namespace
165165
);
166166
}
@@ -175,6 +175,17 @@ private function all(string $namespace): iterable
175175
$pathClassNameMapping,
176176
);
177177
}
178+
179+
foreach ($schemaRegistry->unknownSchemas() as $schema) {
180+
yield from Schema::generate(
181+
$schema['name'],
182+
$this->dirname($namespace . 'Schema/' . $schema['className']),
183+
$this->basename($namespace . 'Schema/' . $schema['className']),
184+
$schema['schema'],
185+
$schemaRegistry,
186+
$namespace . 'Schema'
187+
);
188+
}
178189
}
179190

180191
private function fqcn(string $fqcn): string
@@ -196,7 +207,7 @@ private function basename(string $fqcn): string
196207
return $this->cleanUpNamespace(basename($fqcn));
197208
}
198209

199-
private function isKeyword(string $name): bool
210+
private static function isKeyword(string $name): bool
200211
{
201212
return in_array($name, array('__halt_compiler', 'abstract', 'and', 'array', 'as', 'break', 'callable', 'case', 'catch', 'class', 'clone', 'const', 'continue', 'declare', 'default', 'die', 'do', 'echo', 'else', 'elseif', 'empty', 'enddeclare', 'endfor', 'endforeach', 'endif', 'endswitch', 'endwhile', 'eval', 'exit', 'extends', 'final', 'for', 'foreach', 'function', 'global', 'goto', 'if', 'implements', 'include', 'include_once', 'instanceof', 'insteadof', 'interface', 'isset', 'list', 'namespace', 'new', 'or', 'print', 'private', 'protected', 'public', 'require', 'require_once', 'return', 'static', 'switch', 'throw', 'trait', 'try', 'unset', 'use', 'var', 'while', 'xor'), false);
202213
}

src/Generator/Clients.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace ApiClients\Tools\OpenApiClientGenerator\Generator;
44

55
use ApiClients\Tools\OpenApiClientGenerator\File;
6+
use ApiClients\Tools\OpenApiClientGenerator\SchemaRegistry;
67
use cebe\openapi\spec\Operation as OpenAPiOperation;
78
use cebe\openapi\spec\PathItem;
89
use Jawira\CaseConverter\Convert;
@@ -26,7 +27,7 @@ final class Clients
2627
* @return iterable<Node>
2728
* @throws \Jawira\CaseConverter\CaseConverterException
2829
*/
29-
public static function generate(string $namespace, array $clients, array $schemaClassNameMap): iterable
30+
public static function generate(string $namespace, array $clients, SchemaRegistry $schemaRegistry): iterable
3031
{
3132
$factory = new BuilderFactory();
3233
$stmt = $factory->namespace(rtrim($namespace, '\\'));
@@ -94,7 +95,7 @@ public static function generate(string $namespace, array $clients, array $schema
9495
$returnType = [];
9596
foreach ($operationDetails['operation']->responses as $spec) {
9697
foreach ($spec->content as $contentTypeSchema) {
97-
$callReturnTypes[] = $returnType[] = '\\' . $namespace . 'Schema\\' . $schemaClassNameMap[spl_object_hash($contentTypeSchema->schema)];
98+
$callReturnTypes[] = $returnType[] = '\\' . $namespace . 'Schema\\' . $schemaRegistry->get($contentTypeSchema->schema);
9899
}
99100
}
100101
$operationCalls[] = [

src/Generator/Operation.php

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace ApiClients\Tools\OpenApiClientGenerator\Generator;
44

55
use ApiClients\Tools\OpenApiClientGenerator\File;
6+
use ApiClients\Tools\OpenApiClientGenerator\SchemaRegistry;
67
use cebe\openapi\spec\Operation as OpenAPiOperation;
78
use PhpParser\Builder\Param;
89
use PhpParser\BuilderFactory;
@@ -25,7 +26,7 @@ final class Operation
2526
* @param OpenAPiOperation $operation
2627
* @return iterable<Node>
2728
*/
28-
public static function generate(string $path, string $method, string $namespace, string $rootNamespace, string $className, OpenAPiOperation $operation, array $schemaClassNameMap): iterable
29+
public static function generate(string $path, string $method, string $namespace, string $rootNamespace, string $className, OpenAPiOperation $operation, SchemaRegistry $schemaRegistry): iterable
2930
{
3031
$factory = new BuilderFactory();
3132
$stmt = $factory->namespace($namespace);
@@ -180,7 +181,13 @@ public static function generate(string $path, string $method, string $namespace,
180181
new Node\Name('validate'),
181182
[
182183
new Node\Arg(new Node\Expr\Variable('data')),
183-
new Node\Arg(new Node\Expr\StaticCall(new Node\Name('\cebe\openapi\Reader'), new Node\Name('readFromJson'), [new Node\Scalar\String_(json_encode($requestBodyContent->schema->getSerializableData())), new Node\Scalar\String_('\cebe\openapi\spec\Schema')])),
184+
new Node\Arg(new Node\Expr\StaticCall(new Node\Name('\cebe\openapi\Reader'), new Node\Name('readFromJson'), [
185+
new Node\Expr\ClassConstFetch(
186+
new Node\Name('\\' . $rootNamespace . 'Schema\\' . $schemaRegistry->get($requestBodyContent->schema)),
187+
new Node\Name('SCHEMA_JSON'),
188+
),
189+
new Node\Scalar\String_('\cebe\openapi\spec\Schema'),
190+
])),
184191
]
185192
))
186193
);
@@ -207,7 +214,7 @@ public static function generate(string $path, string $method, string $namespace,
207214
foreach ($operation->responses as $code => $spec) {
208215
$contentTypeCases = [];
209216
foreach ($spec->content as $contentType => $contentTypeSchema) {
210-
$returnType[] = $object = '\\' . $rootNamespace . 'Schema\\' . $schemaClassNameMap[spl_object_hash($contentTypeSchema->schema)];
217+
$returnType[] = $object = '\\' . $rootNamespace . 'Schema\\' . $schemaRegistry->get($contentTypeSchema->schema);
211218
$ctc = new Node\Stmt\Case_(
212219
new Node\Scalar\String_($contentType),
213220
[
@@ -219,7 +226,13 @@ public static function generate(string $path, string $method, string $namespace,
219226
new Node\Name('validate'),
220227
[
221228
new Node\Arg(new Node\Expr\Variable('body')),
222-
new Node\Arg(new Node\Expr\StaticCall(new Node\Name('\cebe\openapi\Reader'), new Node\Name('readFromJson'), [new Node\Scalar\String_(json_encode($contentTypeSchema->schema->getSerializableData())), new Node\Scalar\String_('\cebe\openapi\spec\Schema')])),
229+
new Node\Arg(new Node\Expr\StaticCall(new Node\Name('\cebe\openapi\Reader'), new Node\Name('readFromJson'), [
230+
new Node\Expr\ClassConstFetch(
231+
new Node\Name('\\' . $rootNamespace . 'Schema\\' . $schemaRegistry->get($contentTypeSchema->schema)),
232+
new Node\Name('SCHEMA_JSON'),
233+
),
234+
new Node\Scalar\String_('\cebe\openapi\spec\Schema'),
235+
])),
223236
]
224237
)),
225238
new Node\Stmt\Return_(new Node\Expr\MethodCall(

0 commit comments

Comments
 (0)