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

codeigniter4 / settings / 20033287059

08 Dec 2025 03:25PM UTC coverage: 81.911%. First build
20033287059

Pull #157

github

web-flow
Merge e972c1655 into 7fb10c218
Pull Request #157: Implement a getAll function

0 of 29 new or added lines in 3 files covered. (0.0%)

403 of 492 relevant lines covered (81.91%)

13.34 hits per line

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

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

3
namespace CodeIgniter\Settings;
4

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

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

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

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

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

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

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

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

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

70
        return $config->{$property} ?? null;
9✔
71
    }
72

73
    /**
74
     * Retrieve all values from any handler
75
     * file.arg.optionalArg
76
     */
77
    public function getAll(?string $key = null, ?string $context = null): array
78
    {
NEW
79
        if($key !== null) {
×
NEW
80
            [$class,,] = $this->prepareClassAndProperty($key . ".");
×
81
        } else {
NEW
82
            $class = null;
×
83
        }
84

NEW
85
        $properties = array();
×
86

87
        // Add handlers
NEW
88
        foreach ($this->handlers as $handler) {
×
NEW
89
            $properties[get_class($handler)] = $handler->getAll($class, $context);
×
90
        }
91

NEW
92
        return $properties;
×
93
    }
94

95
    /**
96
     * Save a value to the writable handler for later retrieval.
97
     *
98
     * @param mixed $value
99
     *
100
     * @return void
101
     */
102
    public function set(string $key, $value = null, ?string $context = null)
103
    {
104
        [$class, $property] = $this->prepareClassAndProperty($key);
54✔
105

106
        foreach ($this->getWriteHandlers() as $handler) {
54✔
107
            $handler->set($class, $property, $value, $context);
54✔
108
        }
109
    }
110

111
    /**
112
     * Removes a setting from the persistent storage,
113
     * effectively returning the value to the default value
114
     * found in the config file, if any.
115
     *
116
     * @return void
117
     */
118
    public function forget(string $key, ?string $context = null)
119
    {
120
        [$class, $property] = $this->prepareClassAndProperty($key);
9✔
121

122
        foreach ($this->getWriteHandlers() as $handler) {
9✔
123
            $handler->forget($class, $property, $context);
9✔
124
        }
125
    }
126

127
    /**
128
     * Removes all settings from the persistent storage,
129
     * Useful during testing. Use with caution.
130
     *
131
     * @return void
132
     */
133
    public function flush()
134
    {
135
        foreach ($this->getWriteHandlers() as $handler) {
9✔
136
            $handler->flush();
9✔
137
        }
138
    }
139

140
    /**
141
     * Returns the handler that is set to store values.
142
     *
143
     * @return list<BaseHandler>
144
     *
145
     * @throws RuntimeException
146
     */
147
    private function getWriteHandlers()
148
    {
149
        $handlers = [];
62✔
150

151
        foreach ($this->options as $handler => $options) {
62✔
152
            if (! empty($options['writeable'])) {
62✔
153
                $handlers[] = $this->handlers[$handler];
62✔
154
            }
155
        }
156

157
        if ($handlers === []) {
62✔
158
            throw new RuntimeException('Unable to find a Settings handler that can store values.');
×
159
        }
160

161
        return $handlers;
62✔
162
    }
163

164
    /**
165
     * Analyzes the given key and breaks it into the class.field parts.
166
     *
167
     * @return list<string>
168
     *
169
     * @throws InvalidArgumentException
170
     */
171
    private function parseDotSyntax(string $key): array
172
    {
173
        // Parse the field name for class.field
174
        $parts = explode('.', $key);
61✔
175

176
        if (count($parts) === 1) {
61✔
177
            throw new InvalidArgumentException('$key must contain both the class and field name, i.e. Foo.bar');
1✔
178
        }
179

180
        return $parts;
60✔
181
    }
182

183
    /**
184
     * Given a key in class.property syntax, will split the values
185
     * and determine the fully qualified class name, if possible.
186
     *
187
     * @return array{string, string, BaseConfig|null}
188
     */
189
    private function prepareClassAndProperty(string $key): array
190
    {
191
        [$class, $property] = $this->parseDotSyntax($key);
61✔
192

193
        $config = config($class);
60✔
194

195
        // Use a fully qualified class name if the
196
        // config file was found.
197
        if ($config !== null) {
60✔
198
            $class = $config::class;
55✔
199
        }
200

201
        return [$class, $property, $config];
60✔
202
    }
203
}
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

© 2025 Coveralls, Inc