Skip to content

Commit 9b49e1b

Browse files
committed
Class re-usage
1 parent 0def334 commit 9b49e1b

File tree

16 files changed

+364
-193
lines changed

16 files changed

+364
-193
lines changed

src/Model/RenderJob.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
use PHPModelGenerator\Exception\FileSystemException;
1010
use PHPModelGenerator\Exception\RenderException;
1111
use PHPModelGenerator\Utils\RenderHelper;
12-
use Throwable;
1312

1413
class RenderJob
1514
{
@@ -122,9 +121,10 @@ protected function renderClass(GeneratorConfiguration $generatorConfiguration):
122121
: [$generatorConfiguration->getExceptionClass()]
123122
);
124123

125-
if ($namespace) {
126-
$use[] = Throwable::class;
127-
}
124+
// filter out non-compound namespaces
125+
$use = array_filter($use, function ($classPath) {
126+
return strstr($classPath, '\\');
127+
});
128128

129129
try {
130130
$class = $render->renderTemplate(

src/Model/Schema.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,14 +143,16 @@ public function addNamespaceTransferDecorator(SchemaNamespaceTransferDecorator $
143143
}
144144

145145
/**
146+
* @param Schema[] $visitedSchema
147+
*
146148
* @return array
147149
*/
148-
public function getUsedClasses(): array
150+
public function getUsedClasses(array $visitedSchema = []): array
149151
{
150152
$usedClasses = $this->usedClasses;
151153

152154
foreach ($this->namespaceTransferDecorators as $decorator) {
153-
$usedClasses = array_merge($usedClasses, $decorator->resolve());
155+
$usedClasses = array_merge($usedClasses, $decorator->resolve(array_merge($visitedSchema, [$this])));
154156
}
155157

156158
return $usedClasses;
Lines changed: 111 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,103 +1,111 @@
1-
<?php
2-
3-
declare(strict_types = 1);
4-
5-
namespace PHPModelGenerator\Model\SchemaDefinition;
6-
7-
use PHPModelGenerator\Exception\PHPModelGeneratorException;
8-
use PHPModelGenerator\Exception\SchemaException;
9-
use PHPModelGenerator\Model\Property\PropertyInterface;
10-
use PHPModelGenerator\Model\Property\PropertyProxy;
11-
use PHPModelGenerator\Model\Schema;
12-
use PHPModelGenerator\PropertyProcessor\PropertyCollectionProcessor;
13-
use PHPModelGenerator\PropertyProcessor\PropertyFactory;
14-
use PHPModelGenerator\PropertyProcessor\PropertyProcessorFactory;
15-
use PHPModelGenerator\SchemaProcessor\SchemaProcessor;
16-
17-
/**
18-
* Class SchemaDefinition
19-
*
20-
* Hold a definition from a schema
21-
*
22-
* @package PHPModelGenerator\Model
23-
*/
24-
class SchemaDefinition
25-
{
26-
/** @var array */
27-
protected $structure;
28-
/** @var SchemaProcessor */
29-
protected $schemaProcessor;
30-
/** @var Schema */
31-
protected $schema;
32-
/** @var ResolvedDefinitionsCollection */
33-
protected $resolvedPaths;
34-
35-
/**
36-
* SchemaDefinition constructor.
37-
*
38-
* @param array $structure
39-
* @param SchemaProcessor $schemaProcessor
40-
* @param Schema $schema
41-
*/
42-
public function __construct(array $structure, SchemaProcessor $schemaProcessor, Schema $schema)
43-
{
44-
$this->structure = $structure;
45-
$this->schemaProcessor = $schemaProcessor;
46-
$this->schema = $schema;
47-
48-
$this->resolvedPaths = new ResolvedDefinitionsCollection();
49-
}
50-
51-
/**
52-
* Resolve a reference
53-
*
54-
* @param string $propertyName
55-
* @param array $path
56-
* @param PropertyCollectionProcessor $propertyCollectionProcessor
57-
*
58-
* @return PropertyInterface
59-
*
60-
* @throws PHPModelGeneratorException
61-
* @throws SchemaException
62-
*/
63-
public function resolveReference(
64-
string $propertyName,
65-
array $path,
66-
PropertyCollectionProcessor $propertyCollectionProcessor
67-
): PropertyInterface {
68-
$structure = $this->structure;
69-
$originalPath = $path;
70-
71-
while ($segment = array_shift($path)) {
72-
if (!isset($structure[$segment])) {
73-
throw new SchemaException("Unresolved path segment: $segment");
74-
}
75-
76-
$structure = $structure[$segment];
77-
}
78-
79-
$key = implode('-', $originalPath);
80-
81-
if (!$this->resolvedPaths->offsetExists($key)) {
82-
// create a dummy entry for the path first. If the path is used recursive the recursive usages will point
83-
// to the currently created property
84-
$this->resolvedPaths->offsetSet($key, true);
85-
try {
86-
$this->resolvedPaths->offsetSet($key, (new PropertyFactory(new PropertyProcessorFactory()))
87-
->create(
88-
$propertyCollectionProcessor,
89-
$this->schemaProcessor,
90-
$this->schema,
91-
$propertyName,
92-
$structure
93-
)
94-
);
95-
} catch (PHPModelGeneratorException $exception) {
96-
$this->resolvedPaths->offsetUnset($key);
97-
throw $exception;
98-
}
99-
}
100-
101-
return new PropertyProxy($this->resolvedPaths, $key);
102-
}
103-
}
1+
<?php
2+
3+
declare(strict_types = 1);
4+
5+
namespace PHPModelGenerator\Model\SchemaDefinition;
6+
7+
use PHPModelGenerator\Exception\PHPModelGeneratorException;
8+
use PHPModelGenerator\Exception\SchemaException;
9+
use PHPModelGenerator\Model\Property\PropertyInterface;
10+
use PHPModelGenerator\Model\Property\PropertyProxy;
11+
use PHPModelGenerator\Model\Schema;
12+
use PHPModelGenerator\PropertyProcessor\PropertyCollectionProcessor;
13+
use PHPModelGenerator\PropertyProcessor\PropertyFactory;
14+
use PHPModelGenerator\PropertyProcessor\PropertyProcessorFactory;
15+
use PHPModelGenerator\SchemaProcessor\SchemaProcessor;
16+
17+
/**
18+
* Class SchemaDefinition
19+
*
20+
* Hold a definition from a schema
21+
*
22+
* @package PHPModelGenerator\Model
23+
*/
24+
class SchemaDefinition
25+
{
26+
/** @var array */
27+
protected $structure;
28+
/** @var SchemaProcessor */
29+
protected $schemaProcessor;
30+
/** @var Schema */
31+
protected $schema;
32+
/** @var ResolvedDefinitionsCollection */
33+
protected $resolvedPaths;
34+
35+
/**
36+
* SchemaDefinition constructor.
37+
*
38+
* @param array $structure
39+
* @param SchemaProcessor $schemaProcessor
40+
* @param Schema $schema
41+
*/
42+
public function __construct(array $structure, SchemaProcessor $schemaProcessor, Schema $schema)
43+
{
44+
$this->structure = $structure;
45+
$this->schemaProcessor = $schemaProcessor;
46+
$this->schema = $schema;
47+
48+
$this->resolvedPaths = new ResolvedDefinitionsCollection();
49+
}
50+
51+
/**
52+
* @return Schema
53+
*/
54+
public function getSchema(): Schema
55+
{
56+
return $this->schema;
57+
}
58+
59+
/**
60+
* Resolve a reference
61+
*
62+
* @param string $propertyName
63+
* @param array $path
64+
* @param PropertyCollectionProcessor $propertyCollectionProcessor
65+
*
66+
* @return PropertyInterface
67+
*
68+
* @throws PHPModelGeneratorException
69+
* @throws SchemaException
70+
*/
71+
public function resolveReference(
72+
string $propertyName,
73+
array $path,
74+
PropertyCollectionProcessor $propertyCollectionProcessor
75+
): PropertyInterface {
76+
$structure = $this->structure;
77+
$originalPath = $path;
78+
79+
while ($segment = array_shift($path)) {
80+
if (!isset($structure[$segment])) {
81+
throw new SchemaException("Unresolved path segment: $segment");
82+
}
83+
84+
$structure = $structure[$segment];
85+
}
86+
87+
$key = implode('-', $originalPath);
88+
89+
if (!$this->resolvedPaths->offsetExists($key)) {
90+
// create a dummy entry for the path first. If the path is used recursive the recursive usages will point
91+
// to the currently created property
92+
$this->resolvedPaths->offsetSet($key, true);
93+
try {
94+
$this->resolvedPaths->offsetSet($key, (new PropertyFactory(new PropertyProcessorFactory()))
95+
->create(
96+
$propertyCollectionProcessor,
97+
$this->schemaProcessor,
98+
$this->schema,
99+
$propertyName,
100+
$structure
101+
)
102+
);
103+
} catch (PHPModelGeneratorException $exception) {
104+
$this->resolvedPaths->offsetUnset($key);
105+
throw $exception;
106+
}
107+
}
108+
109+
return new PropertyProxy($this->resolvedPaths, $key);
110+
}
111+
}

src/Model/SchemaDefinition/SchemaDefinitionDictionary.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ protected function parseExternalFile(
173173
}
174174

175175
// set up a dummy schema to fetch the definitions from the external file
176-
$schema = new Schema('', '', new self(dirname($jsonSchemaFilePath)));
176+
$schema = new Schema('ExternalSchema', '', new self(dirname($jsonSchemaFilePath)));
177177
$schema->getSchemaDictionary()->setUpDefinitionDictionary($jsonSchema, $schemaProcessor, $schema);
178178
$this->parsedExternalFileSchemas[$jsonSchemaFile] = $schema;
179179

src/PropertyProcessor/Decorator/SchemaNamespaceTransferDecorator.php

Lines changed: 8 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
namespace PHPModelGenerator\PropertyProcessor\Decorator;
66

7-
use PHPModelGenerator\Model\Property\PropertyInterface;
87
use PHPModelGenerator\Model\Schema;
98

109
/**
@@ -14,59 +13,31 @@ class SchemaNamespaceTransferDecorator
1413
{
1514
/** @var Schema */
1615
private $schema;
17-
/** @var bool */
18-
private $fetchPropertyImports;
1916

2017
/**
2118
* SchemaNamespaceTransferDecorator constructor.
2219
*
2320
* @param Schema $schema
24-
* @param bool $fetchPropertyImports
2521
*/
26-
public function __construct(Schema $schema, bool $fetchPropertyImports = false)
22+
public function __construct(Schema $schema)
2723
{
2824
$this->schema = $schema;
29-
$this->fetchPropertyImports = $fetchPropertyImports;
3025
}
3126

3227
/**
3328
* Get all used classes to use the referenced schema
3429
*
35-
* @return array
36-
*/
37-
public function resolve(): array
38-
{
39-
$usedClasses = $this->schema->getUsedClasses();
40-
41-
if ($this->fetchPropertyImports) {
42-
foreach ($this->schema->getProperties() as $property) {
43-
$usedClasses = array_merge($usedClasses, $this->getUsedClasses($property));
44-
}
45-
}
46-
47-
return $usedClasses;
48-
}
49-
50-
/**
51-
* Fetch required imports for handling a property
52-
*
53-
* @param PropertyInterface $property
30+
* @param Schema[] $visitedSchema
5431
*
5532
* @return array
5633
*/
57-
private function getUsedClasses(PropertyInterface $property): array
34+
public function resolve(array $visitedSchema): array
5835
{
59-
$classes = array_filter(
60-
explode('|', str_replace('[]', '', $property->getTypeHint())),
61-
function (string $type): bool {
62-
return !in_array($type, ['null', 'mixed', 'string', 'int', 'bool', 'float', 'array']);
63-
}
64-
);
65-
66-
array_walk($classes, function (string &$class): void {
67-
$class = "{$this->schema->getClassPath()}\\$class";
68-
});
36+
// avoid an endless loop while resolving recursive schema objects
37+
if (in_array($this->schema, $visitedSchema)) {
38+
return [];
39+
}
6940

70-
return $classes;
41+
return $this->schema->getUsedClasses($visitedSchema);
7142
}
7243
}

src/PropertyProcessor/Property/ObjectProcessor.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,11 @@ public function process(string $propertyName, array $propertyData): PropertyInte
4545
// $propertyData is duplicated) add used classes to the current schema. By importing the class which is
4646
// represented by $schema and by transferring all imports of $schema as well as imports for all properties
4747
// of $schema to $this->schema the already generated schema can be used
48-
if ($schema->getClassPath() !== $this->schema->getClassPath()) {
48+
if ($schema->getClassPath() !== $this->schema->getClassPath() ||
49+
$schema->getClassName() !== $this->schema->getClassName()
50+
) {
4951
$this->schema->addUsedClass("{$schema->getClassPath()}\\{$schema->getClassName()}");
50-
$this->schema->addNamespaceTransferDecorator(new SchemaNamespaceTransferDecorator($schema, true));
52+
$this->schema->addNamespaceTransferDecorator(new SchemaNamespaceTransferDecorator($schema));
5153
}
5254

5355
$property

0 commit comments

Comments
 (0)