• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

codeigniter4 / settings / 13399286100

18 Feb 2025 08:14PM UTC coverage: 85.526%. Remained the same
13399286100

push

github

web-flow
chore: update dependencies to support PHP 8.1 - 8.4 (#145)

* move to PHP 8.1 and PHPUnit 10

* update tests

* cs fix

* update workflows

* update php version in the docs

* update rector config

* update psalm config

1 of 2 new or added lines in 2 files covered. (50.0%)

195 of 228 relevant lines covered (85.53%)

55.95 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

94.59
/src/Settings.php
1
<?php
2

3
namespace CodeIgniter\Settings;
4

5
use CodeIgniter\Settings\Config\Settings as SettingsConfig;
6
use CodeIgniter\Settings\Handlers\BaseHandler;
7
use InvalidArgumentException;
8
use RuntimeException;
9

10
/**
11
 * Allows developers a single location to store and
12
 * retrieve settings that were original set in config files
13
 * in the core application or any third-party module.
14
 */
15
class Settings
16
{
17
    /**
18
     * An array of handlers for getting/setting the values.
19
     *
20
     * @var list<BaseHandler>
21
     */
22
    private array $handlers = [];
23

24
    /**
25
     * An array of the config options for each handler.
26
     *
27
     * @var array<string,array<string,mixed>>
28
     */
29
    private ?array $options = null;
30

31
    /**
32
     * Grabs instances of our handlers.
33
     */
34
    public function __construct(SettingsConfig $config)
35
    {
36
        foreach ($config->handlers as $handler) {
162✔
37
            $class = $config->{$handler}['class'] ?? null;
162✔
38

39
            if ($class === null) {
162✔
40
                continue;
×
41
            }
42

43
            $this->handlers[$handler] = new $class();
162✔
44
            $this->options[$handler]  = $config->{$handler};
162✔
45
        }
46
    }
47

48
    /**
49
     * Retrieve a value from any handler
50
     * or from a config file matching the name
51
     * file.arg.optionalArg
52
     */
53
    public function get(string $key, ?string $context = null)
54
    {
55
        [$class, $property, $config] = $this->prepareClassAndProperty($key);
102✔
56

57
        // Check each of our handlers
58
        foreach ($this->handlers as $handler) {
96✔
59
            if ($handler->has($class, $property, $context)) {
96✔
60
                return $handler->get($class, $property, $context);
84✔
61
            }
62
        }
63

64
        // If no contextual value was found then fall back to general
65
        if ($context !== null) {
30✔
66
            return $this->get($key);
12✔
67
        }
68

69
        return $config->{$property} ?? null;
18✔
70
    }
71

72
    /**
73
     * Save a value to the writable handler for later retrieval.
74
     *
75
     * @param mixed $value
76
     *
77
     * @return void
78
     */
79
    public function set(string $key, $value = null, ?string $context = null)
80
    {
81
        [$class, $property] = $this->prepareClassAndProperty($key);
108✔
82

83
        foreach ($this->getWriteHandlers() as $handler) {
108✔
84
            $handler->set($class, $property, $value, $context);
108✔
85
        }
86
    }
87

88
    /**
89
     * Removes a setting from the persistent storage,
90
     * effectively returning the value to the default value
91
     * found in the config file, if any.
92
     *
93
     * @return void
94
     */
95
    public function forget(string $key, ?string $context = null)
96
    {
97
        [$class, $property] = $this->prepareClassAndProperty($key);
18✔
98

99
        foreach ($this->getWriteHandlers() as $handler) {
18✔
100
            $handler->forget($class, $property, $context);
18✔
101
        }
102
    }
103

104
    /**
105
     * Removes all settings from the persistent storage,
106
     * Useful during testing. Use with caution.
107
     *
108
     * @return void
109
     */
110
    public function flush()
111
    {
112
        foreach ($this->getWriteHandlers() as $handler) {
6✔
113
            $handler->flush();
6✔
114
        }
115
    }
116

117
    /**
118
     * Returns the handler that is set to store values.
119
     *
120
     * @return list<BaseHandler>
121
     *
122
     * @throws RuntimeException
123
     */
124
    private function getWriteHandlers()
125
    {
126
        $handlers = [];
120✔
127

128
        foreach ($this->options as $handler => $options) {
120✔
129
            if (! empty($options['writeable'])) {
120✔
130
                $handlers[] = $this->handlers[$handler];
120✔
131
            }
132
        }
133

134
        if ($handlers === []) {
120✔
135
            throw new RuntimeException('Unable to find a Settings handler that can store values.');
×
136
        }
137

138
        return $handlers;
120✔
139
    }
140

141
    /**
142
     * Analyzes the given key and breaks it into the class.field parts.
143
     *
144
     * @return list<string>
145
     *
146
     * @throws InvalidArgumentException
147
     */
148
    private function parseDotSyntax(string $key): array
149
    {
150
        // Parse the field name for class.field
151
        $parts = explode('.', $key);
138✔
152

153
        if (count($parts) === 1) {
138✔
154
            throw new InvalidArgumentException('$key must contain both the class and field name, i.e. Foo.bar');
6✔
155
        }
156

157
        return $parts;
132✔
158
    }
159

160
    /**
161
     * Given a key in class.property syntax, will split the values
162
     * and determine the fully qualified class name, if possible.
163
     */
164
    private function prepareClassAndProperty(string $key): array
165
    {
166
        [$class, $property] = $this->parseDotSyntax($key);
138✔
167

168
        $config = config($class);
132✔
169

170
        // Use a fully qualified class name if the
171
        // config file was found.
172
        if ($config !== null) {
132✔
173
            $class = $config::class;
108✔
174
        }
175

176
        return [$class, $property, $config];
132✔
177
    }
178
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc