Skip to content

Commit a8ddd3f

Browse files
Bernhard Schmittmficzel
authored andcommitted
Adjust Neos.Flow Configuration subcontext
1 parent 65cecb8 commit a8ddd3f

11 files changed

Lines changed: 114 additions & 47 deletions

Neos.Flow/Classes/Configuration/ConfigurationManager.php

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ class ConfigurationManager
135135
/**
136136
* Storage of the raw special configurations
137137
*
138-
* @var array
138+
* @var array<string,mixed>
139139
*/
140140
protected $configurations = [];
141141

@@ -159,7 +159,7 @@ class ConfigurationManager
159159
protected $temporaryDirectoryPath = null;
160160

161161
/**
162-
* @var array
162+
* @var array<string,mixed>
163163
*/
164164
protected $unprocessedConfiguration = [];
165165

@@ -229,9 +229,6 @@ public function registerConfigurationType(string $configurationType, $configurat
229229
} elseif (is_string($configurationLoader)) {
230230
$configurationLoader = $this->convertLegacyProcessingType($configurationType, $configurationLoader);
231231
}
232-
if (!$configurationLoader instanceof LoaderInterface) {
233-
throw new \InvalidArgumentException(sprintf('Specified invalid configuration loader of type "%s" while registering custom configuration type "%s". This should be an instance of %s', is_object($configurationLoader) ? get_class($configurationLoader) : gettype($configurationLoader), $configurationType, LoaderInterface::class), 1617895964);
234-
}
235232

236233
// if the configuration was already registered and the there is an unprocessed loaded configuration, the configuration needs to be loaded again
237234
// on the other hand, if there is a processed configuration loaded, but no unprocessed configuration, the config must be from the cache and is assumed to be valid
@@ -418,6 +415,7 @@ public function flushConfigurationCache(): void
418415
* Generate configuration with environment variables replaced without modifying or loading the cache
419416
*
420417
* @param string $configurationType The kind of configuration to fetch
418+
* @return void
421419
*/
422420
protected function processConfigurationType(string $configurationType)
423421
{
@@ -524,15 +522,15 @@ protected function replaceVariablesInPhpString(string $phpString): string
524522
}
525523
$replacement .= ($constantDoesNotStartAsBeginning ? $matchGroup['startString'] . "' . " : '=> ');
526524

527-
if (isset($matchGroup['prefix']) && $matchGroup['prefix'] === 'env') {
525+
if ($matchGroup['prefix'] === 'env') {
528526
if ($matchGroup['type'] === 'bool') {
529527
$replacement .= "!in_array(strtolower(getenv('" . $matchGroup['name'] . "')), ['', '0', 'false'], true)";
530528
} elseif ($matchGroup['type'] !== '') {
531529
$replacement .= "(" . $matchGroup['type'] . ")getenv('" . $matchGroup['name'] . "')";
532530
} else {
533531
$replacement .= "getenv('" . $matchGroup['name'] . "')";
534532
}
535-
} elseif (isset($matchGroup['expression'])) {
533+
} else {
536534
$replacement .= "(defined('" . $matchGroup['expression'] . "') ? constant('" . $matchGroup['expression'] . "') : null)";
537535
}
538536

@@ -548,7 +546,11 @@ protected function replaceVariablesInPhpString(string $phpString): string
548546
return $replacement;
549547
}, $phpString);
550548

551-
return $phpString;
549+
if (is_string($phpString)) {
550+
return $phpString;
551+
}
552+
553+
throw new \RuntimeException('Failed to render PHP string', 1744468312);
552554
}
553555

554556
/**

Neos.Flow/Classes/Configuration/ConfigurationSchemaValidator.php

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,9 @@ class ConfigurationSchemaValidator
6464
/**
6565
* Validate the given $configurationType and $path
6666
*
67-
* @param string $configurationType (optional) the configuration type to validate. if NULL, validates all configuration.
68-
* @param string $path (optional) configuration path to validate
69-
* @param array $loadedSchemaFiles (optional). if given, will be filled with a list of loaded schema files
67+
* @param ?string $configurationType (optional) the configuration type to validate. if NULL, validates all configuration.
68+
* @param ?string $path (optional) configuration path to validate
69+
* @param array<int,string> $loadedSchemaFiles (optional). if given, will be filled with a list of loaded schema files
7070
* @return \Neos\Error\Messages\Result the result of the validation
7171
* @throws Exception\SchemaValidationException
7272
*/
@@ -91,7 +91,7 @@ public function validate(?string $configurationType = null, ?string $path = null
9191
*
9292
* @param string $configurationType the configuration typr to validate
9393
* @param string|null $path configuration path to validate, or NULL.
94-
* @param array $loadedSchemaFiles will be filled with a list of loaded schema files
94+
* @param array<int,string> $loadedSchemaFiles will be filled with a list of loaded schema files
9595
* @return \Neos\Error\Messages\Result
9696
* @throws Exception\SchemaValidationException
9797
*/
@@ -121,7 +121,7 @@ protected function validateSingleType(string $configurationType, ?string $path =
121121
$schemaType = $schemaNameParts[0];
122122
$schemaPath = isset($schemaNameParts[1]) ? $schemaNameParts[1] : null;
123123

124-
if ($schemaType === $configurationType && ($path === null || strpos($schemaPath, $path) === 0)) {
124+
if ($schemaPath && $schemaType === $configurationType && ($path === null || str_starts_with($schemaPath, $path))) {
125125
$schemaFileInfos[] = [
126126
'file' => $schemaFile,
127127
'name' => $schemaName,
@@ -138,6 +138,7 @@ protected function validateSingleType(string $configurationType, ?string $path =
138138
}
139139

140140
$result = new Result();
141+
/** @var array<int,array{file: string, name: string, path: ?string, packageKey: string}> $schemaFileInfos */
141142
foreach ($schemaFileInfos as $schemaFileInfo) {
142143
$loadedSchemaFiles[] = $schemaFileInfo['file'];
143144

Neos.Flow/Classes/Configuration/Loader/AppendLoader.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515

1616
use Neos\Flow\Configuration\Source\YamlSource;
1717
use Neos\Flow\Core\ApplicationContext;
18+
use Neos\Flow\Package\FlowPackageInterface;
19+
use Neos\Flow\Package\PackageInterface;
1820

1921
class AppendLoader implements LoaderInterface
2022
{
@@ -34,6 +36,10 @@ public function __construct(YamlSource $yamlSource, string $filePrefix)
3436
$this->filePrefix = $filePrefix;
3537
}
3638

39+
/**
40+
* @param array<FlowPackageInterface> $packages
41+
* @return array<int,array<mixed>>
42+
*/
3743
public function load(array $packages, ApplicationContext $context): array
3844
{
3945
$configuration = [];

Neos.Flow/Classes/Configuration/Loader/LoaderInterface.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
*/
1515

1616
use Neos\Flow\Core\ApplicationContext;
17+
use Neos\Flow\Package\PackageInterface;
1718

1819
/**
1920
* The interface for a configuration loader
@@ -23,9 +24,9 @@ interface LoaderInterface
2324
/**
2425
* Read configuration resources and return the final configuration array for the given configurationType
2526
*
26-
* @param array $packages An array of Package objects (indexed by package key) to consider
27+
* @param array<PackageInterface> $packages An array of Package objects (indexed by package key) to consider
2728
* @param ApplicationContext $context
28-
* @return array The Configuration array for the current configurationType
29+
* @return array<mixed> The Configuration array for the current configurationType
2930
*/
3031
public function load(array $packages, ApplicationContext $context) : array;
3132
}

Neos.Flow/Classes/Configuration/Loader/MergeLoader.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515

1616
use Neos\Flow\Configuration\Source\YamlSource;
1717
use Neos\Flow\Core\ApplicationContext;
18+
use Neos\Flow\Package\FlowPackageInterface;
19+
use Neos\Flow\Package\PackageInterface;
1820
use Neos\Utility\Arrays;
1921

2022
class MergeLoader implements LoaderInterface
@@ -35,6 +37,10 @@ public function __construct(YamlSource $yamlSource, string $filePrefix)
3537
$this->filePrefix = $filePrefix;
3638
}
3739

40+
/**
41+
* @param array<FlowPackageInterface> $packages
42+
* @return array<mixed>
43+
*/
3844
public function load(array $packages, ApplicationContext $context): array
3945
{
4046
$configuration = [];

Neos.Flow/Classes/Configuration/Loader/ObjectsLoader.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Neos\Flow\Configuration\ConfigurationManager;
1717
use Neos\Flow\Configuration\Source\YamlSource;
1818
use Neos\Flow\Core\ApplicationContext;
19+
use Neos\Flow\Package\FlowPackageInterface;
1920
use Neos\Utility\Arrays;
2021

2122
class ObjectsLoader implements LoaderInterface
@@ -30,6 +31,10 @@ public function __construct(YamlSource $yamlSource)
3031
$this->yamlSource = $yamlSource;
3132
}
3233

34+
/**
35+
* @param array<string, FlowPackageInterface> $packages
36+
* @return array<string,array<mixed>>
37+
*/
3338
public function load(array $packages, ApplicationContext $context): array
3439
{
3540
$configuration = [];

Neos.Flow/Classes/Configuration/Loader/PolicyLoader.php

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,12 @@
1616
use Neos\Flow\Configuration\ConfigurationManager;
1717
use Neos\Flow\Configuration\Source\YamlSource;
1818
use Neos\Flow\Core\ApplicationContext;
19+
use Neos\Flow\Package\FlowPackageInterface;
1920
use Neos\Utility\Arrays;
2021

22+
/**
23+
* @phpstan-type PolicyDefinition array{roles?: array<string, array{privileges: array<mixed>}>}
24+
*/
2125
class PolicyLoader implements LoaderInterface
2226
{
2327
/**
@@ -47,6 +51,10 @@ public function setTemporaryDirectoryPath(string $temporaryDirectoryPath): void
4751
$this->temporaryDirectoryPath = $temporaryDirectoryPath;
4852
}
4953

54+
/**
55+
* @param array<FlowPackageInterface> $packages
56+
* @return PolicyDefinition
57+
*/
5058
public function load(array $packages, ApplicationContext $context): array
5159
{
5260
if ($context->isTesting()) {
@@ -77,9 +85,9 @@ public function load(array $packages, ApplicationContext $context): array
7785
/**
7886
* Merges two policy configuration arrays.
7987
*
80-
* @param array $firstConfigurationArray
81-
* @param array $secondConfigurationArray
82-
* @return array
88+
* @param PolicyDefinition $firstConfigurationArray
89+
* @param PolicyDefinition $secondConfigurationArray
90+
* @return PolicyDefinition
8391
*/
8492
private function mergePolicyConfiguration(array $firstConfigurationArray, array $secondConfigurationArray): array
8593
{

Neos.Flow/Classes/Configuration/Loader/RoutesLoader.php

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
* source code.
1414
*/
1515

16+
use http\Encoding\Stream\Deflate;
1617
use Neos\Flow\Configuration\ConfigurationManager;
1718
use Neos\Flow\Configuration\Exception as ConfigurationException;
1819
use Neos\Flow\Configuration\Exception\InvalidConfigurationException;
@@ -26,6 +27,26 @@
2627
use Neos\Utility\Arrays;
2728
use Neos\Utility\PositionalArraySorter;
2829

30+
/**
31+
* @phpstan-type RouteDefinition array{
32+
* name: string,
33+
* providerFactory?: class-string,
34+
* providerOptions?: array<mixed>,
35+
* uriPattern?: string,
36+
* subRoutes?: array<string,array{
37+
* package: string,
38+
* variables?: array<mixed>,
39+
* suffix?: string,
40+
* }>
41+
* }
42+
* @phpstan-type SubrouteDefinition array{
43+
* name?: string,
44+
* uriPattern?: string,
45+
* defaults?: mixed,
46+
* routeParts?: mixed,
47+
* subRoutes?: mixed,
48+
* }
49+
*/
2950
class RoutesLoader implements LoaderInterface
3051
{
3152
/**
@@ -52,9 +73,9 @@ public function __construct(YamlSource $yamlSource, ConfigurationManager $config
5273
}
5374

5475
/**
55-
* @param array $packages
76+
* @param array<PackageInterface> $packages
5677
* @param ApplicationContext $context
57-
* @return array
78+
* @return array<int,array<mixed>>
5879
* @throws ConfigurationException | InvalidConfigurationException | InvalidConfigurationTypeException | ParseErrorException | RecursionException
5980
*/
6081
public function load(array $packages, ApplicationContext $context): array
@@ -77,9 +98,9 @@ public function load(array $packages, ApplicationContext $context): array
7798
* Merges routes from Neos.Flow.mvc.routes settings into $routeDefinitions
7899
* NOTE: Routes from settings will always be appended to existing route definitions from the main Routes configuration!
79100
*
80-
* @param array $routeDefinitions
81-
* @param array $routeSettings
82-
* @return array
101+
* @param array<int,RouteDefinition> $routeDefinitions
102+
* @param array<mixed> $routeSettings
103+
* @return array<int,RouteDefinition>
83104
*/
84105
protected function includeSubRoutesFromSettings(array $routeDefinitions, array $routeSettings): array
85106
{
@@ -121,9 +142,9 @@ protected function includeSubRoutesFromSettings(array $routeDefinitions, array $
121142
*
122143
* @param PackageInterface[] $packages
123144
* @param ApplicationContext $context
124-
* @param array $routesConfiguration
145+
* @param array<mixed> $routesConfiguration
125146
* @param int $subRoutesRecursionLevel Counts how many SubRoutes have been loaded. If this number exceeds MAXIMUM_SUBROUTE_RECURSIONS, an exception is thrown
126-
* @return array
147+
* @return array<int,array<mixed>>
127148
* @throws ParseErrorException | RecursionException| ConfigurationException
128149
*/
129150
protected function mergeRoutesWithSubRoutes(array $packages, ApplicationContext $context, array $routesConfiguration, int $subRoutesRecursionLevel = 0): array
@@ -176,11 +197,11 @@ protected function mergeRoutesWithSubRoutes(array $packages, ApplicationContext
176197
/**
177198
* Merges all routes in $routesConfiguration with the sub routes in $subRoutesConfiguration
178199
*
179-
* @param array $routesConfiguration
180-
* @param array $subRoutesConfiguration
200+
* @param array<array{name?: string, uriPattern: string}> $routesConfiguration
201+
* @param array<SubrouteDefinition> $subRoutesConfiguration
181202
* @param string $subRouteKey the key of the sub route: <subRouteKey>
182-
* @param array $subRouteOptions
183-
* @return array the merged route configuration
203+
* @param array{variables?: array<mixed>} $subRouteOptions
204+
* @return array<int,SubrouteDefinition> the merged route configuration
184205
* @throws ParseErrorException
185206
*/
186207
protected function buildSubRouteConfigurations(array $routesConfiguration, array $subRoutesConfiguration, string $subRouteKey, array $subRouteOptions): array
@@ -190,7 +211,11 @@ protected function buildSubRouteConfigurations(array $routesConfiguration, array
190211
foreach ($subRoutesConfiguration as $subRouteConfiguration) {
191212
foreach ($routesConfiguration as $routeConfiguration) {
192213
$mergedSubRouteConfiguration = $subRouteConfiguration;
193-
$mergedSubRouteConfiguration['name'] = sprintf('%s :: %s', $routeConfiguration['name'] ?? 'Unnamed Route', $subRouteConfiguration['name'] ?? 'Unnamed Subroute');
214+
$mergedSubRouteConfiguration['name'] = sprintf(
215+
'%s :: %s',
216+
$routeConfiguration['name'] ?? 'Unnamed Route',
217+
$subRouteConfiguration['name'] ?? 'Unnamed Subroute'
218+
);
194219
$mergedSubRouteConfiguration['name'] = $this->replacePlaceholders($mergedSubRouteConfiguration['name'], $variables);
195220
if (!isset($mergedSubRouteConfiguration['uriPattern'])) {
196221
throw new ParseErrorException('No uriPattern defined in route configuration "' . $mergedSubRouteConfiguration['name'] . '".', 1274197615);
@@ -207,6 +232,7 @@ protected function buildSubRouteConfigurations(array $routesConfiguration, array
207232
if (isset($mergedSubRouteConfiguration['routeParts'])) {
208233
$mergedSubRouteConfiguration['routeParts'] = $this->replacePlaceholders($mergedSubRouteConfiguration['routeParts'], $variables);
209234
}
235+
/** @var SubrouteDefinition $mergedSubRouteConfiguration arrayMergeRecursiveOverrule does not change that */
210236
$mergedSubRouteConfiguration = Arrays::arrayMergeRecursiveOverrule($routeConfiguration, $mergedSubRouteConfiguration);
211237
unset($mergedSubRouteConfiguration['subRoutes']);
212238
$mergedSubRoutesConfigurations[] = $mergedSubRouteConfiguration;
@@ -219,9 +245,10 @@ protected function buildSubRouteConfigurations(array $routesConfiguration, array
219245
/**
220246
* Replaces placeholders in the format <variableName> with the corresponding variable of the specified $variables collection.
221247
*
222-
* @param string|array $value
223-
* @param array $variables
224-
* @return array|string
248+
* @param string|array<mixed> $value
249+
* @param array<mixed> $variables
250+
*
251+
* @return ($value is string ? string : array<mixed>)
225252
*/
226253
private function replacePlaceholders($value, array $variables)
227254
{

Neos.Flow/Classes/Configuration/Loader/SettingsLoader.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Neos\Flow\Configuration\ConfigurationManager;
1717
use Neos\Flow\Configuration\Source\YamlSource;
1818
use Neos\Flow\Core\ApplicationContext;
19+
use Neos\Flow\Package\FlowPackageInterface;
1920
use Neos\Utility\Arrays;
2021

2122
class SettingsLoader implements LoaderInterface
@@ -30,6 +31,10 @@ public function __construct(YamlSource $yamlSource)
3031
$this->yamlSource = $yamlSource;
3132
}
3233

34+
/**
35+
* @param array<string,FlowPackageInterface> $packages
36+
* @return array<mixed>
37+
*/
3338
public function load(array $packages, ApplicationContext $context): array
3439
{
3540
// Make sure that the Flow package is the first item of the packages array:

0 commit comments

Comments
 (0)