Skip to content

Commit 9988a6c

Browse files
committed
Generate merged properties for property-level composed objects to access all properties
1 parent 6800622 commit 9988a6c

File tree

8 files changed

+90
-10
lines changed

8 files changed

+90
-10
lines changed

src/Model/Schema.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ class Schema
3333
*
3434
* @param SchemaDefinitionDictionary $dictionary
3535
*/
36-
public function __construct(SchemaDefinitionDictionary $dictionary)
36+
public function __construct(SchemaDefinitionDictionary $dictionary = null)
3737
{
38-
$this->schemaDefinitionDictionary = $dictionary;
38+
$this->schemaDefinitionDictionary = $dictionary ?? new SchemaDefinitionDictionary('');
3939
}
4040

4141
/**

src/PropertyProcessor/ComposedValue/AbstractComposedValueProcessor.php

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@
55
namespace PHPModelGenerator\PropertyProcessor\ComposedValue;
66

77
use PHPModelGenerator\Model\Property\CompositionPropertyDecorator;
8+
use PHPModelGenerator\Model\Property\Property;
89
use PHPModelGenerator\Model\Property\PropertyInterface;
10+
use PHPModelGenerator\Model\Schema;
911
use PHPModelGenerator\Model\Validator;
1012
use PHPModelGenerator\Model\Validator\ComposedPropertyValidator;
1113
use PHPModelGenerator\Model\Validator\RequiredPropertyValidator;
14+
use PHPModelGenerator\PropertyProcessor\Decorator\Property\ObjectInstantiationDecorator;
1215
use PHPModelGenerator\PropertyProcessor\Decorator\TypeHint\CompositionTypeHintDecorator;
1316
use PHPModelGenerator\PropertyProcessor\Property\AbstractValueProcessor;
1417
use PHPModelGenerator\PropertyProcessor\PropertyCollectionProcessor;
@@ -31,6 +34,7 @@ protected function generateValidators(PropertyInterface $property, array $proper
3134
$propertyFactory = new PropertyFactory(new PropertyProcessorFactory());
3235

3336
$properties = [];
37+
$createMergedProperty = $this instanceof MergedComposedPropertiesInterface;
3438

3539
foreach ($propertyData['propertyData'][$propertyData['type']] as $compositionElement) {
3640
$compositionProperty = new CompositionPropertyDecorator(
@@ -49,13 +53,23 @@ protected function generateValidators(PropertyInterface $property, array $proper
4953
!is_a($validator->getValidator(), ComposedPropertyValidator::class);
5054
});
5155

52-
$property->addTypeHintDecorator(new CompositionTypeHintDecorator($compositionProperty));
56+
// only create a composed type hint if we aren't a AnyOf or an AllOf processor and the compositionProperty
57+
// contains no object. This results in objects being composed each separately for a OneOf processor
58+
// (eg. string|ObjectA|ObjectB). For a merged composed property the objects are merged together so it
59+
// results in string|MergedObject
60+
if (!($createMergedProperty && $compositionProperty->getNestedSchema())) {
61+
$property->addTypeHintDecorator(new CompositionTypeHintDecorator($compositionProperty));
62+
}
5363

5464
$properties[] = $compositionProperty;
5565
}
5666

5767
$availableAmount = count($properties);
5868

69+
if ($createMergedProperty) {
70+
$this->createMergedProperty($property, $properties);
71+
}
72+
5973
$property->addValidator(
6074
new ComposedPropertyValidator(
6175
$property,
@@ -78,6 +92,43 @@ protected function generateValidators(PropertyInterface $property, array $proper
7892
);
7993
}
8094

95+
/**
96+
* TODO: no nested properties --> cancel, only one --> use original model
97+
*
98+
* Gather all nested object properties and merge them together into a single merged property
99+
*
100+
* @param PropertyInterface $property
101+
* @param CompositionPropertyDecorator[] $properties
102+
*
103+
* @return PropertyInterface
104+
*/
105+
private function createMergedProperty(PropertyInterface $property, array $properties): PropertyInterface
106+
{
107+
$mergedPropertySchema = new Schema();
108+
$mergedClassName = sprintf('%s_Merged_%s', $this->schemaProcessor->getCurrentClassName(), uniqid());
109+
$mergedProperty = new Property('MergedProperty', $mergedClassName);
110+
111+
foreach ($properties as $property) {
112+
if ($property->getNestedSchema()) {
113+
foreach ($property->getNestedSchema()->getProperties() as $nestedProperty) {
114+
$mergedPropertySchema->addProperty($nestedProperty);
115+
}
116+
}
117+
}
118+
119+
$this->schemaProcessor->generateClassFile(
120+
$this->schemaProcessor->getCurrentClassPath(),
121+
$mergedClassName,
122+
$mergedPropertySchema
123+
);
124+
125+
$property->addTypeHintDecorator(new CompositionTypeHintDecorator($mergedProperty));
126+
127+
return $mergedProperty
128+
->addDecorator(new ObjectInstantiationDecorator($mergedClassName))
129+
->setNestedSchema($mergedPropertySchema);
130+
}
131+
81132
/**
82133
* @param int $composedElements The amount of elements which are composed together
83134
*

src/PropertyProcessor/ComposedValue/AllOfProcessor.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
*
88
* @package PHPModelGenerator\PropertyProcessor\ComposedValue
99
*/
10-
class AllOfProcessor extends AbstractComposedValueProcessor implements ComposedPropertiesInterface
10+
class AllOfProcessor
11+
extends AbstractComposedValueProcessor
12+
implements ComposedPropertiesInterface, MergedComposedPropertiesInterface
1113
{
1214
/**
1315
* @inheritdoc

src/PropertyProcessor/ComposedValue/AnyOfProcessor.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
*
88
* @package PHPModelGenerator\PropertyProcessor\ComposedValue
99
*/
10-
class AnyOfProcessor extends AbstractComposedValueProcessor implements ComposedPropertiesInterface
10+
class AnyOfProcessor
11+
extends AbstractComposedValueProcessor
12+
implements ComposedPropertiesInterface, MergedComposedPropertiesInterface
1113
{
1214
/**
1315
* @inheritdoc

src/PropertyProcessor/ComposedValue/IfProcessor.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ protected function generateValidators(PropertyInterface $property, array $proper
6363
$properties[$compositionElement] = $compositionProperty;
6464
}
6565

66-
print_r($propertyData['propertyData'], true);
6766
$property->addValidator(
6867
new ConditionalPropertyValidator(
6968
$property,
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
declare(strict_types = 1);
4+
5+
namespace PHPModelGenerator\PropertyProcessor\ComposedValue;
6+
7+
/**
8+
* Interface MergedComposedPropertiesInterface
9+
*
10+
* @package PHPModelGenerator\PropertyProcessor\ComposedValue
11+
*/
12+
interface MergedComposedPropertiesInterface
13+
{
14+
}

src/SchemaProcessor/SchemaProcessor.php

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,20 @@ protected function generateModel(
143143
$structure
144144
);
145145

146+
$this->generateClassFile($classPath, $className, $schema);
147+
148+
return $schema;
149+
}
150+
151+
/**
152+
* Attach a new class file render job to the render proxy
153+
*
154+
* @param string $classPath
155+
* @param string $className
156+
* @param Schema $schema
157+
*/
158+
public function generateClassFile(string $classPath, string $className, Schema $schema): void
159+
{
146160
$fileName = join(
147161
DIRECTORY_SEPARATOR,
148162
[$this->destination, str_replace('\\', DIRECTORY_SEPARATOR, $classPath), $className]
@@ -157,8 +171,6 @@ protected function generateModel(
157171
}
158172

159173
$this->generatedFiles[] = $fileName;
160-
161-
return $schema;
162174
}
163175

164176
/**

tests/PropertyProcessor/PropertyProcessorFactoryTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public function testGetPropertyProcessor(string $type, string $expectedClass): v
4141
$type,
4242
new PropertyCollectionProcessor(),
4343
new SchemaProcessor('', '', new GeneratorConfiguration(), new RenderQueue()),
44-
new Schema(new SchemaDefinitionDictionary(''))
44+
new Schema()
4545
);
4646

4747
$this->assertInstanceOf($expectedClass, $propertyProcessor);
@@ -79,7 +79,7 @@ public function testGetInvalidPropertyProcessorThrowsAnException()
7979
'Hello',
8080
new PropertyCollectionProcessor(),
8181
new SchemaProcessor('', '', new GeneratorConfiguration(), new RenderQueue()),
82-
new Schema(new SchemaDefinitionDictionary(''))
82+
new Schema()
8383
);
8484
}
8585
}

0 commit comments

Comments
 (0)