Skip to content

Commit c4f4bf8

Browse files
authored
Merge pull request #54 from php-api-clients/introduce-client-to-wire-everything-up
Introduce client to wire operations up
2 parents f577a4d + d0c908d commit c4f4bf8

File tree

3 files changed

+145
-1
lines changed

3 files changed

+145
-1
lines changed

src/Generator.php

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace ApiClients\Tools\OpenApiClientGenerator;
44

5+
use ApiClients\Tools\OpenApiClientGenerator\Generator\Client;
6+
use ApiClients\Tools\OpenApiClientGenerator\Generator\Clients;
57
use ApiClients\Tools\OpenApiClientGenerator\Generator\Operation;
68
use ApiClients\Tools\OpenApiClientGenerator\Generator\Path;
79
use ApiClients\Tools\OpenApiClientGenerator\Generator\Schema;
@@ -81,6 +83,7 @@ private function all(string $namespace): iterable
8183
}
8284
}
8385

86+
$clients = [];
8487
if (count($this->spec->paths ?? []) > 0) {
8588
foreach ($this->spec->paths as $path => $pathItem) {
8689
$pathClassName = $this->className($path);
@@ -97,7 +100,7 @@ private function all(string $namespace): iterable
97100
);
98101

99102
foreach ($pathItem->getOperations() as $method => $operation) {
100-
$operationClassName = $this->className((new Convert($operation->operationId))->fromTrain()->toPascal());
103+
$operationClassName = $this->className((new Convert($operation->operationId))->fromTrain()->toPascal()) . '_';
101104
$operations[$method] = $operationClassName;
102105
if (strlen($operationClassName) === 0) {
103106
continue;
@@ -110,10 +113,35 @@ private function all(string $namespace): iterable
110113
$this->basename($namespace . 'Operation/' . $operationClassName),
111114
$operation
112115
);
116+
117+
[$operationGroup, $operationOperation] = explode('/', $operationClassName);
118+
if (!array_key_exists($operationGroup, $clients)) {
119+
$clients[$operationGroup] = [];
120+
}
121+
$clients[$operationGroup][$operationOperation] = [
122+
'class' => $operationClassName,
123+
'operation' => $operation,
124+
];
113125
}
114126
}
115127
}
116128

129+
yield from (function (array $clients, string $namespace): \Generator {
130+
foreach ($clients as $operationGroup => $operations) {
131+
yield from Client::generate(
132+
$operationGroup,
133+
$this->dirname($namespace . 'Operation/' . $operationGroup),
134+
$this->basename($namespace . 'Operation/' . $operationGroup),
135+
$operations,
136+
);
137+
138+
}
139+
yield from Clients::generate(
140+
$namespace,
141+
$clients,
142+
);
143+
})($clients, $namespace);
144+
117145
if (count($this->spec->webhooks ?? []) > 0) {
118146
$pathClassNameMapping = [];
119147
foreach ($this->spec->webhooks as $path => $pathItem) {

src/Generator/Client.php

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<?php
2+
3+
namespace ApiClients\Tools\OpenApiClientGenerator\Generator;
4+
5+
use ApiClients\Tools\OpenApiClientGenerator\File;
6+
use cebe\openapi\spec\Operation as OpenAPiOperation;
7+
use PhpParser\Builder\Param;
8+
use PhpParser\BuilderFactory;
9+
use PhpParser\Node;
10+
use PhpParser\Node\Stmt\Class_;
11+
use Psr\Http\Message\RequestInterface;
12+
use RingCentral\Psr7\Request;
13+
14+
final class Client
15+
{
16+
/**
17+
* @param array<string, string> $operations
18+
* @return iterable<Node>
19+
*/
20+
public static function generate(string $operationGroup, string $namespace, string $className, array $operations): iterable
21+
{
22+
$factory = new BuilderFactory();
23+
$stmt = $factory->namespace($namespace);
24+
25+
$class = $factory->class($className)->makeFinal();
26+
27+
foreach ($operations as $operationOperation => $operationDetails) {
28+
$params = [];
29+
$cn = str_replace('/', '\\', '\\' . $namespace . '\\' . $operationDetails['class']);
30+
$method = $factory->method(lcfirst($operationOperation))->setReturnType($cn)->makePublic();
31+
foreach ($operationDetails['operation']->parameters as $parameter) {
32+
$params[] = new Node\Arg(new Node\Expr\Variable($parameter->name));
33+
$param = new Param($parameter->name);
34+
if ($parameter->schema->default !== null) {
35+
$param->setType(
36+
str_replace([
37+
'integer',
38+
'any',
39+
'boolean',
40+
], [
41+
'int',
42+
'',
43+
'bool',
44+
], $parameter->schema->type)
45+
);
46+
}
47+
if ($parameter->schema->default !== null) {
48+
$param->setDefault($parameter->schema->default);
49+
}
50+
$method->addParam($param);
51+
}
52+
$class->addStmt($method->addStmt(
53+
new Node\Stmt\Return_(
54+
new Node\Expr\New_(
55+
new Node\Name(
56+
$cn
57+
),
58+
$params
59+
)
60+
)
61+
));
62+
}
63+
64+
yield new File($namespace . '\\' . $className, $stmt->addStmt($class)->getNode());
65+
}
66+
}

src/Generator/Clients.php

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
namespace ApiClients\Tools\OpenApiClientGenerator\Generator;
4+
5+
use ApiClients\Tools\OpenApiClientGenerator\File;
6+
use cebe\openapi\spec\Operation as OpenAPiOperation;
7+
use cebe\openapi\spec\PathItem;
8+
use Jawira\CaseConverter\Convert;
9+
use League\OpenAPIValidation\Schema\Exception\SchemaMismatch;
10+
use PhpParser\Builder\Param;
11+
use PhpParser\BuilderFactory;
12+
use PhpParser\Node;
13+
use PhpParser\Node\Stmt\Class_;
14+
use Psr\Http\Message\RequestInterface;
15+
use Psr\Http\Message\ServerRequestInterface;
16+
use RingCentral\Psr7\Request;
17+
18+
final class Clients
19+
{
20+
/**
21+
* @return iterable<Node>
22+
* @throws \Jawira\CaseConverter\CaseConverterException
23+
*/
24+
public static function generate(string $namespace, array $clients): iterable
25+
{
26+
$factory = new BuilderFactory();
27+
$stmt = $factory->namespace(rtrim($namespace, '\\'));
28+
29+
$class = $factory->class('Client')->makeFinal();
30+
31+
32+
foreach ($clients as $operationGroup => $operations) {
33+
$cn = str_replace('/', '\\', '\\' . $namespace . 'Operation/' . $operationGroup);
34+
$class->addStmt(
35+
$factory->method(lcfirst($operationGroup))->setReturnType($cn)->addStmt(
36+
new Node\Stmt\Return_(
37+
new Node\Expr\New_(
38+
new Node\Name(
39+
$cn
40+
),
41+
)
42+
)
43+
)->makePublic()
44+
);
45+
}
46+
47+
48+
yield new File($namespace . '\\' . 'Client', $stmt->addStmt($class)->getNode());
49+
}
50+
}

0 commit comments

Comments
 (0)