diff --git a/src/Node/BaseNode.php b/src/Node/BaseNode.php index b88571a..d9f43ae 100644 --- a/src/Node/BaseNode.php +++ b/src/Node/BaseNode.php @@ -33,6 +33,11 @@ class BaseNode */ protected $type = 'array'; + /** + * @var string + */ + protected $typeAlias = 'array'; + /** * @var bool */ @@ -88,6 +93,16 @@ public function setType(string $type) $this->type = $type; } + public function setTypeAlias(string $typeAlias) + { + $this->typeAlias = $typeAlias; + } + + public function getTypeAlias(): string + { + return $this->typeAlias; + } + public function setRequired(bool $required) { $this->required = $required; diff --git a/src/SchemaBuilder.php b/src/SchemaBuilder.php new file mode 100644 index 0000000..c2db376 --- /dev/null +++ b/src/SchemaBuilder.php @@ -0,0 +1,34 @@ +define(); + $schema = $this->walk($inputHandler->getRoot()); + + return $schema; + } + + protected function walk(BaseNode $node): array + { + if (!$node->hasChildren()) { + return []; + } + + foreach ($node->getChildren() as $field => $childNode) { + $schema[$field]['type'] = $childNode->getTypeAlias(); + $schema[$field]['required'] = $childNode->isRequired(); + $schema[$field]['default'] = $childNode->getDefault(); + $schema[$field]['nullable'] = $childNode->allowNull(); + $schema[$field]['children'] = $this->walk($childNode); + } + + return $schema; + } +} diff --git a/src/TypeHandler.php b/src/TypeHandler.php index 3d7754e..ef9bb8c 100644 --- a/src/TypeHandler.php +++ b/src/TypeHandler.php @@ -54,6 +54,7 @@ public function getType(string $name): BaseNode { if (isset($this->types[$name])) { $type = new $this->types[$name](); + $type->setTypeAlias($name); $type->setTypeHandler($this); return $type; @@ -62,6 +63,7 @@ public function getType(string $name): BaseNode if ($this->isScalarCollectionType($name)) { $type = new ScalarCollectionNode(); $type->setType($this->getCollectionType($name)); + $type->setTypeAlias($name); $type->setTypeHandler($this); return $type; @@ -70,6 +72,7 @@ public function getType(string $name): BaseNode if ($this->isClassType($name)) { $type = new ObjectNode(); $type->setType($name); + $type->setTypeAlias('object'); $type->setTypeHandler($this); $type->setInstantiator($this->defaultInstantiator); @@ -79,6 +82,7 @@ public function getType(string $name): BaseNode if ($this->isCollectionType($name)) { $type = new CollectionNode(); $type->setType($this->getCollectionType($name)); + $type->setTypeAlias('object[]'); $type->setTypeHandler($this); $type->setInstantiator($this->defaultInstantiator); diff --git a/tests/SchemaBuilderTest.php b/tests/SchemaBuilderTest.php new file mode 100644 index 0000000..dcbeaf5 --- /dev/null +++ b/tests/SchemaBuilderTest.php @@ -0,0 +1,151 @@ +add('title', 'string'); + $this->add('size', 'int'); + $this->add('dimensions', 'int[]'); + $this->add('date', 'datetime'); + $this->add('metadata', 'array'); + + $simple = $this->add('simple', 'array'); + $simple->add('title', 'string', ['default' => 'Barfoo']); + $simple->add('size', 'int', ['required' => false, 'default' => 15]); + $simple->add('date', 'datetime'); + + $author = $this->add('author', 'Linio\Component\Input\TestUser'); + $author->add('name', 'string'); + $author->add('age', 'int'); + $author->add('is_active', 'bool', ['required' => false]); + + $authors = $this->add('authors', 'Linio\Component\Input\TestUser[]'); + $authors->add('name', 'string'); + } +} + +class SchemaBuilderTest extends \PHPUnit_Framework_TestCase +{ + public function testIsBuildingSchema() + { + $expectedSchema = [ + 'title' => [ + 'type' => 'string', + 'required' => true, + 'default' => null, + 'nullable' => false, + 'children' => [], + ], + 'size' => [ + 'type' => 'int', + 'required' => true, + 'default' => null, + 'nullable' => false, + 'children' => [], + ], + 'dimensions' => [ + 'type' => 'int[]', + 'required' => true, + 'default' => null, + 'nullable' => false, + 'children' => [], + ], + 'date' => [ + 'type' => 'datetime', + 'required' => true, + 'default' => null, + 'nullable' => false, + 'children' => [], + ], + 'metadata' => [ + 'type' => 'array', + 'required' => true, + 'default' => null, + 'nullable' => false, + 'children' => [], + ], + 'simple' => [ + 'type' => 'array', + 'required' => true, + 'default' => null, + 'nullable' => false, + 'children' => [ + 'title' => [ + 'type' => 'string', + 'required' => false, + 'default' => 'Barfoo', + 'nullable' => false, + 'children' => [], + ], + 'size' => [ + 'type' => 'int', + 'required' => false, + 'default' => 15, + 'nullable' => false, + 'children' => [], + ], + 'date' => [ + 'type' => 'datetime', + 'required' => true, + 'default' => null, + 'nullable' => false, + 'children' => [], + ], + ], + ], + 'author' => [ + 'type' => 'object', + 'required' => true, + 'default' => null, + 'nullable' => false, + 'children' => [ + 'name' => [ + 'type' => 'string', + 'required' => true, + 'default' => null, + 'nullable' => false, + 'children' => [], + ], + 'age' => [ + 'type' => 'int', + 'required' => true, + 'default' => null, + 'nullable' => false, + 'children' => [], + ], + 'is_active' => [ + 'type' => 'bool', + 'required' => false, + 'default' => null, + 'nullable' => false, + 'children' => [], + ], + ], + ], + 'authors' => [ + 'type' => 'object[]', + 'required' => true, + 'default' => null, + 'nullable' => false, + 'children' => [ + 'name' => [ + 'type' => 'string', + 'required' => true, + 'default' => null, + 'nullable' => false, + 'children' => [], + ], + ], + ], + ]; + + $schemaBuilder = new SchemaBuilder(); + $schema = $schemaBuilder->build(new SchemaTestInputHandler()); + + $this->assertEquals($expectedSchema, $schema); + } +}