Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
22 / 22
100.00% covered (success)
100.00%
4 / 4
CRAP
n/a
0 / 0
FastForward\Config\config
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
9
FastForward\Config\configCache
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
FastForward\Config\configDir
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
FastForward\Config\configProvider
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5/**
6 * This file is part of php-fast-forward/config.
7 *
8 * This source file is subject to the license bundled
9 * with this source code in the file LICENSE.
10 *
11 * @link      https://github.com/php-fast-forward/config
12 * @copyright Copyright (c) 2025 Felipe SayĆ£o Lobato Abreu <github@mentordosnerds.com>
13 * @license   https://opensource.org/licenses/MIT MIT License
14 */
15
16namespace FastForward\Config;
17
18use Psr\SimpleCache\CacheInterface;
19
20/**
21 * Creates a unified configuration object from various sources.
22 *
23 * This function SHALL normalize and aggregate mixed input types such as arrays,
24 * directories, and Laminas configuration providers into a single configuration instance.
25 *
26 * @param array|ConfigInterface|string ...$configs The configuration sources.
27 *
28 * @return ConfigInterface the aggregated configuration instance
29 */
30function config(
31    array|ConfigInterface|string ...$configs,
32): ConfigInterface {
33    foreach ($configs as $index => $config) {
34        if (\is_array($config)) {
35            $configs[$index] = new ArrayConfig($config);
36        }
37
38        if (\is_string($config) && is_dir($config) && is_readable($config)) {
39            $configs[$index] = configDir($config, true);
40        }
41
42        if (\is_string($config)
43            && class_exists($config)
44            && method_exists($config, '__invoke')
45        ) {
46            $configs[$index] = configProvider([$config]);
47        }
48    }
49
50    return new AggregateConfig(...$configs);
51}
52
53/**
54 * Creates a cached configuration object from various sources.
55 *
56 * This function SHALL wrap the configuration in a caching layer using PSR-16 CacheInterface.
57 *
58 * @param CacheInterface               $cache      the cache pool for storing configuration data
59 * @param array|ConfigInterface|string ...$configs The configuration sources.
60 *
61 * @return ConfigInterface the cached configuration instance
62 */
63function configCache(
64    CacheInterface $cache,
65    array|ConfigInterface|string ...$configs,
66): ConfigInterface {
67    return new CachedConfig(
68        cache: $cache,
69        defaultConfig: config(...$configs),
70    );
71}
72
73/**
74 * Creates a directory-based configuration provider.
75 *
76 * If the recursive flag is TRUE, nested directories SHALL be included in the scan.
77 * Configuration files MUST follow the PHP file format.
78 *
79 * @param string      $rootDirectory    the directory to load configuration files from
80 * @param bool        $recursive        whether to include files in subdirectories recursively
81 * @param null|string $cachedConfigFile optional path to a cache file for the configuration
82 *
83 * @return ConfigInterface the resulting configuration provider instance
84 */
85function configDir(
86    string $rootDirectory,
87    bool $recursive = false,
88    ?string $cachedConfigFile = null,
89): ConfigInterface {
90    $configClass = $recursive
91        ? RecursiveDirectoryConfig::class
92        : DirectoryConfig::class;
93
94    return new $configClass($rootDirectory, $cachedConfigFile);
95}
96
97/**
98 * Creates a configuration from a list of Laminas-style configuration providers.
99 *
100 * Each provider MUST be invokable and return an array or configuration structure.
101 *
102 * @param iterable    $providers        a list of configuration providers
103 * @param null|string $cachedConfigFile optional path to a cache file for the configuration
104 *
105 * @return ConfigInterface the resulting configuration instance
106 */
107function configProvider(
108    iterable $providers,
109    ?string $cachedConfigFile = null,
110): ConfigInterface {
111    return new LamiasConfigAggregatorConfig(
112        providers: $providers,
113        cachedConfigFile: $cachedConfigFile,
114    );
115}