diff --git a/composer.json b/composer.json
index ac54af7..05d1d04 100644
--- a/composer.json
+++ b/composer.json
@@ -18,11 +18,11 @@
],
"license": "MIT",
"require": {
- "php": ">=7.2|^8.0",
- "symfony/console": "^2.7|^3.0|^4.0|^5.0|^6.0",
- "symfony/dependency-injection": "^2.2|^3.0|^4.0|^5.0|^6.0",
- "symfony/yaml": "^2.2|^3.0|^4.0|^5.0|^6.0",
- "symfony/config": "^2.2|^3.0|^4.0|^5.0|^6.0",
+ "php": "^8.0",
+ "symfony/console": "^4.0|^5.0|^6.0",
+ "symfony/dependency-injection": "^4.0|^5.0|^6.0",
+ "symfony/yaml": "^4.0|^5.0|^6.0",
+ "symfony/config": "^4.0|^5.0|^6.0",
"goetas-webservices/xsd-reader": "^0.3.7 | ^0.4.1",
"doctrine/inflector": "^2.0",
"laminas/laminas-code": "^3.3.2|^4.0",
@@ -47,7 +47,7 @@
},
"extra": {
"branch-alias": {
- "dev-master": "0.4-dev"
+ "dev-master": "1.x-dev"
}
},
"bin": [
diff --git a/src/Php/ClassGenerator.php b/src/Php/ClassGenerator.php
index 1c80ccd..63cfc8c 100644
--- a/src/Php/ClassGenerator.php
+++ b/src/Php/ClassGenerator.php
@@ -14,16 +14,10 @@
use Laminas\Code\Generator\MethodGenerator;
use Laminas\Code\Generator\ParameterGenerator;
use Laminas\Code\Generator\PropertyGenerator;
+use Laminas\Code\Generator\PropertyValueGenerator;
class ClassGenerator
{
- private $strictTypes;
-
- public function __construct(bool $strictTypes = false)
- {
- $this->strictTypes = $strictTypes;
- }
-
private function handleBody(Generator\ClassGenerator $class, PHPClass $type)
{
foreach ($type->getProperties() as $prop) {
@@ -48,43 +42,60 @@ private function handleValueMethod(Generator\ClassGenerator $generator, PHPPrope
{
$type = $prop->getType();
- $docblock = new DocBlockGenerator('Construct');
+ $docblock = new DocBlockGenerator();
$docblock->setWordWrap(false);
$paramTag = new ParamTag('value');
$paramTag->setTypes(($type ? $type->getPhpType() : 'mixed'));
- $docblock->setTag($paramTag);
-
$param = new ParameterGenerator('value');
- if ($type && !$type->isNativeType()) {
- $param->setType($type->getPhpType());
+ $param->setDefaultValue(null);
+ if ($type) {
+ $param->setType($this->getTypeAsPhpString($type));
+ } else {
+ $docblock->setTag($paramTag);
}
$method = new MethodGenerator('__construct', [
$param,
]);
- $method->setDocBlock($docblock);
+ if ($docblock->getTags()) {
+ $method->setDocBlock($docblock);
+ }
$method->setBody('$this->value($value);');
$generator->addMethodFromGenerator($method);
$docblock = new DocBlockGenerator('Gets or sets the inner value');
$docblock->setWordWrap(false);
+
+ $parameter = new ParameterGenerator('value');
+ $parameter->setVariadic(true);
+
$paramTag = new ParamTag('value');
+ $paramTag->setDescription('if provided, allows to set the inner value');
if ($type && $type instanceof PHPClassOf) {
$paramTag->setTypes($type->getArg()->getType()->getPhpType() . '[]');
+ $parameter->setType('?array');
} elseif ($type) {
$paramTag->setTypes($prop->getType()->getPhpType());
+ $parameter->setType($this->getTypeAsPhpString($prop->getType()));
+ } else {
+ $docblock->setTag($paramTag);
}
- $docblock->setTag($paramTag);
+
+ $method = new MethodGenerator('value', [$parameter]);
$returnTag = new ReturnTag('mixed');
if ($type && $type instanceof PHPClassOf) {
$returnTag->setTypes($type->getArg()->getType()->getPhpType() . '[]');
+ $method->setReturnType('?array');
+ $docblock->setTag($returnTag);
} elseif ($type) {
- $returnTag->setTypes($type->getPhpType());
+ $method->setReturnType($this->getTypeAsPhpString($type));
+ } else {
+ $docblock->setTag($returnTag);
}
- $docblock->setTag($returnTag);
+
$param = new ParameterGenerator('value');
$param->setDefaultValue(null);
@@ -92,21 +103,21 @@ private function handleValueMethod(Generator\ClassGenerator $generator, PHPPrope
if ($type && !$type->isNativeType()) {
$param->setType($type->getPhpType());
}
- $method = new MethodGenerator('value', []);
+
$method->setDocBlock($docblock);
- $methodBody = 'if ($args = func_get_args()) {' . PHP_EOL;
- $methodBody .= ' $this->' . $prop->getName() . ' = $args[0];' . PHP_EOL;
+ $methodBody = 'if ($value) {' . PHP_EOL;
+ $methodBody .= ' $this->' . $prop->getName() . ' = $value[0];' . PHP_EOL;
$methodBody .= '}' . PHP_EOL;
$methodBody .= 'return $this->' . $prop->getName() . ';' . PHP_EOL;
$method->setBody($methodBody);
$generator->addMethodFromGenerator($method);
- $docblock = new DocBlockGenerator('Gets a string value');
+ $docblock = new DocBlockGenerator('Gets the inner value as string');
$docblock->setWordWrap(false);
- $docblock->setTag(new ReturnTag('string'));
$method = new MethodGenerator('__toString');
+ $method->setReturnType('string');
$method->setDocBlock($docblock);
$method->setBody('return strval($this->' . $prop->getName() . ');');
$generator->addMethodFromGenerator($method);
@@ -125,10 +136,7 @@ private function handleSetter(Generator\ClassGenerator $generator, PHPProperty $
}
$patramTag = new ParamTag($prop->getName());
- $docblock->setTag($patramTag);
- $return = new ReturnTag('self');
- $docblock->setTag($return);
$type = $prop->getType();
@@ -138,9 +146,16 @@ private function handleSetter(Generator\ClassGenerator $generator, PHPProperty $
$parameter = new ParameterGenerator($prop->getName());
if ($type && $type instanceof PHPClassOf) {
+ $docblock->setTag($patramTag);
$patramTag->setTypes($type->getArg()
->getType()->getPhpType() . '[]');
- $parameter->setType('array');
+
+ if ($type->getArg()->getDefault() === []) {
+ $parameter->setType('array');
+ } else {
+ $parameter->setType('?array');
+ }
+
if ($p = $type->getArg()->getType()->isSimpleType()
) {
@@ -150,32 +165,20 @@ private function handleSetter(Generator\ClassGenerator $generator, PHPProperty $
}
} elseif ($type) {
if ($type->isNativeType()) {
- $patramTag->setTypes($type->getPhpType());
- if ($this->strictTypes) {
- $parameter->setType($type->getPhpType());
- }
+ $parameter->setType($this->getTypeAsPhpString($type));
} elseif ($p = $type->isSimpleType()) {
if (($t = $p->getType()) && !$t->isNativeType()) {
- $patramTag->setTypes($t->getPhpType());
$parameter->setType($t->getPhpType());
} elseif ($t) {
- $patramTag->setTypes($t->getPhpType());
- if ($this->strictTypes) {
- $parameter->setType($t->getPhpType());
- }
+ $parameter->setType($this->getTypeAsPhpString($t));
}
} else {
- $patramTag->setTypes($type->getPhpType());
$parameter->setType(($prop->getNullable() ? '?' : '') . $type->getPhpType());
}
- }
- if ($this->strictTypes && $prop->getDefault() === null) {
- $parameter->setDefaultValue(null);
- }
-
- if ($prop->getNullable() && $parameter->getType()) {
- $parameter->setDefaultValue(null);
+ if ($prop->getNullable() && $parameter->getType()) {
+ $parameter->setDefaultValue(null);
+ }
}
$methodBody .= '$this->' . $prop->getName() . ' = $' . $prop->getName() . ';' . PHP_EOL;
@@ -184,6 +187,10 @@ private function handleSetter(Generator\ClassGenerator $generator, PHPProperty $
$method->setDocBlock($docblock);
$method->setParameter($parameter);
+ if ($prop->getDefault() === null) {
+ $method->setReturnType('static');
+ }
+
$generator->addMethodFromGenerator($method);
}
@@ -199,17 +206,14 @@ private function handleGetter(Generator\ClassGenerator $generator, PHPProperty $
$docblock->setLongDescription($prop->getDoc());
}
- $patramTag = new ParamTag('index', 'int|string');
- $docblock->setTag($patramTag);
-
- $docblock->setTag(new ReturnTag('bool'));
-
$paramIndex = new ParameterGenerator('index');
+ $paramIndex->setType('int|string');
$method = new MethodGenerator('isset' . $inflector->classify($prop->getName()), [$paramIndex]);
$method->setDocBlock($docblock);
$method->setBody('return isset($this->' . $prop->getName() . '[$index]);');
+ $method->setReturnType('bool');
$generator->addMethodFromGenerator($method);
$docblock = new DocBlockGenerator();
@@ -219,15 +223,13 @@ private function handleGetter(Generator\ClassGenerator $generator, PHPProperty $
$docblock->setLongDescription($prop->getDoc());
}
- $patramTag = new ParamTag('index', 'int|string');
- $docblock->setTag($patramTag);
$paramIndex = new ParameterGenerator('index');
-
- $docblock->setTag(new ReturnTag('void'));
+ $paramIndex->setType('int|string');
$method = new MethodGenerator('unset' . $inflector->classify($prop->getName()), [$paramIndex]);
$method->setDocBlock($docblock);
$method->setBody('unset($this->' . $prop->getName() . '[$index]);');
+ $method->setReturnType('void');
$generator->addMethodFromGenerator($method);
}
// ////
@@ -235,38 +237,39 @@ private function handleGetter(Generator\ClassGenerator $generator, PHPProperty $
$docblock = new DocBlockGenerator();
$docblock->setWordWrap(false);
- $docblock->setShortDescription('Gets as ' . $prop->getName());
+ $docblock->setShortDescription('Get the ' . $prop->getName());
if ($prop->getDoc()) {
$docblock->setLongDescription($prop->getDoc());
}
+ $method = new MethodGenerator('get' . $inflector->classify($prop->getName()));
+ $method->setDocBlock($docblock);
+ $method->setBody('return $this->' . $prop->getName() . ';');
+
$tag = new ReturnTag('mixed');
$type = $prop->getType();
if ($type && $type instanceof PHPClassOf) {
$tt = $type->getArg()->getType();
$tag->setTypes($tt->getPhpType() . '[]');
- if ($p = $tt->isSimpleType()) {
- if (($t = $p->getType())) {
- $tag->setTypes($t->getPhpType() . '[]');
- }
+ $docblock->setTag($tag);
+
+
+ if ($type->getArg()->getDefault() === []) {
+ $method->setReturnType('array');
+ } else {
+ $method->setReturnType('?array');
}
} elseif ($type) {
if ($p = $type->isSimpleType()) {
if ($t = $p->getType()) {
- $tag->setTypes($t->getPhpType());
+ $method->setReturnType($this->getTypeAsPhpString($t));
}
} else {
- $tag->setTypes($type->getPhpType());
+ $method->setReturnType($this->getTypeAsPhpString($type));
}
}
- $docblock->setTag($tag);
-
- $method = new MethodGenerator('get' . $inflector->classify($prop->getName()));
- $method->setDocBlock($docblock);
- $method->setBody('return $this->' . $prop->getName() . ';');
-
$generator->addMethodFromGenerator($method);
}
@@ -283,15 +286,12 @@ private function handleAdder(Generator\ClassGenerator $generator, PHPProperty $p
$docblock->setLongDescription($prop->getDoc());
}
- $return = new ReturnTag();
- $return->setTypes('self');
- $docblock->setTag($return);
-
$patramTag = new ParamTag($propName, $type->getArg()->getType()->getPhpType());
$docblock->setTag($patramTag);
$inflector = InflectorFactory::create()->build();
$method = new MethodGenerator('addTo' . $inflector->classify($prop->getName()));
+ $method->setReturnType('static');
$parameter = new ParameterGenerator($propName);
$tt = $type->getArg()->getType();
@@ -336,22 +336,23 @@ private function handleProperty(Generator\ClassGenerator $class, PHPProperty $pr
$class->addPropertyFromGenerator($generatedProp);
- if ($prop->getType() && (!$prop->getType()->getNamespace() && $prop->getType()->getName() == 'array')) {
- // $generatedProp->setDefaultValue(array(), PropertyValueGenerator::TYPE_AUTO, PropertyValueGenerator::OUTPUT_SINGLE_LINE);
- }
-
$docBlock = new DocBlockGenerator();
$docBlock->setWordWrap(false);
- $generatedProp->setDocBlock($docBlock);
- if ($prop->getDoc()) {
- $docBlock->setLongDescription($prop->getDoc());
- }
$tag = new VarTag($prop->getName(), 'mixed');
$type = $prop->getType();
if ($type && $type instanceof PHPClassOf) {
+
+ if ($type->getArg()->getDefault() === []) {
+ $generatedProp->setType(Generator\TypeGenerator::fromTypeString('array'));
+ $generatedProp->setDefaultValue($type->getArg()->getDefault(), PropertyValueGenerator::TYPE_ARRAY, PropertyValueGenerator::OUTPUT_SINGLE_LINE);
+ } else {
+ $generatedProp->setType(Generator\TypeGenerator::fromTypeString('?array'));
+ $generatedProp->setDefaultValue($type->getArg()->getDefault());
+ }
+
$tt = $type->getArg()->getType();
$tag->setTypes($tt->getPhpType() . '[]');
if ($p = $tt->isSimpleType()) {
@@ -359,17 +360,28 @@ private function handleProperty(Generator\ClassGenerator $class, PHPProperty $pr
$tag->setTypes($t->getPhpType() . '[]');
}
}
- $generatedProp->setDefaultValue($type->getArg()->getDefault());
+
+ $docBlock->setTag($tag);
} elseif ($type) {
if ($type->isNativeType()) {
- $tag->setTypes($type->getPhpType());
+ $generatedProp->setType(Generator\TypeGenerator::fromTypeString($this->getTypeAsPhpString($type)));
} elseif (($p = $type->isSimpleType()) && ($t = $p->getType())) {
- $tag->setTypes($t->getPhpType());
+ $generatedProp->setType(Generator\TypeGenerator::fromTypeString($this->getTypeAsPhpString($t)));
} else {
- $tag->setTypes($prop->getType()->getPhpType());
+ $generatedProp->setType(Generator\TypeGenerator::fromTypeString($this->getTypeAsPhpString($prop->getType())));
}
+ } else {
+ $docBlock->setTag($tag);
}
- $docBlock->setTag($tag);
+
+ if ($prop->getDoc()) {
+ $docBlock->setLongDescription($prop->getDoc());
+ }
+
+ if ($prop->getDoc() || $docBlock->getTags()) {
+ $generatedProp->setDocBlock($docBlock);
+ }
+
}
public function generate(PHPClass $type)
@@ -406,4 +418,9 @@ public function generate(PHPClass $type)
return $class;
}
}
+
+ private function getTypeAsPhpString(PHPClass $type): string
+ {
+ return ($type->getPhpType() === 'mixed' ? '' : '?') . $type->getPhpType();
+ }
}
diff --git a/src/Php/PhpConverter.php b/src/Php/PhpConverter.php
index 1d48fe7..79829b5 100644
--- a/src/Php/PhpConverter.php
+++ b/src/Php/PhpConverter.php
@@ -6,6 +6,7 @@
use GoetasWebservices\XML\XSDReader\Schema\Attribute\AttributeItem;
use GoetasWebservices\XML\XSDReader\Schema\Attribute\Group as AttributeGroup;
use GoetasWebservices\XML\XSDReader\Schema\Element\Element;
+use GoetasWebservices\XML\XSDReader\Schema\Element\ElementContainer;
use GoetasWebservices\XML\XSDReader\Schema\Element\ElementDef;
use GoetasWebservices\XML\XSDReader\Schema\Element\ElementItem;
use GoetasWebservices\XML\XSDReader\Schema\Element\ElementRef;
@@ -119,33 +120,6 @@ private function visitTypeBase(PHPClass $class, Type $type)
}
}
- /**
- * Process xsd:complexType xsd:choice xsd:element
- *
- * @param PHPClass $class
- * @param Schema $schema
- * @param Choice $choice
- */
- private function visitChoice(PHPClass $class, Schema $schema, Choice $choice)
- {
- foreach ($choice->getElements() as $choiceOption) {
- $property = $this->visitElement($class, $schema, $choiceOption);
- $class->addProperty($property);
- }
- }
-
- private function visitGroup(PHPClass $class, Schema $schema, Group $group)
- {
- foreach ($group->getElements() as $childGroup) {
- if ($childGroup instanceof Group) {
- $this->visitGroup($class, $schema, $childGroup);
- } else {
- $property = $this->visitElement($class, $schema, $childGroup);
- $class->addProperty($property);
- }
- }
- }
-
private function visitAttributeGroup(PHPClass $class, Schema $schema, AttributeGroup $att)
{
foreach ($att->getAttributes() as $childAttr) {
@@ -319,18 +293,27 @@ private function visitTypeAnonymous(Type $type, $name, PHPClass $parentClass)
private function visitComplexType(PHPClass $class, ComplexType $type)
{
$schema = $type->getSchema();
- foreach ($type->getElements() as $element) {
- if ($element instanceof Choice) {
- $this->visitChoice($class, $schema, $element);
- } elseif ($element instanceof Group) {
- $this->visitGroup($class, $schema, $element);
+ foreach ($this->flattElements($type) as $element) {
+ $property = $this->visitElement($class, $schema, $element);
+ $class->addProperty($property);
+ }
+ }
+
+ private function flattElements(ElementContainer $container)
+ {
+ $items = [];
+ foreach ($container->getElements() as $attr) {
+ if ($attr instanceof ElementContainer) {
+ $items = array_merge($items, $this->flattElements($attr));
} else {
- $property = $this->visitElement($class, $schema, $element);
- $class->addProperty($property);
+ $items[] = $attr;
}
}
+
+ return $items;
}
+
private function visitSimpleType(PHPClass $class, SimpleType $type)
{
if ($restriction = $type->getRestriction()) {
diff --git a/tests/Converter/Validator/Xsd2ValidatorTest.php b/tests/Converter/Validator/Xsd2ValidatorTest.php
index bdf5e04..97a44be 100644
--- a/tests/Converter/Validator/Xsd2ValidatorTest.php
+++ b/tests/Converter/Validator/Xsd2ValidatorTest.php
@@ -136,17 +136,6 @@ public function getRestrictionsValidations()
],
],
],
- [
- '',
- [
- [
- 'Regex' => [
- 'pattern' => '~[\x{0000}-\x{007F}\x{0080}-\x{00FF}]~u',
- 'groups' => ['xsd_rules'],
- ],
- ],
- ],
- ],
[
'',
[
diff --git a/tests/PHP/AnyTypePHPConversionTest.php b/tests/PHP/AnyTypePHPConversionTest.php
index f4f01c9..beff5ed 100644
--- a/tests/PHP/AnyTypePHPConversionTest.php
+++ b/tests/PHP/AnyTypePHPConversionTest.php
@@ -105,8 +105,8 @@ public function testSimpleAnyTypePHP()
$returnTags = $single->getMethod('getId')->getDocBlock()->getTags();
- $this->assertCount(1, $returnTags);
- $this->assertEquals(['mixed'], $returnTags[0]->getTypes());
+ $this->assertCount(0, $returnTags);
+ $this->assertEquals('mixed', (string)$single->getMethod('getId')->getReturnType());
}
public function testSimpleAnyTypeYaml()
diff --git a/tests/PHP/PHPConversionTest.php b/tests/PHP/PHPConversionTest.php
index 37e9b49..c49a5ee 100644
--- a/tests/PHP/PHPConversionTest.php
+++ b/tests/PHP/PHPConversionTest.php
@@ -146,9 +146,11 @@ public function testMulteplicity()
$this->assertTrue($codegen->hasMethod('getId'));
$this->assertTrue($codegen->hasMethod('setId'));
+ $this->assertEquals('static',(string)$codegen->getMethod('setId')->getReturnType());
+ $this->assertEquals('array',(string)$codegen->getMethod('getId')->getReturnType());
- $this->assertNull($codegen->getMethod('issetId')->getParameters()['index']->getType());
- $this->assertNull($codegen->getMethod('issetId')->getParameters()['index']->getType());
+ $this->assertEquals('int|string',$codegen->getMethod('issetId')->getParameters()['index']->getType());
+ $this->assertEquals('int|string',$codegen->getMethod('unsetId')->getParameters()['index']->getType());
}
public function testNestedMulteplicity()
@@ -278,7 +280,7 @@ public function testNillableElement()
$this->assertTrue($codegen->hasMethod('setDate2'));
$this->assertNull($codegen->getMethod('setDate2')->getParameters()['date2']->getDefaultValue());
$this->assertTrue($codegen->hasMethod('setStr1'));
- $this->assertNull($codegen->getMethod('setStr1')->getParameters()['str1']->getDefaultValue());
+ $this->assertNull($codegen->getMethod('setStr1')->getParameters()['str1']->getDefaultValue()->getValue());
$this->assertTrue($codegen->hasMethod('setStr2'));
$this->assertNull($codegen->getMethod('setStr2')->getParameters()['str2']->getDefaultValue());
}