diff --git a/src/JsonSchema/PhpBuilder.php b/src/JsonSchema/PhpBuilder.php index 8401a29..cebdfcf 100644 --- a/src/JsonSchema/PhpBuilder.php +++ b/src/JsonSchema/PhpBuilder.php @@ -19,6 +19,7 @@ use Swaggest\PhpCodeBuilder\PhpFlags; use Swaggest\PhpCodeBuilder\PhpFunction; use Swaggest\PhpCodeBuilder\PhpNamedVar; +use Swaggest\PhpCodeBuilder\PhpStdType; use Swaggest\PhpCodeBuilder\Property\AdditionalPropertiesGetter; use Swaggest\PhpCodeBuilder\Property\AdditionalPropertySetter; use Swaggest\PhpCodeBuilder\Property\Getter; @@ -73,6 +74,13 @@ public function __construct() */ public $declarePropertyDefaults = false; + /** + * Build setter and getter methods for additional properties + * on a boolean true value for `additionalProperties`. + * @var bool + */ + public $buildAdditionalPropertyMethodsOnTrue = false; + /** * @param SchemaContract $schema * @param string $path @@ -210,9 +218,19 @@ private function makeClass($schema, $path) } } + $additionalPropertiesType = null; + $buildAdditionalPropertiesMethods = false; if ($schema->additionalProperties instanceof Schema) { - $class->addMethod(new AdditionalPropertiesGetter($this->getType($schema->additionalProperties))); - $class->addMethod(new AdditionalPropertySetter($this->getType($schema->additionalProperties))); + $additionalPropertiesType = $this->getType($schema->additionalProperties); + $buildAdditionalPropertiesMethods = true; + } elseif ($this->buildAdditionalPropertyMethodsOnTrue && $schema->additionalProperties === true) { + $additionalPropertiesType = PhpStdType::mixed(); + $buildAdditionalPropertiesMethods = true; + } + + if ($buildAdditionalPropertiesMethods) { + $class->addMethod(new AdditionalPropertiesGetter($additionalPropertiesType)); + $class->addMethod(new AdditionalPropertySetter($additionalPropertiesType)); } if ($schema->patternProperties !== null) { diff --git a/tests/resources/JsonSchema/AdvancedTest/testBuildingAdditionalPropertyMethodsOnTrue-new-behavior.txt b/tests/resources/JsonSchema/AdvancedTest/testBuildingAdditionalPropertyMethodsOnTrue-new-behavior.txt new file mode 100644 index 0000000..2463ab7 --- /dev/null +++ b/tests/resources/JsonSchema/AdvancedTest/testBuildingAdditionalPropertyMethodsOnTrue-new-behavior.txt @@ -0,0 +1,47 @@ +/** + * @method static mixed import($data, Swaggest\JsonSchema\Context $options = null) + */ +class Root extends Swaggest\JsonSchema\Structure\ClassStructure +{ + /** + * @param Swaggest\JsonSchema\Constraint\Properties|static $properties + * @param Swaggest\JsonSchema\Schema $ownerSchema + */ + public static function setUpProperties($properties, Swaggest\JsonSchema\Schema $ownerSchema) + { + $ownerSchema->type = Swaggest\JsonSchema\Schema::OBJECT; + $ownerSchema->additionalProperties = true; + } + + /** + * @return array + * @codeCoverageIgnoreStart + */ + public function getAdditionalPropertyValues() + { + $result = array(); + if (!$names = $this->getAdditionalPropertyNames()) { + return $result; + } + foreach ($names as $name) { + $result[$name] = $this->$name; + } + return $result; + } + /** @codeCoverageIgnoreEnd */ + + /** + * @param string $name + * @param mixed $value + * @return self + * @codeCoverageIgnoreStart + */ + public function setAdditionalPropertyValue($name, $value) + { + $this->addAdditionalPropertyName($name); + $this->{$name} = $value; + return $this; + } + /** @codeCoverageIgnoreEnd */ +} + diff --git a/tests/resources/JsonSchema/AdvancedTest/testBuildingAdditionalPropertyMethodsOnTrue-old-behavior.txt b/tests/resources/JsonSchema/AdvancedTest/testBuildingAdditionalPropertyMethodsOnTrue-old-behavior.txt new file mode 100644 index 0000000..2bede1c --- /dev/null +++ b/tests/resources/JsonSchema/AdvancedTest/testBuildingAdditionalPropertyMethodsOnTrue-old-behavior.txt @@ -0,0 +1,16 @@ +/** + * @method static mixed import($data, Swaggest\JsonSchema\Context $options = null) + */ +class Root extends Swaggest\JsonSchema\Structure\ClassStructure +{ + /** + * @param Swaggest\JsonSchema\Constraint\Properties|static $properties + * @param Swaggest\JsonSchema\Schema $ownerSchema + */ + public static function setUpProperties($properties, Swaggest\JsonSchema\Schema $ownerSchema) + { + $ownerSchema->type = Swaggest\JsonSchema\Schema::OBJECT; + $ownerSchema->additionalProperties = true; + } +} + diff --git a/tests/src/PHPUnit/JsonSchema/AdvancedTest.php b/tests/src/PHPUnit/JsonSchema/AdvancedTest.php index e8142a0..e0d4fb9 100644 --- a/tests/src/PHPUnit/JsonSchema/AdvancedTest.php +++ b/tests/src/PHPUnit/JsonSchema/AdvancedTest.php @@ -733,4 +733,43 @@ public function testClassPropertyDefaultsDeactivated() $this->assertContains($expected, $result); } + public function testBuildingAdditionalPropertyMethodsOnTrue() + { + $schemaData = json_decode(<<<'JSON' +{ + "type": "object", + "additionalProperties": true +} +JSON + ); + + // Keeping the old behavior + $schema = Schema::import($schemaData); + $builder = new PhpBuilder(); + $class = $builder->getClass($schema, 'Root'); + + $result = ''; + foreach ($builder->getGeneratedClasses() as $class) { + $result .= $class->class . "\n\n"; + } + + $expected = file_get_contents(__DIR__ . '/../../../resources/JsonSchema/AdvancedTest/' . __FUNCTION__ . '-old-behavior.txt'); + + $this->assertSame($expected, $result, 'Getter and setter not created (old behavior - flag: false)'); + + // Testing the new behavior with setted flag + $schema = Schema::import($schemaData); + $builder = new PhpBuilder(); + $builder->buildAdditionalPropertyMethodsOnTrue = true; + $class = $builder->getClass($schema, 'Root'); + + $result = ''; + foreach ($builder->getGeneratedClasses() as $class) { + $result .= $class->class . "\n\n"; + } + + $expected = file_get_contents(__DIR__ . '/../../../resources/JsonSchema/AdvancedTest/' . __FUNCTION__ . '-new-behavior.txt'); + + $this->assertSame($expected, $result, 'Getter and setter created (new behavior - flag: true)'); + } } \ No newline at end of file