├── COPYRIGHT.md ├── src ├── GlobTrait.php ├── ArrayProvider.php ├── PhpFileProvider.php ├── ConfigCannotBeCachedException.php ├── InvalidConfigProcessorException.php ├── LaminasConfigProvider.php ├── InvalidConfigProviderException.php └── ConfigAggregator.php ├── LICENSE.md ├── composer.json ├── README.md └── CHANGELOG.md /COPYRIGHT.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020 Laminas Project a Series of LF Projects, LLC. (https://getlaminas.org/) 2 | -------------------------------------------------------------------------------- /src/GlobTrait.php: -------------------------------------------------------------------------------- 1 | $config 20 | */ 21 | public function __construct(private readonly array $config) 22 | { 23 | } 24 | 25 | /** 26 | * @return array 27 | */ 28 | public function __invoke() 29 | { 30 | return $this->config; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/PhpFileProvider.php: -------------------------------------------------------------------------------- 1 | glob($this->pattern) as $file) { 31 | yield include $file; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/ConfigCannotBeCachedException.php: -------------------------------------------------------------------------------- 1 | getMessage() 24 | ), 25 | $exportException->getCode(), 26 | $exportException 27 | ); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/InvalidConfigProcessorException.php: -------------------------------------------------------------------------------- 1 | glob($this->pattern); 37 | return ConfigFactory::fromFiles($files); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/InvalidConfigProviderException.php: -------------------------------------------------------------------------------- 1 | ## 🇷🇺 Русским гражданам 6 | > 7 | > Мы, участники Laminas, родились и живем в разных странах. У многих из нас есть друзья, родственники и коллеги как в России, так и в Украине. Некоторые из нас родились в России. Некоторые из нас живут в России. У некоторых бабушки и дедушки сражались с фашистами во Второй мировой войне. Здесь никто не поддерживает фашизм. 8 | > 9 | > У одного из нас есть украинская родственница, которая спаслась из дома вместе с сыном. Поезд задержался из-за бомбежки на дороге впереди. У нас есть друзья, которые прячутся в бомбоубежищах. Мы с тревогой ждем весточки от них после воздушных налетов, которые беспорядочно наносят удары и попадают по больницам, школам, детским садам и домам. Мы не берем это из каких-либо СМИ. Мы наблюдаем это напрямую. 10 | > 11 | > Вы доверяете нам достаточно, чтоб использовать наши программы, и мы просим вас довериться нам вновь. Мы нуждаемся в помощи. Выходите и протестуйте против этой бесполезной войны. Остановите кровопролитие. Скажите "Нет войне!" 12 | > 13 | > ## 🇺🇸 To Citizens of Russia 14 | > 15 | > We at Laminas come from all over the world. Many of us have friends, family and colleagues in both Russia and Ukraine. Some of us were born in Russia. Some of us currently live in Russia. Some have grandparents who fought Nazis in World War II. Nobody here supports fascism. 16 | > 17 | > One team member has a Ukrainian relative who fled her home with her son. The train was delayed due to bombing on the road ahead. We have friends who are hiding in bomb shelters. We anxiously follow up on them after the air raids, which indiscriminately fire at hospitals, schools, kindergartens and houses. We're not taking this from any media. These are our actual experiences. 18 | > 19 | > You trust us enough to use our software. We ask that you trust us to say the truth on this. We need your help. Go out and protest this unnecessary war. Stop the bloodshed. Say "stop the war!" 20 | 21 | Aggregates and merges configuration, from a variety of formats. Supports caching 22 | for fast bootstrap in production environments. 23 | 24 | ## Usage 25 | 26 | The standalone `ConfigAggregator` can be used to merge PHP-based configuration 27 | files: 28 | 29 | ```php 30 | use Laminas\ConfigAggregator\ConfigAggregator; 31 | use Laminas\ConfigAggregator\PhpFileProvider; 32 | 33 | $aggregator = new ConfigAggregator([ 34 | new PhpFileProvider('*.global.php'), 35 | ]); 36 | 37 | var_dump($aggregator->getMergedConfig()); 38 | ``` 39 | 40 | Using this provider, each file should return a PHP array: 41 | 42 | ```php 43 | // db.global.php 44 | return [ 45 | 'db' => [ 46 | 'dsn' => 'mysql:...', 47 | ], 48 | ]; 49 | 50 | // cache.global.php 51 | return [ 52 | 'cache_storage' => 'redis', 53 | 'redis' => [ ... ], 54 | ]; 55 | ``` 56 | 57 | Result: 58 | 59 | ```php 60 | array(3) { 61 | 'db' => 62 | array(1) { 63 | 'dsn' => 64 | string(9) "mysql:..." 65 | } 66 | 'cache_storage' => 67 | string(5) "redis" 68 | 'redis' => 69 | array(0) { 70 | ... 71 | } 72 | } 73 | ``` 74 | 75 | Configuration is merged in the same order as it is passed, with later entries 76 | having precedence. 77 | 78 | Together with `laminas-config`, `laminas-config-aggregator` can be also used to load 79 | configuration in different formats, including YAML, JSON, XML, or INI: 80 | 81 | ```php 82 | use Laminas\ConfigAggregator\ConfigAggregator; 83 | use Laminas\ConfigAggregator\LaminasConfigProvider; 84 | 85 | $aggregator = new ConfigAggregator([ 86 | new LaminasConfigProvider('config/*.{json,yaml,php}'), 87 | ]); 88 | ``` 89 | 90 | For more details, please refer to the [documentation](https://docs.laminas.dev/laminas-config-aggregator/). 91 | 92 | ----- 93 | 94 | - File issues at https://github.com/laminas/laminas-config-aggregator/issues 95 | - Documentation is at https://docs.laminas.dev/laminas-config-aggregator/ 96 | -------------------------------------------------------------------------------- /src/ConfigAggregator.php: -------------------------------------------------------------------------------- 1 | 35 | * @psalm-type PostProcessorCallable = callable(array): array 36 | * @psalm-type PreProcessorCallable = callable(ProviderIterable): ProviderIterable 37 | * @final 38 | */ 39 | class ConfigAggregator 40 | { 41 | public const ENABLE_CACHE = 'config_cache_enabled'; 42 | 43 | public const CACHE_FILEMODE = 'config_cache_filemode'; 44 | 45 | /** 46 | * @todo Make this constant private in version 2.0.0 47 | */ 48 | public const CACHE_TEMPLATE = <<<'EOT' 49 | $postProcessors Array of post-processors. These may be callables, 68 | * or string values representing classes that act as post-processors. If the latter, they must be instantiable 69 | * without constructor arguments. 70 | * @param list $preProcessors Array of pre-processors. These may be callables, or 71 | * string values representing classes that act as pre-processors. If the latter, they must be instantiable 72 | * without constructor arguments. 73 | * @throws InvalidConfigProviderException 74 | */ 75 | public function __construct( 76 | iterable $providers = [], 77 | $cachedConfigFile = null, 78 | array $postProcessors = [], 79 | array $preProcessors = [], 80 | ) { 81 | if ($this->loadConfigFromCache($cachedConfigFile)) { 82 | return; 83 | } 84 | 85 | $providers = $this->preProcessProviders($preProcessors, $providers); 86 | $providers = $this->validateNoDuplicateProviders($providers); 87 | $this->config = $this->loadConfigFromProviders($providers); 88 | $this->config = $this->postProcessConfig($postProcessors, $this->config); 89 | $this->cacheConfig($this->config, $cachedConfigFile); 90 | } 91 | 92 | /** 93 | * @return array 94 | */ 95 | public function getMergedConfig() 96 | { 97 | return $this->config; 98 | } 99 | 100 | /** 101 | * Throw an exception if duplicate config providers are found. 102 | * 103 | * @param ProviderIterable $providers 104 | * @return ProviderIterable 105 | * @throws InvalidConfigProviderException 106 | */ 107 | private function validateNoDuplicateProviders(iterable $providers): iterable 108 | { 109 | $allProviders = $uniqueProviders = []; 110 | 111 | foreach ($providers as $provider) { 112 | $allProviders[] = $provider; 113 | if (! is_string($provider) && ! is_object($provider)) { 114 | continue; 115 | } 116 | 117 | if (in_array($provider, $uniqueProviders, true)) { 118 | throw InvalidConfigProviderException::fromDuplicateProvider( 119 | is_string($provider) ? $provider : get_debug_type($provider) 120 | ); 121 | } 122 | 123 | $uniqueProviders[] = $provider; 124 | } 125 | 126 | return $allProviders; 127 | } 128 | 129 | /** 130 | * Resolve a provider. 131 | * 132 | * If the provider is a string class name, instantiates that class and 133 | * tests if it is callable, returning it if true. 134 | * 135 | * If the provider is a callable, returns it verbatim. 136 | * 137 | * Raises an exception for any other condition. 138 | * 139 | * @param ProviderCallable|class-string $provider 140 | * @return ProviderCallable 141 | * @throws InvalidConfigProviderException 142 | */ 143 | private function resolveProvider(string|callable $provider): callable 144 | { 145 | if (is_string($provider)) { 146 | if (! class_exists($provider)) { 147 | throw InvalidConfigProviderException::fromNamedProvider($provider); 148 | } 149 | $provider = new $provider(); 150 | } 151 | 152 | if (! is_callable($provider)) { 153 | $type = $this->detectVariableType($provider); 154 | throw InvalidConfigProviderException::fromUnsupportedType($type); 155 | } 156 | 157 | // phpcs:ignore SlevomatCodingStandard.Commenting.InlineDocCommentDeclaration.MissingVariable 158 | /** @var ProviderCallable $provider */ 159 | return $provider; 160 | } 161 | 162 | /** 163 | * Resolve a processor. 164 | * 165 | * If the processor is a string class name, instantiates that class and 166 | * tests if it is callable, returning it if true. 167 | * 168 | * If the processor is a callable, returns it verbatim. 169 | * 170 | * Raises an exception for any other condition. 171 | * 172 | * @param PostProcessorCallable|PreProcessorCallable|class-string $processor 173 | * @return PostProcessorCallable|PreProcessorCallable 174 | * @throws InvalidConfigProcessorException 175 | */ 176 | private function resolveProcessor(string|callable $processor): callable 177 | { 178 | if (is_string($processor)) { 179 | if (! class_exists($processor)) { 180 | throw InvalidConfigProcessorException::fromNamedProcessor($processor); 181 | } 182 | $processor = new $processor(); 183 | } 184 | 185 | if (! is_callable($processor)) { 186 | $type = $this->detectVariableType($processor); 187 | throw InvalidConfigProcessorException::fromUnsupportedType($type); 188 | } 189 | 190 | // phpcs:ignore SlevomatCodingStandard.Commenting.InlineDocCommentDeclaration.MissingVariable 191 | /** @var PostProcessorCallable|PreProcessorCallable $processor */ 192 | return $processor; 193 | } 194 | 195 | /** 196 | * Perform a recursive merge of two multidimensional arrays. 197 | * 198 | * @codingStandardsIgnoreStart 199 | * Copied from https://github.com/laminas/laminas-stdlib/blob/980ce463c29c1a66c33e0eb67961bba895d0e19e/src/ArrayUtils.php#L269 200 | * @codingStandardsIgnoreEnd 201 | * 202 | * @return $a 203 | */ 204 | private function mergeArray(array $a, array $b): array 205 | { 206 | foreach ($b as $key => $value) { 207 | if ($value instanceof MergeReplaceKeyInterface) { 208 | $a[$key] = $value->getData(); 209 | } elseif (isset($a[$key]) || array_key_exists($key, $a)) { 210 | if ($value instanceof MergeRemoveKey) { 211 | unset($a[$key]); 212 | } elseif (is_int($key)) { 213 | $a[] = $value; 214 | } elseif (is_array($value) && is_array($a[$key])) { 215 | $a[$key] = $this->mergeArray($a[$key], $value); 216 | } else { 217 | $a[$key] = $value; 218 | } 219 | } else { 220 | if (! $value instanceof MergeRemoveKey) { 221 | $a[$key] = $value; 222 | } 223 | } 224 | } 225 | return $a; 226 | } 227 | 228 | /** 229 | * Merge configuration from a provider with existing configuration. 230 | * 231 | * @param array $mergedConfig Passed by reference as a performance/resource 232 | * optimization. 233 | * @param mixed $config Configuration generated by the $provider. 234 | * @param callable $provider Provider responsible for generating $config; 235 | * used for exception messages only. 236 | * @throws InvalidConfigProviderException 237 | */ 238 | private function mergeConfig(array &$mergedConfig, mixed $config, callable $provider): void 239 | { 240 | if (! is_array($config)) { 241 | $type = $this->detectVariableType($provider); 242 | 243 | throw new InvalidConfigProviderException(sprintf( 244 | 'Cannot read config from %s; does not return array', 245 | $type 246 | )); 247 | } 248 | 249 | $mergedConfig = $this->mergeArray($mergedConfig, $config); 250 | } 251 | 252 | /** 253 | * Iterate providers, merging config from each with the previous. 254 | * 255 | * @param ProviderIterable $providers 256 | */ 257 | private function loadConfigFromProviders(iterable $providers): array 258 | { 259 | $mergedConfig = []; 260 | foreach ($providers as $provider) { 261 | $provider = $this->resolveProvider($provider); 262 | $config = $provider(); 263 | if (! $config instanceof Generator) { 264 | $this->mergeConfig($mergedConfig, $config, $provider); 265 | continue; 266 | } 267 | 268 | // Handle generators 269 | foreach ($config as $cfg) { 270 | $this->mergeConfig($mergedConfig, $cfg, $provider); 271 | } 272 | } 273 | return $mergedConfig; 274 | } 275 | 276 | /** 277 | * Attempt to load the configuration from a cache file. 278 | * 279 | * @param null|non-empty-string $cachedConfigFile 280 | */ 281 | private function loadConfigFromCache(null|string $cachedConfigFile): bool 282 | { 283 | if (null === $cachedConfigFile) { 284 | return false; 285 | } 286 | 287 | if (! file_exists($cachedConfigFile)) { 288 | return false; 289 | } 290 | 291 | $this->config = require $cachedConfigFile; 292 | return true; 293 | } 294 | 295 | /** 296 | * Attempt to cache discovered configuration. 297 | * 298 | * @param null|non-empty-string $cachedConfigFile 299 | * @throws ConfigCannotBeCachedException 300 | */ 301 | private function cacheConfig(array $config, null|string $cachedConfigFile): void 302 | { 303 | if (null === $cachedConfigFile) { 304 | return; 305 | } 306 | 307 | if (empty($config[static::ENABLE_CACHE])) { 308 | return; 309 | } 310 | 311 | try { 312 | $contents = sprintf( 313 | self::CACHE_TEMPLATE, 314 | static::class, 315 | date('c'), 316 | VarExporter::export($config, VarExporter::ADD_RETURN | VarExporter::CLOSURE_SNAPSHOT_USES) 317 | ); 318 | } catch (ExportException $e) { 319 | throw ConfigCannotBeCachedException::fromExporterException($e); 320 | } 321 | 322 | $mode = $config[self::CACHE_FILEMODE] ?? null; 323 | $this->writeCache($cachedConfigFile, $contents, $mode); 324 | } 325 | 326 | /** 327 | * @param list $processors 328 | * @param ProviderIterable $providers 329 | * @return ProviderIterable 330 | */ 331 | private function preProcessProviders(array $processors, iterable $providers): iterable 332 | { 333 | foreach ($processors as $processor) { 334 | /** @var PreProcessorCallable $processorCallable */ 335 | $processorCallable = $this->resolveProcessor($processor); 336 | $providers = $processorCallable($providers); 337 | } 338 | 339 | return $providers; 340 | } 341 | 342 | /** 343 | * @param list $processors 344 | */ 345 | private function postProcessConfig(array $processors, array $config): array 346 | { 347 | foreach ($processors as $processor) { 348 | /** @var PostProcessorCallable $processorCallable */ 349 | $processorCallable = $this->resolveProcessor($processor); 350 | $config = $processorCallable($config); 351 | } 352 | 353 | return $config; 354 | } 355 | 356 | private function detectVariableType(object|callable $variable): string 357 | { 358 | if ($variable instanceof Closure) { 359 | return 'Closure'; 360 | } 361 | 362 | if (is_object($variable)) { 363 | return $variable::class; 364 | } 365 | 366 | return is_string($variable) ? $variable : gettype($variable); 367 | } 368 | 369 | /** 370 | * Attempt to cache discovered configuration. 371 | * 372 | * @param non-empty-string $cachedConfigFile 373 | */ 374 | private function writeCache(string $cachedConfigFile, string $contents, int|null $mode): void 375 | { 376 | try { 377 | if ($mode !== null) { 378 | FileWriter::writeFile($cachedConfigFile, $contents, $mode); 379 | } else { 380 | FileWriter::writeFile($cachedConfigFile, $contents); 381 | } 382 | } catch (FileWriterException) { 383 | // ignore errors writing cache file 384 | } 385 | } 386 | } 387 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file, in reverse chronological order by release. 4 | 5 | ## 1.20.0 - TBD 6 | 7 | ### Added 8 | 9 | - Nothing. 10 | 11 | ### Changed 12 | 13 | - Nothing. 14 | 15 | ### Deprecated 16 | 17 | - Nothing. 18 | 19 | ### Removed 20 | 21 | - Nothing. 22 | 23 | ### Fixed 24 | 25 | - Nothing. 26 | 27 | ## 1.19.0 - 2025-10-14 28 | 29 | 30 | ----- 31 | 32 | ### Release Notes for [1.19.0](https://github.com/laminas/laminas-config-aggregator/milestone/35) 33 | 34 | Feature release (minor) 35 | 36 | ### 1.19.0 37 | 38 | - Total issues resolved: **0** 39 | - Total pull requests resolved: **1** 40 | - Total contributors: **1** 41 | 42 | #### Dependencies,Enhancement 43 | 44 | - [58: Drop support for PHP 8.1, add support for PHP 8.5](https://github.com/laminas/laminas-config-aggregator/pull/58) thanks to @gsteel 45 | 46 | ## 1.18.0 - 2025-02-21 47 | 48 | 49 | ----- 50 | 51 | ### Release Notes for [1.18.0](https://github.com/laminas/laminas-config-aggregator/milestone/33) 52 | 53 | Feature release (minor) 54 | 55 | ### 1.18.0 56 | 57 | - Total issues resolved: **0** 58 | - Total pull requests resolved: **3** 59 | - Total contributors: **2** 60 | 61 | #### Dependencies,Enhancement 62 | 63 | - [56: Update dependency brick/varexporter to ^0.5.0 || ^0.4.0 || ^0.6.0](https://github.com/laminas/laminas-config-aggregator/pull/56) thanks to @renovate[bot] 64 | - [55: allow newer varexporter version](https://github.com/laminas/laminas-config-aggregator/pull/55) thanks to @reinfi 65 | 66 | #### Dependencies,Enhancement,QA 67 | 68 | - [53: Update Psalm to v6 marking all classes as soft `@final`](https://github.com/laminas/laminas-config-aggregator/pull/53) thanks to @renovate[bot] 69 | 70 | ## 1.17.0 - 2024-11-17 71 | 72 | 73 | ----- 74 | 75 | ### Release Notes for [1.17.0](https://github.com/laminas/laminas-config-aggregator/milestone/31) 76 | 77 | Feature release (minor) 78 | 79 | ### 1.17.0 80 | 81 | - Total issues resolved: **0** 82 | - Total pull requests resolved: **1** 83 | - Total contributors: **1** 84 | 85 | #### Enhancement 86 | 87 | - [52: Add support for PHP 8.4](https://github.com/laminas/laminas-config-aggregator/pull/52) thanks to @acelaya 88 | 89 | ## 1.16.0 - 2024-11-11 90 | 91 | 92 | ----- 93 | 94 | ### Release Notes for [1.16.0](https://github.com/laminas/laminas-config-aggregator/milestone/29) 95 | 96 | Feature release (minor) 97 | 98 | ### 1.16.0 99 | 100 | - Total issues resolved: **0** 101 | - Total pull requests resolved: **3** 102 | - Total contributors: **3** 103 | 104 | #### Enhancement 105 | 106 | - [51: Update to latest PHP 8.1 syntax](https://github.com/laminas/laminas-config-aggregator/pull/51) thanks to @samsonasik 107 | - [47: Make sure config providers are unique](https://github.com/laminas/laminas-config-aggregator/pull/47) thanks to @alexmerlin 108 | 109 | #### renovate 110 | 111 | - [49: Update dependency laminas/laminas-coding-standard to v3](https://github.com/laminas/laminas-config-aggregator/pull/49) thanks to @renovate[bot] 112 | 113 | ## 1.15.0 - 2024-05-12 114 | 115 | 116 | ----- 117 | 118 | ### Release Notes for [1.15.0](https://github.com/laminas/laminas-config-aggregator/milestone/27) 119 | 120 | Feature release (minor) 121 | 122 | ### 1.15.0 123 | 124 | - Total issues resolved: **0** 125 | - Total pull requests resolved: **6** 126 | - Total contributors: **3** 127 | 128 | #### Enhancement 129 | 130 | - [45: Add support for `brick/varexporter` 0.5.0](https://github.com/laminas/laminas-config-aggregator/pull/45) thanks to @acelaya 131 | - [39: Upgrade PHPUnit to version 10.x](https://github.com/laminas/laminas-config-aggregator/pull/39) thanks to @gsteel 132 | 133 | #### Duplicate,renovate 134 | 135 | - [44: Update dependency brick/varexporter to ^0.4.0 || ^0.5.0 - autoclosed](https://github.com/laminas/laminas-config-aggregator/pull/44) thanks to @renovate[bot] 136 | - [33: Update dependency phpunit/phpunit to v10](https://github.com/laminas/laminas-config-aggregator/pull/33) thanks to @renovate[bot] 137 | 138 | #### renovate 139 | 140 | - [43: Remove dev dependency laminas/laminas-servicemanager, CI matrix QA](https://github.com/laminas/laminas-config-aggregator/pull/43) thanks to @renovate[bot] 141 | - [41: Drop direct dev dependency on `nikic/php-parser`](https://github.com/laminas/laminas-config-aggregator/pull/41) thanks to @renovate[bot] 142 | 143 | ## 1.14.0 - 2023-09-19 144 | 145 | 146 | ----- 147 | 148 | ### Release Notes for [1.14.0](https://github.com/laminas/laminas-config-aggregator/milestone/25) 149 | 150 | Feature release (minor) 151 | 152 | ### 1.14.0 153 | 154 | - Total issues resolved: **0** 155 | - Total pull requests resolved: **4** 156 | - Total contributors: **2** 157 | 158 | #### Enhancement 159 | 160 | - [38: Remove support for PHP 8.0, add support for PHP 8.3](https://github.com/laminas/laminas-config-aggregator/pull/38) thanks to @gsteel 161 | 162 | #### renovate 163 | 164 | - [37: Bump brick/varexporter to ^0.4.0](https://github.com/laminas/laminas-config-aggregator/pull/37) thanks to @renovate[bot] 165 | - [32: Lock file maintenance](https://github.com/laminas/laminas-config-aggregator/pull/32) thanks to @renovate[bot] 166 | - [31: Lock file maintenance](https://github.com/laminas/laminas-config-aggregator/pull/31) thanks to @renovate[bot] 167 | 168 | ## 1.13.0 - 2022-12-03 169 | 170 | 171 | ----- 172 | 173 | ### Release Notes for [1.13.0](https://github.com/laminas/laminas-config-aggregator/milestone/23) 174 | 175 | Feature release (minor) 176 | 177 | ### 1.13.0 178 | 179 | - Total issues resolved: **0** 180 | - Total pull requests resolved: **2** 181 | - Total contributors: **2** 182 | 183 | #### renovate 184 | 185 | - [30: Update dependency vimeo/psalm to v5](https://github.com/laminas/laminas-config-aggregator/pull/30) thanks to @renovate[bot] 186 | 187 | #### Enhancement 188 | 189 | - [28: Add ability to preprocess the list of providers](https://github.com/laminas/laminas-config-aggregator/pull/28) thanks to @internalsystemerror 190 | 191 | ## 1.12.0 - 2022-11-22 192 | 193 | 194 | ----- 195 | 196 | ### Release Notes for [1.12.0](https://github.com/laminas/laminas-config-aggregator/milestone/21) 197 | 198 | Feature release (minor) 199 | 200 | ### 1.12.0 201 | 202 | - Total issues resolved: **0** 203 | - Total pull requests resolved: **1** 204 | - Total contributors: **1** 205 | 206 | #### Documentation,Enhancement 207 | 208 | - [29: Some minor type improvements](https://github.com/laminas/laminas-config-aggregator/pull/29) thanks to @internalsystemerror 209 | 210 | ## 1.11.0 - 2022-10-11 211 | 212 | 213 | ----- 214 | 215 | ### Release Notes for [1.11.0](https://github.com/laminas/laminas-config-aggregator/milestone/19) 216 | 217 | Feature release (minor) 218 | 219 | ### 1.11.0 220 | 221 | - Total issues resolved: **0** 222 | - Total pull requests resolved: **1** 223 | - Total contributors: **1** 224 | 225 | #### Enhancement 226 | 227 | - [27: Apply PHP 8.0 Syntax and constructor promotion](https://github.com/laminas/laminas-config-aggregator/pull/27) thanks to @samsonasik 228 | 229 | ## 1.10.0 - 2022-10-11 230 | 231 | 232 | ----- 233 | 234 | ### Release Notes for [1.10.0](https://github.com/laminas/laminas-config-aggregator/milestone/17) 235 | 236 | Feature release (minor) 237 | 238 | ### 1.10.0 239 | 240 | - Total issues resolved: **0** 241 | - Total pull requests resolved: **1** 242 | - Total contributors: **1** 243 | 244 | #### Enhancement 245 | 246 | - [26: Add support for PHP 8.2, Remove support for PHP 7.4](https://github.com/laminas/laminas-config-aggregator/pull/26) thanks to @gsteel 247 | 248 | ## 1.9.0 - 2022-09-15 249 | 250 | 251 | ----- 252 | 253 | ### Release Notes for [1.9.0](https://github.com/laminas/laminas-config-aggregator/milestone/15) 254 | 255 | Feature release (minor) 256 | 257 | ### 1.9.0 258 | 259 | - Total issues resolved: **0** 260 | - Total pull requests resolved: **1** 261 | - Total contributors: **1** 262 | 263 | #### Enhancement 264 | 265 | - [24: Apply PHP 7.4 syntax and typed property](https://github.com/laminas/laminas-config-aggregator/pull/24) thanks to @samsonasik 266 | 267 | ## 1.8.0 - 2022-07-24 268 | 269 | 270 | ----- 271 | 272 | ### Release Notes for [1.8.0](https://github.com/laminas/laminas-config-aggregator/milestone/13) 273 | 274 | Feature release (minor) 275 | 276 | ### 1.8.0 277 | 278 | - Total issues resolved: **0** 279 | - Total pull requests resolved: **3** 280 | - Total contributors: **3** 281 | 282 | #### Enhancement 283 | 284 | - [22: Drop Support for PHP 7.3](https://github.com/laminas/laminas-config-aggregator/pull/22) thanks to @gsteel 285 | - [20: Prepare for Renovate with reusable workflows](https://github.com/laminas/laminas-config-aggregator/pull/20) thanks to @ghostwriter 286 | 287 | #### renovate 288 | 289 | - [21: Configure Renovate](https://github.com/laminas/laminas-config-aggregator/pull/21) thanks to @renovate[bot] 290 | 291 | ## 1.7.0 - 2021-10-26 292 | 293 | 294 | ----- 295 | 296 | ### Release Notes for [1.7.0](https://github.com/laminas/laminas-config-aggregator/milestone/11) 297 | 298 | Feature release (minor) 299 | 300 | ### 1.7.0 301 | 302 | - Total issues resolved: **0** 303 | - Total pull requests resolved: **2** 304 | - Total contributors: **1** 305 | 306 | #### Enhancement,hacktoberfest-accepted 307 | 308 | - [19: Upgrade laminas-coding-standard to 2.3](https://github.com/laminas/laminas-config-aggregator/pull/19) thanks to @arueckauer 309 | 310 | #### Enhancement 311 | 312 | - [18: Remove file headers](https://github.com/laminas/laminas-config-aggregator/pull/18) thanks to @arueckauer 313 | 314 | ## 1.6.0 - 2021-09-15 315 | 316 | ### Changed 317 | 318 | - `Laminas\ConfigAggregator\ConfigAggregator` now accepts any iterable type for $providers constructor argument. 319 | 320 | 321 | ----- 322 | 323 | ### Release Notes for [1.6.0](https://github.com/laminas/laminas-config-aggregator/milestone/9) 324 | 325 | Feature release (minor) 326 | 327 | ### 1.6.0 328 | 329 | - Total issues resolved: **0** 330 | - Total pull requests resolved: **2** 331 | - Total contributors: **2** 332 | 333 | #### Enhancement 334 | 335 | - [17: PHP 8.1 support](https://github.com/laminas/laminas-config-aggregator/pull/17) thanks to @boesing 336 | - [14: Allow to pass an `iterable` of config providers to the `ConfigAggregator`](https://github.com/laminas/laminas-config-aggregator/pull/14) thanks to @ronan-gloo 337 | 338 | ## 1.5.0 - 2021-03-16 339 | 340 | 341 | ----- 342 | 343 | ### Release Notes for [1.5.0](https://github.com/laminas/laminas-config-aggregator/milestone/6) 344 | 345 | 346 | 347 | ### 1.5.0 348 | 349 | - Total issues resolved: **0** 350 | - Total pull requests resolved: **3** 351 | - Total contributors: **2** 352 | 353 | #### Enhancement 354 | 355 | - [13: Migrate to GitHub Actions and Initial Psalm Setup](https://github.com/laminas/laminas-config-aggregator/pull/13) thanks to @gsteel 356 | - [12: Ignore platform requirements only for nightly builds](https://github.com/laminas/laminas-config-aggregator/pull/12) thanks to @arueckauer 357 | - [11: Use local XML schema description file](https://github.com/laminas/laminas-config-aggregator/pull/11) thanks to @arueckauer 358 | 359 | ## 1.4.0 - 2020-11-18 360 | 361 | ### Added 362 | 363 | - [#10](https://github.com/laminas/laminas-config-aggregator/pull/10) Adds PHP 8.0 support 364 | 365 | 366 | ----- 367 | 368 | ### Release Notes for [1.4.0](https://github.com/laminas/laminas-config-aggregator/milestone/3) 369 | 370 | 371 | 372 | ### 1.4.0 373 | 374 | - Total issues resolved: **0** 375 | - Total pull requests resolved: **1** 376 | - Total contributors: **1** 377 | 378 | #### Enhancement 379 | 380 | - [10: PHP 8.0 support](https://github.com/laminas/laminas-config-aggregator/pull/10) thanks to @arueckauer 381 | 382 | ## 1.3.0 - 2020-07-08 383 | 384 | ### Added 385 | 386 | - [#7](https://github.com/laminas/laminas-config-aggregator/pull/7) adds support for caching closures when caching configuration. 387 | 388 | ### Changed 389 | 390 | - Nothing. 391 | 392 | ### Deprecated 393 | 394 | - Nothing. 395 | 396 | ### Removed 397 | 398 | - [#7](https://github.com/laminas/laminas-config-aggregator/pull/7) removes support for PHP versions prior to 7.2. 399 | 400 | ### Fixed 401 | 402 | - Nothing. 403 | 404 | ## 1.2.2 - 2020-03-29 405 | 406 | ### Added 407 | 408 | - Nothing. 409 | 410 | ### Changed 411 | 412 | - Nothing. 413 | 414 | ### Deprecated 415 | 416 | - Nothing. 417 | 418 | ### Removed 419 | 420 | - Nothing. 421 | 422 | ### Fixed 423 | 424 | - Fixed `replace` version constraint in composer.json so repository can be used as replacement of `zendframework/zend-config-aggregator:^1.2.0`. 425 | 426 | ## 1.2.1 - 2020-03-21 427 | 428 | ### Added 429 | 430 | - [#5](https://github.com/laminas/laminas-config-aggregator/pull/5) adds support for PHP 7.4. 431 | 432 | ### Changed 433 | 434 | - Nothing. 435 | 436 | ### Deprecated 437 | 438 | - Nothing. 439 | 440 | ### Removed 441 | 442 | - Nothing. 443 | 444 | ### Fixed 445 | 446 | - [#4](https://github.com/laminas/laminas-config-aggregator/pull/4) fixes creating cache file on Windows. Internally we are using now [webimpress/safe-writer](https://github.com/webimpress/safe-writer) to write cache files. 447 | 448 | ## 1.2.0 - 2019-12-27 449 | 450 | ### Added 451 | 452 | - [zendframework/zend-config-aggregator#23](https://github.com/zendframework/zend-config-aggregator/pull/23) adds the ability to specify the file mode for the generated cache file, when generating a cache file. The mode can be provided via the `Laminas\ConfigAggregator\ConfigAggregator::CACHE_FILEMODE` configuration option. Modes should be expressed as octal values (e.g., `0600`). 453 | 454 | - [zendframework/zend-config-aggregator#21](https://github.com/zendframework/zend-config-aggregator/pull/21) adds support for PHP 7.3. 455 | 456 | ### Changed 457 | 458 | - Nothing. 459 | 460 | ### Deprecated 461 | 462 | - Nothing. 463 | 464 | ### Removed 465 | 466 | - Nothing. 467 | 468 | ### Fixed 469 | 470 | - Nothing. 471 | 472 | ## 1.1.1 - 2018-04-04 473 | 474 | ### Added 475 | 476 | - [zendframework/zend-config-aggregator#18](https://github.com/zendframework/zend-config-aggregator/pull/18) adds 477 | a package suggestion for [laminas-config-aggregator-modulemanager](https://github.com/zendframework/zend-config-aggregator-modulemanager), 478 | which supplies a custom provider for using zend-mvc `Module` classes as 479 | configuration providers. 480 | 481 | - [zendframework/zend-config-aggregator#19](https://github.com/zendframework/zend-config-aggregator/pull/19) adds 482 | a package suggestion for [laminas-config-aggregator-parameters](https://github.com/zendframework/zend-config-aggregator-parameters), 483 | which supplies a post-processor consuming the Symfony DI `ParameterBag` in 484 | order to allow templated configuration parameter values. 485 | 486 | ### Changed 487 | 488 | - Nothing. 489 | 490 | ### Deprecated 491 | 492 | - Nothing. 493 | 494 | ### Removed 495 | 496 | - Nothing. 497 | 498 | ### Fixed 499 | 500 | - Nothing. 501 | 502 | ## 1.1.0 - 2018-02-26 503 | 504 | ### Added 505 | 506 | - [zendframework/zend-config-aggregator#12](https://github.com/zendframework/zend-config-aggregator/pull/12) adds 507 | post-processing capabilities. Post processors are PHP callables (or class 508 | names of classes that define `__invoke()`) that accept the configuration 509 | array, and return a processed configuration array. Like providers, they are 510 | provided as an array of values when defining the `ConfigAggregator` instance, 511 | and passed as the third constructor argument. One use case is to re-use values 512 | by referencing another configuration key, ala the Symfony DI ParameterBag. 513 | 514 | ### Changed 515 | 516 | - Nothing. 517 | 518 | ### Deprecated 519 | 520 | - Nothing. 521 | 522 | ### Removed 523 | 524 | - Nothing. 525 | 526 | ### Fixed 527 | 528 | - Nothing. 529 | 530 | ## 1.0.1 - 2017-11-06 531 | 532 | ### Added 533 | 534 | - Nothing. 535 | 536 | ### Deprecated 537 | 538 | - Nothing. 539 | 540 | ### Removed 541 | 542 | - Nothing. 543 | 544 | ### Fixed 545 | 546 | - [zendframework/zend-config-aggregator#14](https://github.com/zendframework/zend-config-aggregator/pull/14) fixes 547 | how file globbing of configuration files works on FreeBSD and IBM i Series 548 | systems. It does so by adding a dependency on laminas-stdlib, which provides a 549 | glob compatibility layer. 550 | 551 | ## 1.0.0 - 2017-04-24 552 | 553 | ### Added 554 | 555 | - [zendframework/zend-config-aggregator#7](https://github.com/zendframework/zend-config-aggregator/pull/7) adds 556 | online documentation at https://docs.laminas.dev/laminas-config-aggregator/ 557 | 558 | ### Deprecated 559 | 560 | - Nothing. 561 | 562 | ### Removed 563 | 564 | - Nothing. 565 | 566 | ### Fixed 567 | 568 | - Nothing. 569 | 570 | ## 0.2.1 - 2017-04-23 571 | 572 | ### Added 573 | 574 | - [zendframework/zend-config-aggregator#3](https://github.com/zendframework/zend-config-aggregator/pull/3) added 575 | laminas-config ^3.0 support 576 | 577 | ### Deprecated 578 | 579 | - Nothing. 580 | 581 | ### Removed 582 | 583 | - Nothing. 584 | 585 | ### Fixed 586 | 587 | - Nothing. 588 | 589 | ## 0.2.0 - 2017-01-11 590 | 591 | ### Added 592 | 593 | - [zendframework/zend-config-aggregator#2](https://github.com/zendframework/zend-config-aggregator/pull/2) adds a 594 | new `ArrayProvider`, which accepts an array to its constructor, and returns 595 | it when invoked. This can be used to provide in-line array configuration when 596 | feeding the `ConfigAggregator` instance. 597 | 598 | ### Deprecated 599 | 600 | - Nothing. 601 | 602 | ### Removed 603 | 604 | - Nothing. 605 | 606 | ### Fixed 607 | 608 | - Nothing. 609 | 610 | ## 0.1.0 - 2016-12-08 611 | 612 | Initial release. 613 | 614 | Based on the 0.4.0 version of [mtymek/mezzio-config-manager](https://github.com/mtymek/mezzio-config-manager), 615 | this version renames the namespace from `Mezzio\ConfigManager` to 616 | `Laminas\ConfigAggregator`, and renames the `ConfigManager` class to 617 | `ConfigAggregator`. All other functionality remains the same. 618 | --------------------------------------------------------------------------------