Skip to content

Commit 38bce59

Browse files
committed
TASK: Extract code generation into factories and value objects
1 parent 137c1ad commit 38bce59

7 files changed

Lines changed: 295 additions & 127 deletions

Classes/Command/NodetypeObjectsCommandController.php

Lines changed: 27 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,17 @@
1212
use Neos\Flow\Package\PackageManager;
1313
use Neos\Utility\Files;
1414
use Neos\Utility\Unicode\Functions as UnicodeFunctions;
15+
use PackageFactory\NodeTypeObjects\Factory\NodeTypeObjectFileFactory;
16+
use PackageFactory\NodeTypeObjects\Factory\NodeTypeSpecificationFactory;
1517

1618
class NodetypeObjectsCommandController extends CommandController
1719
{
1820
private NodeTypeManager $nodeTypeManager;
1921
private PackageManager $packageManager;
22+
private NodeTypeSpecificationFactory $nodeTypeSpecificationFactory;
23+
private NodeTypeObjectFileFactory $nodeTypeObjectFileFactory;
24+
25+
2026

2127
public function injectNodeTypeManager(NodeTypeManager $nodeTypeManager): void
2228
{
@@ -28,6 +34,16 @@ public function injectPackageManager(PackageManager $packageManager): void
2834
$this->packageManager = $packageManager;
2935
}
3036

37+
public function injectNodeTypeSpecificationFactory(NodeTypeSpecificationFactory $nodeTypeSpecificationFactory): void
38+
{
39+
$this->nodeTypeSpecificationFactory = $nodeTypeSpecificationFactory;
40+
}
41+
42+
public function injectNodeTypeObjectFileFactory(NodeTypeObjectFileFactory $nodeTypeObjectFileFactory): void
43+
{
44+
$this->nodeTypeObjectFileFactory = $nodeTypeObjectFileFactory;
45+
}
46+
3147
/**
3248
* Remove all NodeTypeObjects from the selected package
3349
*
@@ -77,143 +93,27 @@ public function buildCommand(string $packageKey): void
7793
$this->quit(1);
7894
}
7995

80-
$packagePath = $package->getPackagePath();
81-
$allNodeTypes = $this->nodeTypeManager->getNodeTypes(false);
82-
foreach ($allNodeTypes as $nodeType) {
96+
$nodeTypes = $this->nodeTypeManager->getNodeTypes(false);
97+
foreach ($nodeTypes as $nodeType) {
8398
if (!str_starts_with($nodeType->getName(), $packageKey . ':')) {
8499
continue;
85100
}
86-
$localNameParts = explode('.', str_replace($packageKey . ':', '', $nodeType->getName()));
87-
$localName = array_pop($localNameParts);
88-
$localNamespace = implode('.', $localNameParts);
89-
90-
$filePath = $packagePath
91-
. 'NodeTypes/'
92-
. str_replace('.', '/', $localNamespace)
93-
. '/' . $localName;
94-
$fileName = $localName . 'NodeObject.php';
95101

96-
$classNamespace = str_replace('.', '\\', $packageKey)
97-
. '\\NodeTypes'
98-
. '\\' . str_replace('.', '\\', $localNamespace)
99-
. '\\' . str_replace('.', '\\', $localName);
100-
101-
$className = $localName . 'NodeObject';
102-
103-
$this->buildOne(
102+
$specification = $this->nodeTypeSpecificationFactory->createFromPackageKeyAndNodeType(
104103
$package,
105-
$nodeType,
106-
$classNamespace,
107-
$className,
108-
$filePath,
109-
$fileName,
104+
$nodeType
110105
);
111106

112-
$this->outputLine(' - ' . $filePath . '/' . $fileName);
113-
}
114-
}
115-
116-
private function buildOne(FlowPackageInterface $package, NodeType $nodeType, string $classNamespace, string $className, string $filePath, string $fileName): void
117-
{
107+
$nodeTypeObjectFile = $this->nodeTypeObjectFileFactory->createNodeTypeObjectPhpCodeFromNode($specification);
118108

119-
$propertyAccesssors = '';
120-
foreach ($nodeType->getProperties() as $propertyName => $propertyConfig) {
121-
if (str_starts_with($propertyName, '_')) {
122-
$methodName = 'getInternal' . UnicodeFunctions::ucfirst(substr($propertyName, 1));
123-
} else {
124-
$methodName = 'get' . UnicodeFunctions::ucfirst($propertyName);
125-
}
126-
$type = $propertyConfig[ 'type' ];
127-
128-
$annotationType = null;
129-
$phpType = $type;
130-
131-
if (str_ends_with($type, '[]')) {
132-
$annotationType = $type;
133-
$phpType = 'array';
134-
} elseif (str_starts_with($type, 'array<') && str_ends_with($type, '>')) {
135-
$annotationType = substr($type, 6, -1) . '[]';
136-
$phpType = 'array';
137-
} elseif ($type === 'boolean') {
138-
$phpType = 'bool';
139-
} elseif ($type === 'integer') {
140-
$phpType = 'int';
141-
} elseif ($type === 'DateTime') {
142-
$phpType = '\DateTime';
143-
}
109+
Files::createDirectoryRecursively($nodeTypeObjectFile->pathName);
144110

145-
if (str_contains($phpType, '\\') && !str_starts_with($phpType, '\\')) {
146-
$phpType = '\\' . $phpType;
147-
}
148-
if (is_string($annotationType) && str_contains($annotationType, '\\') && !str_starts_with($annotationType, '\\')) {
149-
$annotationType = '\\' . $annotationType;
150-
}
151-
152-
if ($annotationType) {
153-
$propertyAccesssors .= <<<EOL
154-
155-
156-
/**
157-
* @return ?$annotationType;
158-
*/
159-
public function $methodName(): ?$phpType
160-
{
161-
return \$this->node->getProperty('$propertyName');
162-
}
163-
EOL;
164-
} else {
165-
$propertyAccesssors .= <<<EOL
166-
167-
168-
public function $methodName(): ?$phpType
169-
{
170-
return \$this->node->getProperty('$propertyName');
171-
}
172-
EOL;
173-
}
174-
}
175-
176-
$nodeTypeName = $nodeType->getName();
177-
178-
$class = <<<EOL
179-
<?php
180-
181-
declare(strict_types=1);
182-
183-
namespace $classNamespace;
184-
185-
use Neos\ContentRepository\Domain\Model\NodeInterface;
186-
use Neos\Flow\Annotations as Flow;
187-
188-
/**
189-
* AUTOGENERATED CODE ... DO NOT MODIFY !!!
190-
*
191-
* run `./ nodetypeobjects:build` to regenerate this
192-
*/
193-
#[Flow\Proxy(false)]
194-
final readonly class $className
195-
{
196-
private function __construct(
197-
public NodeInterface \$node
198-
) {
199-
}
111+
file_put_contents(
112+
$nodeTypeObjectFile->fileNameWithPath,
113+
$nodeTypeObjectFile->fileContent
114+
);
200115

201-
public static function fromNode(NodeInterface \$node): self
202-
{
203-
if (\$node->getNodeType()->getName() !== "$nodeTypeName") {
204-
throw new \Exception("unsupported nodetype " . \$node->getNodeType()->getName());
205-
}
206-
return new self(\$node);
207-
}$propertyAccesssors
116+
$this->outputLine(' - ' . $specification->nodeTypeName . '/' . $specification->className);
208117
}
209-
210-
EOL;
211-
212-
Files::createDirectoryRecursively($filePath);
213-
214-
file_put_contents(
215-
$filePath . '/' . $fileName,
216-
$class
217-
);
218118
}
219119
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PackageFactory\NodeTypeObjects\Domain;
6+
7+
use Neos\Flow\Annotations as Flow;
8+
9+
#[Flow\Proxy(false)]
10+
readonly class NodePropertySpecification
11+
{
12+
public function __construct(
13+
readonly string $propertyName,
14+
readonly string $propertyType
15+
) {
16+
}
17+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PackageFactory\NodeTypeObjects\Domain;
6+
7+
use Neos\Flow\Annotations as Flow;
8+
9+
/**
10+
* @implements \IteratorAggregate<int, NodePropertySpecification>
11+
*/
12+
#[Flow\Proxy(false)]
13+
readonly class NodePropertySpecificationCollection implements \IteratorAggregate
14+
{
15+
/**
16+
* @var NodePropertySpecification[]
17+
*/
18+
public array $properties;
19+
20+
public function __construct(
21+
NodePropertySpecification ...$properties
22+
) {
23+
$this->properties = $properties;
24+
}
25+
26+
/**
27+
* @return \Generator<int, NodePropertySpecification>
28+
*/
29+
public function getIterator(): \Generator
30+
{
31+
yield from $this->properties;
32+
}
33+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PackageFactory\NodeTypeObjects\Domain;
6+
7+
use Neos\Flow\Annotations as Flow;
8+
9+
#[Flow\Proxy(false)]
10+
readonly class NodeTypeObjectFile
11+
{
12+
public string $pathName;
13+
public string $fileName;
14+
15+
public function __construct(
16+
public string $fileNameWithPath,
17+
public string $fileContent,
18+
) {
19+
$filePathParts = explode(DIRECTORY_SEPARATOR, $this->fileNameWithPath);
20+
/** @var string $fileName */
21+
$fileName = array_pop($filePathParts);
22+
$this->fileName = $fileName;
23+
$this->pathName = implode(DIRECTORY_SEPARATOR, $filePathParts);
24+
}
25+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PackageFactory\NodeTypeObjects\Domain;
6+
7+
use Neos\Flow\Annotations as Flow;
8+
9+
#[Flow\Proxy(false)]
10+
readonly class NodeTypeObjectSpecification
11+
{
12+
public function __construct(
13+
public string $nodeTypeName,
14+
public string $className,
15+
public string $fileNameWithPath,
16+
public NodePropertySpecificationCollection $properties
17+
) {
18+
}
19+
}

0 commit comments

Comments
 (0)