Passed
Push — 4 ( d81415...e2bea6 )
by Maxime
07:41
created

Config   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 129
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 30
dl 0
loc 129
rs 10
c 0
b 0
f 0
wmc 9

6 Methods

Rating   Name   Duplication   Size   Complexity  
A forClass() 0 3 1
A inst() 0 3 1
A unnest() 0 13 2
A nest() 0 6 1
A withConfig() 0 9 1
A modify() 0 14 3
1
<?php
2
3
namespace SilverStripe\Core\Config;
4
5
use InvalidArgumentException;
6
use SilverStripe\Config\Collections\ConfigCollectionInterface;
7
use SilverStripe\Config\Collections\MutableConfigCollectionInterface;
8
9
abstract class Config
10
{
11
12
    // -- Source options bitmask --
13
14
    /**
15
     * source options bitmask value - only get configuration set for this
16
     * specific class, not any of it's parents.
17
     *
18
     * @const
19
     */
20
    const UNINHERITED = 1;
21
22
    /**
23
     * @const source options bitmask value - do not use additional statics
24
     * sources (such as extension)
25
     */
26
    const EXCLUDE_EXTRA_SOURCES = 4;
27
28
    /**
29
     * Disable all modifications to the config
30
     *
31
     * @const
32
     */
33
    const NO_DELTAS = 8;
34
35
    /**
36
     * Get the current active Config instance.
37
     *
38
     * In general use you will use this method to obtain the current Config
39
     * instance. It assumes the config instance has already been set.
40
     *
41
     * @return ConfigCollectionInterface
42
     */
43
    public static function inst()
44
    {
45
        return ConfigLoader::inst()->getManifest();
46
    }
47
48
    /**
49
     * Make this config available to be modified
50
     *
51
     * @return MutableConfigCollectionInterface
52
     */
53
    public static function modify()
54
    {
55
        $instance = static::inst();
56
        if ($instance instanceof MutableConfigCollectionInterface) {
57
            return $instance;
58
        }
59
60
        // By default nested configs should become mutable
61
        $instance = static::nest();
62
        if ($instance instanceof MutableConfigCollectionInterface) {
63
            return $instance;
64
        }
65
66
        throw new InvalidArgumentException("Nested config could not be made mutable");
67
    }
68
69
    /**
70
     * Make the newly active {@link Config} be a copy of the current active
71
     * {@link Config} instance.
72
     *
73
     * You can then make changes to the configuration by calling update and
74
     * remove on the new value returned by {@link Config::inst()}, and then discard
75
     * those changes later by calling unnest.
76
     *
77
     * @return ConfigCollectionInterface Active config
78
     */
79
    public static function nest()
80
    {
81
        // Clone current config and nest
82
        $new = self::inst()->nest();
83
        ConfigLoader::inst()->pushManifest($new);
84
        return $new;
85
    }
86
87
    /**
88
     * Change the active Config back to the Config instance the current active
89
     * Config object was copied from.
90
     *
91
     * @return ConfigCollectionInterface
92
     */
93
    public static function unnest()
94
    {
95
        // Unnest unless we would be left at 0 manifests
96
        $loader = ConfigLoader::inst();
97
        if ($loader->countManifests() <= 1) {
98
            user_error(
99
                "Unable to unnest root Config, please make sure you don't have mis-matched nest/unnest",
100
                E_USER_WARNING
101
            );
102
        } else {
103
            $loader->popManifest();
104
        }
105
        return static::inst();
106
    }
107
108
    /**
109
     * Get an accessor that returns results by class by default.
110
     *
111
     * Shouldn't be overridden, since there might be many Config_ForClass instances already held in the wild. Each
112
     * Config_ForClass instance asks the current_instance of Config for the actual result, so override that instead
113
     *
114
     * @param string $class
115
     * @return Config_ForClass
116
     */
117
    public static function forClass($class)
118
    {
119
        return new Config_ForClass($class);
120
    }
121
122
    /**
123
     * Perform the given operation in an isolated config state.
124
     * On return, the config state will be restored, so any modifications are temporary.
125
     *
126
     * @param callable $callback Callback to run. Will be passed the nested config state as a parameter
127
     * @return mixed Result of callback
128
     */
129
    public static function withConfig($callback)
130
    {
131
        static::nest();
132
        $config = static::modify();
133
134
        try {
135
            return $callback($config);
136
        } finally {
137
            static::unnest();
138
        }
139
    }
140
}
141