Skip to content

Commit 6403cec

Browse files
author
Bernhard Schmitt
committed
Merge branch 'master' into remove-abstract-lists
2 parents fdf3873 + 3c0ee05 commit 6403cec

34 files changed

Lines changed: 478 additions & 334 deletions

Classes/Application/PseudoEnumProvider.php

Lines changed: 17 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use Neos\Flow\I18n\Translator;
1313
use Neos\Neos\Service\DataSource\AbstractDataSource;
1414
use Neos\Eel\ProtectedContextAwareInterface;
15+
use PackageFactory\AtomicFusion\PresentationObjects\Domain\Component\PropType\IsEnum;
1516
use PackageFactory\AtomicFusion\PresentationObjects\Domain\Enum\EnumLabel;
1617
use PackageFactory\AtomicFusion\PresentationObjects\Domain\Enum\PseudoEnumInterface;
1718

@@ -31,20 +32,21 @@ final class PseudoEnumProvider extends AbstractDataSource implements ProtectedCo
3132
/**
3233
* @param NodeInterface|null $node
3334
* @param array<string|int,string> $arguments
34-
* @return array<string|int|float,array<string,string>>
35+
* @return array<string|int,array<string,string>>
3536
*/
3637
public function getData(NodeInterface $node = null, array $arguments = []): array
3738
{
38-
if (!isset($arguments['enumName'])) {
39+
if (!array_key_exists('enumName', $arguments) || !is_string($arguments['enumName'])) {
3940
throw new \InvalidArgumentException('Argument "enumName" must be provided.', 1625297174);
4041
}
4142
/** @var class-string<mixed> $enumName */
4243
$enumName = $arguments['enumName'];
44+
4345
$values = $this->getValues($enumName);
4446
$enumLabel = EnumLabel::fromEnumName($enumName);
4547
$options = [];
4648
foreach ($values as $value) {
47-
$options[$value]['label'] = $this->getLabel($enumLabel, (string)$value);
49+
$options[$value]['label'] = $enumLabel->translate((string)$value, $this->translator);
4850
}
4951

5052
return $options;
@@ -57,32 +59,25 @@ public function getData(NodeInterface $node = null, array $arguments = []): arra
5759
*/
5860
public function process(NodeType $nodeType, array &$configuration, array $options)
5961
{
60-
if (!isset($options['enumName'])) {
62+
if (!array_key_exists('enumName', $options) || !is_string($options['enumName'])) {
6163
throw new \InvalidArgumentException('Option "enumName" must be provided.', 1625298032);
6264
}
63-
$values = $this->getValues($options['enumName']);
64-
$enumLabel = EnumLabel::fromEnumName($options['enumName']);
65+
if (!array_key_exists('propertyNames', $options) || !is_array($options['propertyNames'])) {
66+
throw new \InvalidArgumentException('Option "propertyNames" must be provided.', 1626540931);
67+
}
68+
/** @var class-string<mixed> $enumName */
69+
$enumName = $options['enumName'];
70+
$values = $this->getValues($enumName);
71+
$enumLabel = EnumLabel::fromEnumName($enumName);
6572
foreach ($options['propertyNames'] as $propertyName) {
6673
foreach ($values as $value) {
6774
$configuration['properties'][$propertyName]['ui']['inspector']['editorOptions']['values'][$value] = [
68-
'label' => $this->getLabel($enumLabel, (string)$value)
75+
'label' => $enumLabel->translate((string)$value, $this->translator)
6976
];
7077
}
7178
}
7279
}
7380

74-
private function getLabel(EnumLabel $enumLabel, string $value): string
75-
{
76-
return $this->translator->translateById(
77-
$enumLabel->getLabelIdPrefix() . $value,
78-
[],
79-
null,
80-
null,
81-
$enumLabel->getSourceName(),
82-
$enumLabel->getPackageKey()
83-
) ?: $value;
84-
}
85-
8681
/**
8782
* @param class-string<mixed> $enumName
8883
* @return array|string[]|int[]
@@ -100,21 +95,13 @@ public function getValues(string $enumName): array
10095
*/
10196
public function getCases(string $enumName): array
10297
{
103-
$this->validateEnumName($enumName);
98+
if (!IsEnum::isSatisfiedByClassName($enumName)) {
99+
throw new \InvalidArgumentException('Given enum "' . $enumName . '" does not exist or does not implement the required ' . PseudoEnumInterface::class, 1625297031);
100+
}
104101

105102
return $enumName::cases();
106103
}
107104

108-
private function validateEnumName(string $enumName): void
109-
{
110-
if (!class_exists($enumName)) {
111-
throw new \InvalidArgumentException('Given enum "' . $enumName . '" does not exist.', 1625297031);
112-
}
113-
if (!in_array(PseudoEnumInterface::class, class_implements($enumName) ?: [])) {
114-
throw new \InvalidArgumentException('Given enum "' . $enumName . '" does not implement the required ' . PseudoEnumInterface::class, 1625297122);
115-
}
116-
}
117-
118105
public function allowsCallOfMethod($methodName): bool
119106
{
120107
return true;

Classes/Command/ComponentCommandController.php

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,13 @@ public function kickStartCommand(string $name, bool $listable = false, bool $yes
6666
new DefensiveConfirmationFileWriter($this->output, $yes)
6767
);
6868
$package = $this->packageResolver->resolvePackage();
69+
$componentName = ComponentName::fromInput($name, PackageKey::fromPackage($package));
70+
$componentPackage = $this->packageResolver->resolvePackage((string)$componentName->getPackageKey());
6971

7072
$componentGenerator->generateComponent(
71-
ComponentName::fromInput($name, PackageKey::fromPackage($package)),
73+
$componentName,
7274
$this->request->getExceedingArguments(),
73-
$package->getPackagePath(),
75+
$componentPackage->getPackagePath(),
7476
$this->colocate,
7577
$listable
7678
);
@@ -101,13 +103,15 @@ public function kickStartEnumCommand(string $componentName, string $name, string
101103
new DefensiveConfirmationFileWriter($this->output, $yes)
102104
);
103105
$package = $this->packageResolver->resolvePackage();
106+
$componentNameObject = ComponentName::fromInput($componentName, PackageKey::fromPackage($package));
107+
$componentPackage = $this->packageResolver->resolvePackage((string)$componentNameObject->getPackageKey());
104108

105109
$enumGenerator->generateEnum(
106-
ComponentName::fromInput($componentName, PackageKey::fromPackage($package)),
110+
$componentNameObject,
107111
$name,
108112
$type,
109113
$values,
110-
$package->getPackagePath(),
114+
$componentPackage->getPackagePath(),
111115
$this->colocate
112116
);
113117
}

Classes/Domain/Component/PropType/ComponentArrayPropType.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ public function getStyleGuideValue(int $nestingLevel = 0): string
4848
$componentPropType = new ComponentPropType($this->componentName, false);
4949
$componentStyleGuideValue = $componentPropType->getStyleGuideValue($nestingLevel + 1);
5050
return '{
51-
' . self::innerLeftPad($nestingLevel) . $componentStyleGuideValue . ',
52-
' . self::innerLeftPad($nestingLevel) . $componentStyleGuideValue . '
51+
' . self::innerLeftPad($nestingLevel) . '0 ' . $componentStyleGuideValue . '
52+
' . self::innerLeftPad($nestingLevel) . '1 ' .$componentStyleGuideValue . '
5353
' . self::outerLeftPad($nestingLevel) . '}';
5454
}
5555

Classes/Domain/Component/PropType/EnumPropType.php

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -61,16 +61,17 @@ public function getStyleGuideValue(int $nestingLevel = 0): string
6161
return '= \'\'';
6262
}
6363

64-
$values = $this->className::cases();
65-
/** @var PseudoEnumInterface $value */
66-
$value = reset($values);
67-
switch ((string) $type) {
68-
case 'string':
69-
return '= \'' . $value->getValue() . '\'';
70-
case 'int':
71-
case 'float':
72-
return '= ' . $value->getValue();
73-
default:
64+
$cases = $this->className::cases();
65+
if (!empty($cases)) {
66+
/** @var PseudoEnumInterface $defaultCase */
67+
$defaultCase = reset($cases);
68+
switch ((string) $type) {
69+
case 'string':
70+
return '= \'' . $defaultCase->getValue() . '\'';
71+
case 'int':
72+
return '= ' . $defaultCase->getValue();
73+
default:
74+
}
7475
}
7576

7677
return '= \'\'';

Classes/Domain/Enum/Enum.php

Lines changed: 47 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,23 @@ final class Enum
2323
private EnumType $type;
2424

2525
/**
26-
* @var null|string[]|int[]|float[]
26+
* @var string[]|int[]
2727
*/
28-
private ?array $values;
28+
private array $cases;
2929

3030
/**
3131
* @param EnumName $name
3232
* @param EnumType $type
33-
* @param null|string[]|int[]|float[] $values
33+
* @param string[]|int[] $cases
3434
*/
35-
public function __construct(EnumName $name, EnumType $type, ?array $values)
35+
public function __construct(EnumName $name, EnumType $type, array $cases)
3636
{
37+
if (empty($cases)) {
38+
throw new \InvalidArgumentException('Enums must have at least one case, none given.', 1626541482);
39+
}
3740
$this->name = $name;
3841
$this->type = $type;
39-
$this->values = $values;
42+
$this->cases = $cases;
4043
}
4144

4245
/**
@@ -62,30 +65,34 @@ final class ' . $this->name->getName() . ' implements PseudoEnumInterface
6265
{
6366
' . $this->renderConstants() . '
6467
68+
/**
69+
* @var array<' . $this->type . ',self>|self[]
70+
*/
71+
private static array $instances;
72+
6573
private ' . $this->type . ' $value;
6674
6775
private function __construct(' . $this->type . ' $value)
6876
{
6977
$this->value = $value;
7078
}
7179
72-
public static function from' . ucfirst((string)$this->type) . '(' . $this->type . ' ' . $variable . '): self
80+
public static function from(' . $this->type . ' ' . $variable . '): self
7381
{
74-
if (!in_array(' . $variable . ', array_map(function(self $case) {
75-
return $case->getValue();
76-
}, self::cases()))) {
77-
throw ' . $this->name->getExceptionName() . '::becauseItMustBeOneOfTheDefinedConstants(' . $variable . ');
82+
if (!isset(self::$instances[' . $variable . '])) {
83+
' . $this->renderValidation() . '
84+
self::$instances[' . $variable . '] = new self(' . $variable . ');
7885
}
7986
80-
return new self(' . $variable . ');
87+
return self::$instances[' . $variable . '];
8188
}
8289
8390
' . $this->renderNamedConstructors() . '
8491
8592
' . $this->renderComparators() . '
8693
8794
/**
88-
* @return array|self[]
95+
* @return array<int,self>|self[]
8996
*/
9097
public static function cases(): array
9198
{
@@ -141,31 +148,43 @@ public static function becauseItMustBeOneOfTheDefinedConstants(' . $this->type .
141148
private function renderConstants(): string
142149
{
143150
$constants = [];
144-
if (is_array($this->values)) {
145-
foreach ($this->values as $name => $value) {
146-
$renderedValue = $this->type->isString()
147-
? '\'' . $value . '\''
148-
: $value;
149-
$constants[] = 'const ' . $this->getConstantName($name) . ' = ' . $renderedValue . ';';
150-
}
151+
foreach ($this->cases as $name => $case) {
152+
$renderedValue = $this->type->isString()
153+
? '\'' . $case . '\''
154+
: $case;
155+
$constants[] = 'const ' . $this->getConstantName($name) . ' = ' . $renderedValue . ';';
151156
}
152157

153158
return trim(implode("\n ", $constants));
154159
}
155160

161+
/**
162+
* @return string
163+
*/
164+
private function renderValidation(): string
165+
{
166+
$variable = '$' . $this->type;
167+
$caseChecks = [];
168+
foreach ($this->cases as $name => $value) {
169+
$caseChecks[] = $variable . ' !== self::' . $this->getConstantName($name);
170+
}
171+
172+
return 'if (' . implode("\n && ", $caseChecks) . ') {
173+
throw ' . $this->name->getExceptionName() . '::becauseItMustBeOneOfTheDefinedConstants(' . $variable . ');
174+
}';
175+
}
176+
156177
/**
157178
* @return string
158179
*/
159180
private function renderNamedConstructors(): string
160181
{
161182
$constructors = [];
162-
if (is_array($this->values)) {
163-
foreach ($this->values as $name => $value) {
164-
$constructors[] = 'public static function ' . $name . '(): self
183+
foreach ($this->cases as $name => $case) {
184+
$constructors[] = 'public static function ' . $name . '(): self
165185
{
166-
return new self(self::' . $this->getConstantName($name) . ');
186+
return self::from(self::' . $this->getConstantName($name) . ');
167187
}';
168-
}
169188
}
170189

171190
return trim(implode("\n\n ", $constructors));
@@ -177,13 +196,11 @@ private function renderNamedConstructors(): string
177196
private function renderComparators(): string
178197
{
179198
$comparators = [];
180-
if (is_array($this->values)) {
181-
foreach ($this->values as $name => $value) {
182-
$comparators[] = 'public function getIs' . ucfirst($name) . '(): bool
199+
foreach ($this->cases as $name => $case) {
200+
$comparators[] = 'public function getIs' . ucfirst($name) . '(): bool
183201
{
184202
return $this->value === self::' . $this->getConstantName($name) . ';
185203
}';
186-
}
187204
}
188205

189206
return trim(implode("\n\n ", $comparators));
@@ -196,10 +213,8 @@ public function renderCases(): string
196213
{
197214
$cases = [];
198215

199-
if (is_array($this->values)) {
200-
foreach ($this->values as $name => $value) {
201-
$cases[] = 'new self(self::' . $this->getConstantName($name) . '),';
202-
}
216+
foreach ($this->cases as $name => $case) {
217+
$cases[] = 'self::from(self::' . $this->getConstantName($name) . '),';
203218
}
204219

205220
return trim(trim(implode("\n ", $cases)), ',');

Classes/Domain/Enum/EnumLabel.php

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*/
77

88
use Neos\Flow\Annotations as Flow;
9+
use Neos\Flow\I18n\Translator;
910

1011
/**
1112
* @Flow\Proxy(false)
@@ -42,18 +43,15 @@ public static function fromEnumName(string $enumName): self
4243
);
4344
}
4445

45-
public function getLabelIdPrefix(): string
46+
public function translate(string $value, Translator $translator): string
4647
{
47-
return $this->labelIdPrefix;
48-
}
49-
50-
public function getSourceName(): string
51-
{
52-
return $this->sourceName;
53-
}
54-
55-
public function getPackageKey(): string
56-
{
57-
return $this->packageKey;
48+
return $translator->translateById(
49+
$this->labelIdPrefix . $value,
50+
[],
51+
null,
52+
null,
53+
$this->sourceName,
54+
$this->packageKey
55+
) ?: $value;
5856
}
5957
}

0 commit comments

Comments
 (0)