Skip to content

Commit 3e46c05

Browse files
authored
Merge pull request #10 from kaz29/feat/cakephp5
Feat/cakephp5
2 parents 32281c3 + d6589fb commit 3e46c05

File tree

9 files changed

+346
-276
lines changed

9 files changed

+346
-276
lines changed

composer.json

+10-3
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@
44
"type": "cakephp-plugin",
55
"license": "MIT",
66
"require": {
7-
"php": ">=7.2",
8-
"cakephp/cakephp": "~4.2.0"
7+
"php": ">=8.1",
8+
"cakephp/cakephp": "^5.0.1",
9+
"cakephp/bake": "^3.1",
10+
"zircote/swagger-php": "^4.9"
911
},
1012
"require-dev": {
11-
"phpunit/phpunit": "^8.0"
13+
"phpunit/phpunit": "^10.1.0"
1214
},
1315
"autoload": {
1416
"psr-4": {
@@ -26,5 +28,10 @@
2628
],
2729
"scripts": {
2830
"build:swagger": "build-swagger-json"
31+
},
32+
"config": {
33+
"allow-plugins": {
34+
"cakephp/plugin-installer": true
35+
}
2936
}
3037
}

src/View/Helper/OpenApiDocBlockHelper.php

+164-29
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,6 @@ public function openApiClassDescription(
3333
$lines[] = '';
3434
}
3535

36-
$lines[] = "@OA\\Schema(\n * schema=\"{$className}\",\n * title=\"\",";
37-
$lines[] = " description=\"{$className} entity\",";
38-
foreach ($propertySchema as $name => $values) {
39-
$lines = array_merge($lines, $this->makeOpenAPIColumn($name, $values['type'], $values));
40-
}
41-
$lines[] = ')';
42-
4336
$previous = false;
4437
foreach ($annotations as $annotation) {
4538
if (strlen($annotation) > 1 && $annotation[0] === '@' && strpos($annotation, ' ') > 0) {
@@ -60,14 +53,117 @@ public function openApiClassDescription(
6053
return rtrim(" * {$line}");
6154
})->toArray(), [' */']);
6255

56+
$required = '';
57+
foreach ($propertySchema as $name => $values) {
58+
if ((array_key_exists('null', $values) && $values['null'] === true)) {
59+
continue;
60+
}
61+
62+
$required .= strlen($required) === 0 ? "'{$name}'" : ", '{$name}'";
63+
}
64+
65+
$lines[] = '#[OA\Schema(';
66+
$lines[] = " schema: '{$className}}',";
67+
$lines[] = " title: '{$className}',";
68+
$lines[] = " description: '{$className} Entity',";
69+
$lines[] = " required: [{$required}],";
70+
$lines[] = ' properties: [';
71+
foreach ($propertySchema as $name => $values) {
72+
$lines = array_merge($lines, $this->makeOpenAPIColumn($name, $values['type'], $values, 8));
73+
}
74+
$lines[] = ' ]';
75+
$lines[] = ')]';
76+
6377
return implode("\n", $lines);
6478
}
6579

66-
protected function makeOpenAPIColumn(string $name, string $type, array $column): array
80+
public function schemaProperty(array $propertySchema, $name): ?array {
81+
$format = null;
82+
$type = $propertySchema[$name]['type'];
83+
switch ($type) {
84+
case TableSchema::TYPE_CHAR:
85+
case TableSchema::TYPE_STRING:
86+
case TableSchema::TYPE_TEXT:
87+
$type = 'string';
88+
break;
89+
90+
case TableSchema::TYPE_DECIMAL:
91+
$type = 'string';
92+
$format = 'decimal';
93+
break;
94+
95+
case TableSchema::TYPE_UUID:
96+
$type = 'string';
97+
$format = 'uuid';
98+
break;
99+
100+
case TableSchema::TYPE_DATE:
101+
$type = 'string';
102+
$format = 'date';
103+
break;
104+
105+
case TableSchema::TYPE_TIMESTAMP:
106+
case TableSchema::TYPE_TIMESTAMP_FRACTIONAL:
107+
case TableSchema::TYPE_TIMESTAMP_TIMEZONE:
108+
case TableSchema::TYPE_DATETIME:
109+
$type = 'string';
110+
$format = 'datetime';
111+
break;
112+
113+
case TableSchema::TYPE_TIME:
114+
$type = 'string';
115+
$format = '"time';
116+
break;
117+
118+
case TableSchema::TYPE_INTEGER:
119+
$type = 'integer';
120+
$format = 'int32';
121+
break;
122+
case TableSchema::TYPE_BIGINTEGER:
123+
$type = 'integer';
124+
$format = 'bigint';
125+
break;
126+
127+
case TableSchema::TYPE_TINYINTEGER:
128+
case TableSchema::TYPE_SMALLINTEGER:
129+
$type = 'integer';
130+
$format = 'smallint';
131+
break;
132+
133+
case TableSchema::TYPE_FLOAT:
134+
$type = 'float';
135+
break;
136+
137+
case TableSchema::TYPE_JSON:
138+
$type = 'string';
139+
$format = 'json';
140+
break;
141+
case TableSchema::TYPE_BOOLEAN:
142+
$type = 'boolean';
143+
break;
144+
145+
default:
146+
if ($type[0] === '\\') {
147+
// exclude associated properties.
148+
return null;
149+
} else {
150+
$format = $type;
151+
$type = 'string';
152+
}
153+
break;
154+
}
155+
156+
return [
157+
'type' => $type,
158+
'format' => $format,
159+
];
160+
}
161+
162+
protected function makeOpenAPIColumn(string $name, string $type, array $column, int $indentNum = 12): array
67163
{
164+
$indentString = str_repeat(' ', $indentNum);
68165
$result = [];
69166
$format = null;
70-
$comment = null;
71167
switch ($type) {
72168
case TableSchema::TYPE_CHAR:
73169
case TableSchema::TYPE_STRING:
@@ -77,45 +173,45 @@ protected function makeOpenAPIColumn(string $name, string $type, array $column):
77173

78174
case TableSchema::TYPE_DECIMAL:
79175
$type = 'string';
80-
$format = ' format="decimal",';
176+
$format = 'decimal';
81177
break;
82178

83179
case TableSchema::TYPE_UUID:
84180
$type = 'string';
85-
$format = ' format="uuid",';
181+
$format = 'uuid';
86182
break;
87183

88184
case TableSchema::TYPE_DATE:
89185
$type = 'string';
90-
$format = ' format="date",';
186+
$format = 'date';
91187
break;
92188

93189
case TableSchema::TYPE_TIMESTAMP:
94190
case TableSchema::TYPE_TIMESTAMP_FRACTIONAL:
95191
case TableSchema::TYPE_TIMESTAMP_TIMEZONE:
96192
case TableSchema::TYPE_DATETIME:
97193
$type = 'string';
98-
$format = ' format="datetime",';
194+
$format = 'datetime';
99195
break;
100196

101197
case TableSchema::TYPE_TIME:
102198
$type = 'string';
103-
$format = ' format="time",';
199+
$format = '"time';
104200
break;
105201

106202
case TableSchema::TYPE_INTEGER:
107203
$type = 'integer';
108-
$format = ' format="int32",';
204+
$format = 'int32';
109205
break;
110206
case TableSchema::TYPE_BIGINTEGER:
111207
$type = 'integer';
112-
$format = ' format="bigint",';
208+
$format = 'bigint';
113209
break;
114210

115211
case TableSchema::TYPE_TINYINTEGER:
116212
case TableSchema::TYPE_SMALLINTEGER:
117213
$type = 'integer';
118-
$format = ' format="smallint",';
214+
$format = 'smallint';
119215
break;
120216

121217
case TableSchema::TYPE_FLOAT:
@@ -124,7 +220,7 @@ protected function makeOpenAPIColumn(string $name, string $type, array $column):
124220

125221
case TableSchema::TYPE_JSON:
126222
$type = 'string';
127-
$format = ' format="json",';
223+
$format = 'json';
128224
break;
129225
case TableSchema::TYPE_BOOLEAN:
130226
$type = 'boolean';
@@ -135,24 +231,24 @@ protected function makeOpenAPIColumn(string $name, string $type, array $column):
135231
// exclude associated properties.
136232
return $result;
137233
} else {
138-
$format = " format=\"{$type}\",";
234+
$format = $type;
139235
$type = 'string';
140236
}
141237
break;
142238
}
143239

144-
if (is_null($comment) && !empty($column['comment'])) {
145-
$comment = str_replace("\n", ' ', $column['comment']);
146-
}
240+
$comment = !empty($column['comment'])
241+
? str_replace("\n", ' ', $column['comment'])
242+
: '';
147243

148-
$result[] = ' @OA\Property(';
149-
$result[] = " property=\"{$name}\",";
150-
$result[] = " type=\"{$type}\",";
244+
$result[] = "{$indentString}new OA\Property(";
245+
$result[] = "{$indentString} property: '{$name}',";
246+
$result[] = "{$indentString} type: '{$type}',";
151247
if (!empty($format)) {
152-
$result[] = $format;
248+
$result[] = "{$indentString} format: '{$format}',";
153249
}
154-
$result[] = " description=\"{$comment}\",";
155-
$result[] = ' ),';
250+
$result[] = "{$indentString} description: '{$comment}',";
251+
$result[] = "{$indentString}),";
156252

157253
return $result;
158254
}
@@ -162,6 +258,45 @@ public function openApiActionBody(
162258
): string {
163259
$lines = [];
164260

261+
$exclude = ['id', 'created', 'modified'];
262+
263+
$lines[] = ' requestBody: new OA\RequestBody(';
264+
$lines[] = ' required: true,';
265+
$lines[] = ' content: new OA\JsonContent(';
266+
$required = '';
267+
foreach ($propertySchema as $name => $values) {
268+
if (in_array($name, $exclude) || (array_key_exists('null', $values) && $values['null'] === true)) {
269+
continue;
270+
}
271+
272+
$required .= strlen($required) === 0 ? "'{$name}'" : ", '{$name}'";
273+
}
274+
$lines[] = " required: [{$required}],";
275+
276+
$lines[] = ' properties: [';
277+
278+
foreach ($propertySchema as $name => $values) {
279+
if (in_array($name, $exclude)) {
280+
continue;
281+
}
282+
283+
$lines = array_merge($lines, (new Collection($this->makeOpenAPIColumn($name, $values['type'], $values)))->map(function ($line) {
284+
return rtrim($line);
285+
})->toArray());
286+
}
287+
288+
$lines[] = ' ]';
289+
$lines[] = ' )';
290+
$lines[] = ' ),';
291+
292+
return implode("\n", $lines);
293+
}
294+
295+
public function openApiActionBodyDocComment(
296+
array $propertySchema
297+
): string {
298+
$lines = [];
299+
165300
$lines[] = ' * @OA\RequestBody(';
166301
$lines[] = ' * required=true,';
167302
$lines[] = ' * @OA\JsonContent(';
@@ -173,7 +308,7 @@ public function openApiActionBody(
173308
}
174309

175310
$lines = array_merge($lines, (new Collection($this->makeOpenAPIColumn($name, $values['type'], $values)))->map(function ($line) {
176-
return rtrim(" * {$line}");
311+
return rtrim($line);
177312
})->toArray());
178313
}
179314

templates/bake/Controller/controller.twig

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ use {{ baseNamespace }}\Controller\AppController;
2727
{% endif %}
2828
use Cake\Event\Event;
2929
use Cake\Http\Exception\MethodNotAllowedException;
30+
use OpenApi\Attributes as OA;
3031
3132
/**
3233
* {{ name }} Controller

templates/bake/Model/entity.twig

+3-2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ declare(strict_types=1);
2929
namespace {{ namespace }}\Model\Entity;
3030
3131
use Cake\ORM\Entity;
32+
use OpenApi\Attributes as OA;
3233
3334
{{ OpenApiDocBlock.openApiClassDescription(name, 'Entity', annotations, propertySchema)|raw }}
3435
class {{ name }} extends Entity
@@ -43,7 +44,7 @@ class {{ name }} extends Entity
4344
*
4445
* @var array<string, bool>
4546
*/
46-
protected $_accessible = {{ Bake.exportVar(accessible, 1)|raw }};
47+
protected array $_accessible = {{ Bake.exportVar(accessible, 1)|raw }};
4748
{% endif %}
4849
{% if accessible and hidden %}
4950
@@ -54,6 +55,6 @@ class {{ name }} extends Entity
5455
*
5556
* @var array
5657
*/
57-
protected $_hidden = [{{ Bake.stringifyList(hidden)|raw }}];
58+
protected array $_hidden = [{{ Bake.stringifyList(hidden)|raw }}];
5859
{% endif %}
5960
}

0 commit comments

Comments
 (0)