-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathGenPhp.php
126 lines (107 loc) · 4.41 KB
/
GenPhp.php
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
<?php
namespace Swaggest\JsonCli;
use Swaggest\JsonCli\GenPhp\BuilderOptions;
use Swaggest\JsonSchema\Schema;
use Swaggest\PhpCodeBuilder\App\PhpApp;
use Swaggest\PhpCodeBuilder\JsonSchema\ClassHookCallback;
use Swaggest\PhpCodeBuilder\JsonSchema\PhpBuilder;
use Swaggest\PhpCodeBuilder\PhpClass;
use Swaggest\PhpCodeBuilder\PhpCode;
use Yaoi\Command;
class GenPhp extends Base
{
use BuilderOptions;
/** @var string */
public $ns;
/** @var string */
public $nsPath;
/** @var string */
public $rootName = 'Structure';
/**
* @param Command\Definition $definition
* @param \stdClass|static $options
*/
public static function setUpDefinition(Command\Definition $definition, $options)
{
$definition->description = 'Generate PHP code from JSON schema';
Base::setupGenOptions($definition, $options);
$options->ns = Command\Option::create()
->setDescription('Namespace to use for generated classes, example \MyClasses')->setType()->setIsRequired();
$options->nsPath = Command\Option::create()
->setDescription('Path to store generated classes, example ./src/MyClasses')
->setType()
->setIsRequired();
$options->rootName = Command\Option::create()->setType()
->setDescription('Root class name, default "Structure", only used for # pointer');
static::setupBuilderOptions($options);
Base::setupGenOptions($definition, $options);
}
public function performAction()
{
try {
$skipRoot = false;
$baseName = null;
$schema = $this->loadSchema($skipRoot, $baseName);
$appPath = realpath($this->nsPath);
if (!$appPath) {
$this->response->error('Could not find directory ' . $this->nsPath);
throw new ExitCode('', 1);
}
$appNs = $this->ns;
$app = new PhpApp();
$app->setNamespaceRoot($appNs, '.');
$builder = new PhpBuilder();
$this->setupBuilder($builder);
$builder->classCreatedHook = new ClassHookCallback(function (PhpClass $class, $path, $schema)
use ($app, $appNs, $skipRoot, $baseName) {
if ($skipRoot && '#' === $path) {
return;
}
$desc = '';
if ($schema->title) {
$desc = $schema->title;
}
if ($schema->description) {
$desc .= "\n" . $schema->description;
}
if ($fromRefs = $schema->getFromRefs()) {
$desc .= "\nBuilt from " . implode("\n" . ' <- ', $fromRefs);
}
$class->setDescription(trim($desc));
$class->setNamespace($appNs);
if ('#' === $path) {
$class->setName($this->rootName);
} else {
if (!empty($fromRefs)) {
$path = $fromRefs[0];
}
foreach ($this->defPtr as $defPtr) {
if (isset($baseName)) {
$baseNameDefPtr = $baseName . $defPtr;
if ($baseNameDefPtr === substr($path, 0, strlen($baseNameDefPtr))) {
$path = substr($path, strlen($baseNameDefPtr));
$className = PhpCode::makePhpClassName($path);
$class->setName($className);
}
}
if ($defPtr === substr($path, 0, strlen($defPtr))) {
$className = PhpCode::makePhpClassName(substr($path, strlen($defPtr)));
$class->setName($className);
}
}
}
$app->addClass($class);
});
if (!$schema instanceof Schema) {
$this->response->error('failed to assert Schema type, ' . get_class($schema) . ' received');
throw new ExitCode('', 1);
}
$builder->getType($schema);
$app->store($appPath);
$this->response->success("Classes are generated in " . $appPath);
} catch (\Exception $e) {
$this->response->error($e->getMessage());
throw new ExitCode('', 1);
}
}
}