-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathSchemaCleaner.php
More file actions
146 lines (128 loc) · 4.94 KB
/
SchemaCleaner.php
File metadata and controls
146 lines (128 loc) · 4.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
<?php namespace Draw\Swagger;
use Draw\Swagger\Schema\PathItem;
use Draw\Swagger\Schema\Schema;
use Draw\Swagger\Schema\Swagger as SwaggerSchema;
/**
* This class is to clean up the schema before dumping it.
* It will remove duplicate definition alias
*
* @internal
*/
class SchemaCleaner
{
/**
* @param SwaggerSchema $swaggerSchema
* @return SwaggerSchema The cleaned schema
*/
public function clean(SwaggerSchema $swaggerSchema)
{
// This is to "clone" the object recursively
/** @var SwaggerSchema $swaggerSchema */
$swaggerSchema = unserialize(serialize($swaggerSchema));
do {
$definitionSchemasByObject = [];
foreach($swaggerSchema->definitions as $name => $definitionSchema) {
$definitionSchemasByObject[parse_url($name)['path']][$name] = $definitionSchema;
}
$replaceSchemas = [];
foreach ($definitionSchemasByObject as $objectName => $definitionSchemas) {
/** @var Schema[] $selectedSchemas */
$selectedSchemas = [];
array_walk($definitionSchemas,
function (Schema $schema, $name) use (&$selectedSchemas, &$replaceSchemas) {
foreach ($selectedSchemas as $selectedName => $selectedSchema) {
if ($this->isEqual($selectedSchema, $schema)) {
$replaceSchemas[$name] = $selectedName;
return;
}
}
$selectedSchemas[$name] = $schema;
});
}
foreach($replaceSchemas as $toReplace => $replaceWith) {
$this->replaceSchemaReference(
$swaggerSchema,
'#/definitions/' . $toReplace,
'#/definitions/' . $replaceWith
);
unset($swaggerSchema->definitions[$toReplace]);
}
} while (count($replaceSchemas));
do {
$suppressionOccurred = false;
foreach ($swaggerSchema->definitions as $name => $definitionSchema) {
if (!$this->hasSchemaReference($swaggerSchema, '#/definitions/' . $name)) {
unset($swaggerSchema->definitions[$name]);
$suppressionOccurred = true;
}
}
} while ($suppressionOccurred);
// Rename aliases in case of skip to be cleaner (e.g.: [User?3, User?6] => [User, User?1])
$definitionsToRename = [];
foreach($swaggerSchema->definitions as $name => $definitionSchema) {
$definitionsToRename[parse_url($name)['path']][] = $name;
}
foreach ($definitionsToRename as $objectName => $names) {
array_walk($names,
function ($name, $index) use ($objectName, $swaggerSchema) {
$replaceWith = $objectName . ($index ? '?' . $index : '');
// If the replace name is the same as the current index we do not do anything
if($replaceWith == $name) {
return;
}
$swaggerSchema->definitions[$replaceWith] = $swaggerSchema->definitions[$name];
unset($swaggerSchema->definitions[$name]);
$this->replaceSchemaReference(
$swaggerSchema,
'#/definitions/' . $name,
'#/definitions/' . $replaceWith
);
});
}
return $swaggerSchema;
}
private function hasSchemaReference($data, $reference)
{
if(!is_object($data) && !is_array($data)) {
return false;
}
if(is_object($data)) {
if($data instanceof Schema || $data instanceof PathItem) {
if($data->ref == $reference) {
return true;
}
}
}
foreach ($data as &$value) {
if ($this->hasSchemaReference($value, $reference)) {
return true;
}
}
return false;
}
private function replaceSchemaReference($data, $definitionToReplace, $definitionToReplaceWith)
{
if(!is_object($data) && !is_array($data)) {
return;
}
if(is_object($data)) {
if($data instanceof Schema || $data instanceof PathItem) {
if($data->ref == $definitionToReplace) {
$data->ref = $definitionToReplaceWith;
}
}
}
foreach($data as &$value) {
$this->replaceSchemaReference($value, $definitionToReplace, $definitionToReplaceWith);
}
}
/**
* @param Schema $schemaA
* @param Schema $schemaB
* @return bool
*/
private function isEqual(Schema $schemaA, Schema $schemaB)
{
return $schemaA == $schemaB;
}
}