Skip to content

Commit 7f506f1

Browse files
committed
major updates
1 parent 15c2a7f commit 7f506f1

45 files changed

Lines changed: 4489 additions & 55 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/Builder/ApiDocBuilder.php

Lines changed: 95 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,15 @@ class ApiDocBuilder
3131
/** @var array<string, array<string, mixed>> */
3232
private array $securitySchemes = [];
3333

34+
/** @var array<string, array<string, mixed>> */
35+
private array $links = [];
36+
37+
/** @var array<string, array<string, mixed>> */
38+
private array $callbacks = [];
39+
40+
/** @var array<string, array<string, mixed>> */
41+
private array $pathItems = [];
42+
3443
/**
3544
* Start building a new route/path definition.
3645
*/
@@ -77,6 +86,36 @@ public function addTag(string $name): TagBuilder
7786
return new TagBuilder($this, $name);
7887
}
7988

89+
/**
90+
* Start building a new link component.
91+
*
92+
* @param string $name The link name
93+
*/
94+
public function addLink(string $name): LinkBuilder
95+
{
96+
return new LinkBuilder($this, $name);
97+
}
98+
99+
/**
100+
* Start building a new callback component.
101+
*
102+
* @param string $name The callback name
103+
*/
104+
public function addCallback(string $name): CallbackBuilder
105+
{
106+
return new CallbackBuilder($this, $name);
107+
}
108+
109+
/**
110+
* Start building a new path item component.
111+
*
112+
* @param string $name The path item name
113+
*/
114+
public function addPathItem(string $name): PathItemBuilder
115+
{
116+
return new PathItemBuilder($this, $name);
117+
}
118+
80119
/**
81120
* Register a custom reference name for a schema.
82121
* This allows you to use short aliases instead of full schema names.
@@ -232,6 +271,45 @@ public function registerSecurityScheme(string $name, array $definition): void
232271
$this->securitySchemes[$name] = $definition;
233272
}
234273

274+
/**
275+
* Internal method to register a link definition.
276+
*
277+
* @param string $name The link name
278+
* @param array<string, mixed> $definition The link definition
279+
*
280+
* @internal
281+
*/
282+
public function registerLink(string $name, array $definition): void
283+
{
284+
$this->links[$name] = $definition;
285+
}
286+
287+
/**
288+
* Internal method to register a callback definition.
289+
*
290+
* @param string $name The callback name
291+
* @param array<string, mixed> $definition The callback definition
292+
*
293+
* @internal
294+
*/
295+
public function registerCallback(string $name, array $definition): void
296+
{
297+
$this->callbacks[$name] = $definition;
298+
}
299+
300+
/**
301+
* Internal method to register a path item definition.
302+
*
303+
* @param string $name The path item name
304+
* @param array<string, mixed> $definition The path item definition
305+
*
306+
* @internal
307+
*/
308+
public function registerPathItem(string $name, array $definition): void
309+
{
310+
$this->pathItems[$name] = $definition;
311+
}
312+
235313
/**
236314
* Get all paths (routes) as an array.
237315
*
@@ -292,14 +370,29 @@ public function build(): array
292370
$spec['paths'] = $this->paths;
293371
}
294372

295-
// Add components (schemas and securitySchemes)
296-
if (!empty($this->schemas) || !empty($this->securitySchemes)) {
373+
// Add components (schemas, securitySchemes, links, callbacks, pathItems)
374+
$hasComponents = !empty($this->schemas)
375+
|| !empty($this->securitySchemes)
376+
|| !empty($this->links)
377+
|| !empty($this->callbacks)
378+
|| !empty($this->pathItems);
379+
380+
if ($hasComponents) {
297381
if (!empty($this->schemas)) {
298382
$spec['components']['schemas'] = $this->schemas;
299383
}
300384
if (!empty($this->securitySchemes)) {
301385
$spec['components']['securitySchemes'] = $this->securitySchemes;
302386
}
387+
if (!empty($this->links)) {
388+
$spec['components']['links'] = $this->links;
389+
}
390+
if (!empty($this->callbacks)) {
391+
$spec['components']['callbacks'] = $this->callbacks;
392+
}
393+
if (!empty($this->pathItems)) {
394+
$spec['components']['pathItems'] = $this->pathItems;
395+
}
303396
}
304397

305398
return $spec;

src/Builder/CallbackBuilder.php

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<?php
2+
3+
namespace Ehyiah\ApiDocBundle\Builder;
4+
5+
/**
6+
* Fluent builder for defining OpenAPI Callback objects.
7+
*
8+
* A map of out-of-band callbacks related to the parent operation.
9+
* Each entry is an expression that evaluates to a Path Item Object.
10+
*/
11+
class CallbackBuilder
12+
{
13+
/** @var RouteBuilder|ApiDocBuilder */
14+
private $parentBuilder;
15+
16+
private string $name;
17+
18+
/** @var array<string, mixed> */
19+
private array $definition = [];
20+
21+
/**
22+
* @param RouteBuilder|ApiDocBuilder $parentBuilder The parent builder
23+
* @param string $name The callback name
24+
*/
25+
public function __construct($parentBuilder, string $name)
26+
{
27+
$this->parentBuilder = $parentBuilder;
28+
$this->name = $name;
29+
}
30+
31+
/**
32+
* Add a path item under an expression.
33+
*
34+
* @param string $expression The key expression (e.g., '{$request.body#/callbackUrl}')
35+
* @param array<string, mixed> $pathItem A Path Item Object definition
36+
*/
37+
public function pathItem(string $expression, array $pathItem): self
38+
{
39+
$this->definition[$expression] = $pathItem;
40+
41+
return $this;
42+
}
43+
44+
/**
45+
* Finish building this callback and return to the parent builder.
46+
*
47+
* @return RouteBuilder|ApiDocBuilder
48+
*/
49+
public function end()
50+
{
51+
if ($this->parentBuilder instanceof ApiDocBuilder) {
52+
$this->parentBuilder->registerCallback($this->name, $this->definition);
53+
}
54+
55+
return $this->parentBuilder;
56+
}
57+
58+
/**
59+
* Get the callback name.
60+
*
61+
* @internal
62+
*/
63+
public function getName(): string
64+
{
65+
return $this->name;
66+
}
67+
68+
/**
69+
* Build the callback definition as an array.
70+
*
71+
* @return array<string, mixed>
72+
*
73+
* @internal
74+
*/
75+
public function buildArray(): array
76+
{
77+
return $this->definition;
78+
}
79+
}

src/Builder/ExampleBuilder.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,18 @@ public function externalValue(string $url): self
8787
return $this;
8888
}
8989

90+
/**
91+
* Set a reference to an existing example component.
92+
*
93+
* @param string $ref Reference path (e.g., '#/components/examples/SuccessResponse')
94+
*/
95+
public function ref(string $ref): self
96+
{
97+
$this->definition = ['$ref' => $ref];
98+
99+
return $this;
100+
}
101+
90102
/**
91103
* Finish building this example and return to the parent builder.
92104
*

src/Builder/LinkBuilder.php

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
<?php
2+
3+
namespace Ehyiah\ApiDocBundle\Builder;
4+
5+
/**
6+
* Fluent builder for defining OpenAPI Link objects.
7+
*
8+
* Links allow outgoing requests to other operations for request/response pairs.
9+
*/
10+
class LinkBuilder
11+
{
12+
/** @var ResponseBuilder|ApiDocBuilder */
13+
private $parentBuilder;
14+
15+
private string $name;
16+
17+
/** @var array<string, mixed> */
18+
private array $definition = [];
19+
20+
/**
21+
* @param ResponseBuilder|ApiDocBuilder $parentBuilder The parent builder
22+
* @param string $name The link name
23+
*/
24+
public function __construct($parentBuilder, string $name)
25+
{
26+
$this->parentBuilder = $parentBuilder;
27+
$this->name = $name;
28+
}
29+
30+
/**
31+
* Set the reference to an existing Operation Object.
32+
*
33+
* @param string $operationRef Relative or absolute URI reference to an OAS operation
34+
*/
35+
public function operationRef(string $operationRef): self
36+
{
37+
$this->definition['operationRef'] = $operationRef;
38+
39+
return $this;
40+
}
41+
42+
/**
43+
* Set the operationId of an existing operation.
44+
*
45+
* @param string $operationId The name of an existing, resolvable OAS operation
46+
*/
47+
public function operationId(string $operationId): self
48+
{
49+
$this->definition['operationId'] = $operationId;
50+
51+
return $this;
52+
}
53+
54+
/**
55+
* Add a parameter to pass to the operation.
56+
*
57+
* @param string $name Parameter name
58+
* @param string $value A literal value or expression
59+
*/
60+
public function parameter(string $name, string $value): self
61+
{
62+
if (!isset($this->definition['parameters'])) {
63+
$this->definition['parameters'] = [];
64+
}
65+
$this->definition['parameters'][$name] = $value;
66+
67+
return $this;
68+
}
69+
70+
/**
71+
* Set the request body to pass to the operation.
72+
*
73+
* @param string $value A literal value or expression
74+
*/
75+
public function requestBody(string $value): self
76+
{
77+
$this->definition['requestBody'] = $value;
78+
79+
return $this;
80+
}
81+
82+
/**
83+
* Set a description of the link.
84+
*
85+
* @param string $description CommonMark syntax MAY be used for rich text representation
86+
*/
87+
public function description(string $description): self
88+
{
89+
$this->definition['description'] = $description;
90+
91+
return $this;
92+
}
93+
94+
/**
95+
* Set a server object to be used by the target operation.
96+
*
97+
* @param string $url URL of the target server
98+
* @param string|null $description An optional description
99+
*/
100+
public function server(string $url, ?string $description = null): self
101+
{
102+
$server = ['url' => $url];
103+
if (null !== $description) {
104+
$server['description'] = $description;
105+
}
106+
$this->definition['server'] = $server;
107+
108+
return $this;
109+
}
110+
111+
/**
112+
* Finish building this link and return to the parent builder.
113+
*
114+
* @return ResponseBuilder|ApiDocBuilder
115+
*/
116+
public function end()
117+
{
118+
if ($this->parentBuilder instanceof ApiDocBuilder) {
119+
$this->parentBuilder->registerLink($this->name, $this->definition);
120+
}
121+
122+
return $this->parentBuilder;
123+
}
124+
125+
/**
126+
* Get the link name.
127+
*
128+
* @internal
129+
*/
130+
public function getName(): string
131+
{
132+
return $this->name;
133+
}
134+
135+
/**
136+
* Build the link definition as an array.
137+
*
138+
* @return array<string, mixed>
139+
*
140+
* @internal
141+
*/
142+
public function buildArray(): array
143+
{
144+
return $this->definition;
145+
}
146+
}

0 commit comments

Comments
 (0)