Skip to content

Commit 71d7f8d

Browse files
committed
WIP Paths, PathItem, Operation, Parameter, Response
1 parent 8d90e03 commit 71d7f8d

11 files changed

Lines changed: 408 additions & 26 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ READ [OpenAPI](https://www.openapis.org/) 3.0.x YAML and JSON files and make the
1313

1414
## Requirements
1515

16-
- PHP 7.0 or higher
16+
- PHP 7.1 or higher
1717

1818
## Usage
1919

composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"source": "https://github.com/cebe/php-openapi"
1919
},
2020
"require": {
21-
"php": ">=7.0.0",
21+
"php": ">=7.1.0",
2222
"ext-json": "*",
2323
"symfony/yaml": "^3.3"
2424
},
@@ -35,7 +35,7 @@
3535
},
3636
"config": {
3737
"platform": {
38-
"php": "7.0.8"
38+
"php": "7.1.0"
3939
}
4040
},
4141
"extra": {

src/Reader.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@
1616
*/
1717
class Reader
1818
{
19-
public static function readFromJson(string $json, string $baseType = OpenApi::class): SpecBaseObject
19+
public static function readFromJson(string $json, string $baseType = OpenApi::class): SpecObjectInterface
2020
{
2121
return new $baseType(json_decode($json, true));
2222
}
2323

24-
public static function readFromYaml(string $yaml, string $baseType = OpenApi::class): SpecBaseObject
24+
public static function readFromYaml(string $yaml, string $baseType = OpenApi::class): SpecObjectInterface
2525
{
2626
return new $baseType(Yaml::parse($yaml));
2727
}

src/SpecBaseObject.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
* Implements property management and validation basics.
1818
*
1919
*/
20-
abstract class SpecBaseObject
20+
abstract class SpecBaseObject implements SpecObjectInterface
2121
{
2222
private $_properties = [];
2323
private $_errors = [];
@@ -115,11 +115,11 @@ public function __construct(array $data)
115115
public function validate(): bool
116116
{
117117
foreach ($this->_properties as $v) {
118-
if ($v instanceof self) {
118+
if ($v instanceof SpecObjectInterface) {
119119
$v->validate();
120120
} elseif (is_array($v)) {
121121
foreach($v as $item) {
122-
if ($item instanceof self) {
122+
if ($item instanceof SpecObjectInterface) {
123123
$item->validate();
124124
}
125125
}
@@ -137,11 +137,11 @@ public function getErrors(): array
137137
{
138138
$errors = [$this->_errors];
139139
foreach ($this->_properties as $v) {
140-
if ($v instanceof self) {
140+
if ($v instanceof SpecObjectInterface) {
141141
$errors[] = $v->getErrors();
142142
} elseif (is_array($v)) {
143143
foreach($v as $item) {
144-
if ($item instanceof self) {
144+
if ($item instanceof SpecObjectInterface) {
145145
$errors[] = $item->getErrors();
146146
}
147147
}

src/SpecObjectInterface.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
/**
3+
* Created by PhpStorm.
4+
* User: cebe
5+
* Date: 07.11.18
6+
* Time: 23:22
7+
*/
8+
9+
namespace cebe\openapi;
10+
11+
/**
12+
* This interface is implemented by all classes that represent objects from the OpenAPI Spec.
13+
*/
14+
interface SpecObjectInterface
15+
{
16+
/**
17+
* Create an object from spec data.
18+
* @param array $data spec data read from YAML or JSON
19+
*/
20+
public function __construct(array $data);
21+
22+
/**
23+
* Validate object data according to OpenAPI spec.
24+
* @return bool whether the loaded data is valid according to OpenAPI spec
25+
* @see getErrors()
26+
*/
27+
public function validate(): bool;
28+
29+
/**
30+
* @return string[] list of validation errors according to OpenAPI spec.
31+
* @see validate()
32+
*/
33+
public function getErrors(): array;
34+
35+
}

src/spec/Operation.php

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?php
2+
/**
3+
* Created by PhpStorm.
4+
* User: cebe
5+
* Date: 07.11.18
6+
* Time: 23:46
7+
*/
8+
9+
namespace cebe\openapi\spec;
10+
use cebe\openapi\SpecBaseObject;
11+
12+
/**
13+
* Describes a single API operation on a path.
14+
*
15+
* @link https://github.com/OAI/OpenAPI-Specification/blob/3.0.2/versions/3.0.2.md#operationObject
16+
*
17+
* @property-read string[] $tags
18+
* @property-read string $summary
19+
* @property-read string $description
20+
* @property-read ExternalDocumentation|null $externalDocs
21+
* @property-read string $operationId
22+
* @property-read Parameter[]|Reference[] $parameters
23+
* @property-read RequestBody|Reference $requestBody
24+
* @property-read Responses $responses
25+
* @property-read Callback[]|Reference[] $callbacks
26+
* @property-read bool $deprecated
27+
* @property-read SecurityRequirement[] $security
28+
* @property-read Server[] $servers
29+
*/
30+
class Operation extends SpecBaseObject
31+
{
32+
33+
/**
34+
* @return array array of attributes available in this object.
35+
*/
36+
protected function attributes(): array
37+
{
38+
return [
39+
'tags' => [Tag::class],
40+
'summary' => Type::STRING,
41+
'description' => Type::STRING,
42+
'externalDocs' => ExternalDocumentation::class,
43+
'operationId' => Type::STRING,
44+
'parameters' => [Parameter::class],// TODO reference
45+
'requestBody' => RequestBody::class,
46+
'responses' => Responses::class,
47+
'callbacks' => [Callback::class],// TODO reference
48+
'deprecated' => Type::BOOLEAN,
49+
'security' => [SecurityRequirement::class],
50+
'servers' => [Server::class],
51+
];
52+
}
53+
54+
/**
55+
* Perform validation on this object, check data against OpenAPI Specification rules.
56+
*
57+
* Call `addError()` in case of validation errors.
58+
*/
59+
protected function performValidation()
60+
{
61+
$this->requireProperties(['responses']);
62+
}
63+
}

src/spec/Parameter.php

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,39 @@
1414
*
1515
* @link https://github.com/OAI/OpenAPI-Specification/blob/3.0.2/versions/3.0.2.md#parameterObject
1616
*
17+
* @property-read string $name
18+
* @property-read string $in
19+
* @property-read string $description
20+
* @property-read bool $required
21+
* @property-read bool $deprecated
22+
* @property-read bool $allowEmptyValue
23+
*
24+
* TODO implement more
1725
*/
18-
class Parameter
26+
class Parameter extends SpecBaseObject
1927
{
20-
// TODO implement
28+
/**
29+
* @return array array of attributes available in this object.
30+
*/
31+
protected function attributes(): array
32+
{
33+
return [
34+
'name' => Type::STRING,
35+
'in' => Type::STRING,
36+
'description' => Type::STRING,
37+
'required' => Type::BOOLEAN,
38+
'deprecated' => Type::BOOLEAN,
39+
'allowEmptyValue' => Type::BOOLEAN,
40+
];
41+
}
42+
43+
/**
44+
* Perform validation on this object, check data against OpenAPI Specification rules.
45+
*
46+
* Call `addError()` in case of validation errors.
47+
*/
48+
protected function performValidation()
49+
{
50+
// TODO: Implement performValidation() method.
51+
}
2152
}

src/spec/PathItem.php

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,19 @@
1515
* A Path Item MAY be empty, due to ACL constraints. The path itself is still exposed to the documentation
1616
* viewer but they will not know which operations and parameters are available.
1717
*
18-
* // @TODO $ref
18+
* @link https://github.com/OAI/OpenAPI-Specification/blob/3.0.2/versions/3.0.2.md#pathItemObject
19+
*
1920
* @property-read string $summary
2021
* @property-read string $description
21-
* @property-read Operation $get
22-
* @property-read Operation $put
23-
* @property-read Operation $post
24-
* @property-read Operation $delete
25-
* @property-read Operation $options
26-
* @property-read Operation $head
27-
* @property-read Operation $patch
28-
* @property-read Operation $trace
29-
* @property-read Server $servers
22+
* @property-read Operation|null $get
23+
* @property-read Operation|null $put
24+
* @property-read Operation|null $post
25+
* @property-read Operation|null $delete
26+
* @property-read Operation|null $options
27+
* @property-read Operation|null $head
28+
* @property-read Operation|null $patch
29+
* @property-read Operation|null $trace
30+
* @property-read Server[] $servers
3031
* @property-read Parameter[]|Reference[] $parameters
3132
*
3233
*/
@@ -38,7 +39,6 @@ class PathItem extends SpecBaseObject
3839
protected function attributes(): array
3940
{
4041
return [
41-
// '$ref' => TYPE::REFERENCE,
4242
'summary' => Type::STRING,
4343
'description' => Type::STRING,
4444
'get' => Operation::class,

src/spec/Paths.php

Lines changed: 85 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
namespace cebe\openapi\spec;
99

10-
use cebe\openapi\SpecBaseObject;
10+
use cebe\openapi\SpecObjectInterface;
1111

1212
/**
1313
* Holds the relative paths to the individual endpoints and their operations.
@@ -18,7 +18,89 @@
1818
* @link https://github.com/OAI/OpenAPI-Specification/blob/3.0.2/versions/3.0.2.md#pathsObject
1919
*
2020
*/
21-
class Paths
21+
class Paths implements SpecObjectInterface
2222
{
23-
// TODO implement
23+
/**
24+
* @var PathItem[]
25+
*/
26+
private $_paths = [];
27+
28+
private $_errors = [];
29+
30+
public function __construct(array $data)
31+
{
32+
foreach($data as $path => $object) {
33+
// TODO support reference
34+
if ($object === null) {
35+
$this->_paths[$path] = null;
36+
} else {
37+
$this->_paths[$path] = new PathItem($object);
38+
}
39+
}
40+
}
41+
42+
/**
43+
* @param string $name path name
44+
* @return bool
45+
*/
46+
public function hasPath(string $name): bool
47+
{
48+
return isset($this->_paths[$name]);
49+
}
50+
51+
/**
52+
* @param string $name path name
53+
* @return PathItem
54+
*/
55+
public function getPath(string $name): ?PathItem
56+
{
57+
return $this->_paths[$name] ?? null;
58+
}
59+
60+
/**
61+
* @return PathItem[]
62+
*/
63+
public function getPaths(): array
64+
{
65+
return $this->_paths;
66+
}
67+
68+
/**
69+
* Validate object data according to OpenAPI spec.
70+
* @return bool whether the loaded data is valid according to OpenAPI spec
71+
* @see getErrors()
72+
*/
73+
public function validate(): bool
74+
{
75+
$valid = true;
76+
$this->_errors = [];
77+
foreach($this->_paths as $key => $path) {
78+
if ($path === null) {
79+
continue;
80+
}
81+
if (!$path->validate()) {
82+
$valid = false;
83+
}
84+
if (strpos($key, '/') !== 0) {
85+
$this->_errors[] = "Path must begin with /: $key";
86+
}
87+
}
88+
return $valid && empty($this->_errors);
89+
}
90+
91+
/**
92+
* @return string[] list of validation errors according to OpenAPI spec.
93+
* @see validate()
94+
*/
95+
public function getErrors(): array
96+
{
97+
$errors = [$this->_errors];
98+
foreach ($this->_paths as $path) {
99+
if ($path === null) {
100+
continue;
101+
}
102+
$errors[] = $path->getErrors();
103+
}
104+
return array_merge(...$errors);
105+
}
24106
}

0 commit comments

Comments
 (0)