-
Notifications
You must be signed in to change notification settings - Fork 15
Expand file tree
/
Copy pathSchemaToClass.php
More file actions
128 lines (100 loc) · 4.3 KB
/
Copy pathSchemaToClass.php
File metadata and controls
128 lines (100 loc) · 4.3 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
<?php
declare(strict_types=1);
namespace Helmich\Schema2Class\Generator;
use Helmich\Schema2Class\Codegen\PropertyGenerator;
use Helmich\Schema2Class\Generator\Property\IntersectProperty;
use Helmich\Schema2Class\Generator\Property\NestedObjectProperty;
use Helmich\Schema2Class\Generator\Property\PropertyCollection;
use Helmich\Schema2Class\Writer\WriterInterface;
use Laminas\Code\DeclareStatement;
use Laminas\Code\Generator\ClassGenerator;
use Laminas\Code\Generator\DocBlock\Tag\GenericTag;
use Laminas\Code\Generator\DocBlockGenerator;
use Laminas\Code\Generator\FileGenerator;
use Symfony\Component\Console\Output\OutputInterface;
class SchemaToClass
{
private WriterInterface $writer;
private SchemaToEnum $enumGenerator;
public function __construct(WriterInterface $writer, OutputInterface $output)
{
$this->writer = $writer;
$this->enumGenerator = new SchemaToEnum($writer);
}
/**
* @param GeneratorRequest $req
* @throws GeneratorException
*/
public function schemaToClass(GeneratorRequest $req): void
{
$schema = $req->getSchema();
if (isset($schema["enum"])) {
$this->enumGenerator->schemaToEnum($req);
return;
}
if (IntersectProperty::canHandleSchema($schema)) {
$schema = (new IntersectProperty($req->getTargetClass(), $schema, $req))->buildSchemaIntersect();
}
if (!NestedObjectProperty::canHandleSchema($schema)) {
throw new GeneratorException("cannot generate class for types other than 'object'");
}
$schemaProperty = new PropertyGenerator("schema", $schema, PropertyGenerator::FLAG_PRIVATE | PropertyGenerator::FLAG_STATIC);
$schemaProperty->setDocBlock(new DocBlockGenerator(
"Schema used to validate input for creating instances of this class",
null,
[new GenericTag("var", "array")]
));
if ($req->isAtLeastPHP("7.4")) {
$schemaProperty->setTypeHint("array");
}
$properties = [$schemaProperty];
$propertiesFromSchema = new PropertyCollection();
if (isset($schema["properties"])) {
foreach ($schema["properties"] as $key => $definition) {
$isRequired = isset($schema["required"]) && in_array($key, $schema["required"]);
$property = PropertyBuilder::buildPropertyFromSchema($req, $key, $definition, $isRequired);
$propertiesFromSchema->add($property);
}
}
foreach ($propertiesFromSchema as $property) {
$property->generateSubTypes($this);
}
$codeGenerator = new Generator($req);
$properties = [
...$properties,
...$codeGenerator->generateProperties($propertiesFromSchema),
];
$methods = [
$codeGenerator->generateConstructor($propertiesFromSchema),
...$codeGenerator->generateGetterMethods($propertiesFromSchema),
...$codeGenerator->generateSetterMethods($propertiesFromSchema),
$codeGenerator->generateBuildMethod($propertiesFromSchema),
$codeGenerator->generateToJSONMethod($propertiesFromSchema),
$codeGenerator->generateValidateMethod(),
$codeGenerator->generateCloneMethod($propertiesFromSchema),
];
$cls = new ClassGenerator(
$req->getTargetClass(),
$req->getTargetNamespace(),
null,
null,
[],
$properties,
$methods,
null
);
$req->onClassCreated($cls);
$filename = $req->getTargetDirectory() . '/' . $req->getTargetClass() . '.php';
$file = new FileGenerator();
$file->setClasses([$cls]);
$req->onFileCreated($filename, $file);
if ($req->isAtLeastPHP("7.0") && !$req->getOptions()->getDisableStrictTypes()) {
$file->setDeclares([DeclareStatement::strictTypes(1)]);
}
$content = $file->generate();
// Do some corrections because the Zend code generation library is stupid.
$content = preg_replace('/ : \\\\self/', ' : self', $content);
$content = preg_replace('/\\\\' . preg_quote($req->getTargetNamespace()) . '\\\\/', '', $content);
$this->writer->writeFile($filename, $content);
}
}