Completed
Push — master ( deca00...5388ff )
by Sam
24s
created

CoreConfigFactory::inst()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 0
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace SilverStripe\Core\Config;
4
5
use SilverStripe\Config\Collections\CachedConfigCollection;
6
use SilverStripe\Config\Collections\MemoryConfigCollection;
7
use SilverStripe\Config\Transformer\PrivateStaticTransformer;
8
use SilverStripe\Config\Transformer\YamlTransformer;
9
use SilverStripe\Control\Director;
10
use SilverStripe\Core\Config\Middleware\ExtensionMiddleware;
11
use SilverStripe\Core\Config\Middleware\InheritanceMiddleware;
12
use SilverStripe\Core\Manifest\ClassLoader;
13
use SilverStripe\Core\Manifest\ModuleLoader;
14
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
15
use Symfony\Component\Finder\Finder;
16
17
/**
18
 * Factory for silverstripe configs
19
 */
20
class CoreConfigFactory
21
{
22
    /**
23
     * @var static
24
     */
25
    protected static $inst = null;
26
27
    /**
28
     * @return static
29
     */
30
    public static function inst()
31
    {
32
        if (!self::$inst) {
33
            self::$inst = new static();
34
        }
35
        return self::$inst;
36
    }
37
38
    /**
39
     * Create root application config.
40
     * This will be an immutable cached config,
41
     * which conditionally generates a nested "core" config.
42
     *
43
     * @param bool $flush
44
     * @return CachedConfigCollection
45
     */
46
    public function createRoot($flush)
47
    {
48
        $instance = new CachedConfigCollection();
49
50
        // Set root cache
51
        $instance->setPool(new FilesystemAdapter('configcache', 0, getTempFolder()));
52
        $instance->setFlush($flush);
53
54
        // Set collection creator
55
        $instance->setCollectionCreator(function () {
56
            return $this->createCore();
57
        });
58
59
        return $instance;
60
    }
61
62
    /**
63
     * Rebuild new uncached config, which is mutable
64
     *
65
     * @return MemoryConfigCollection
66
     */
67
    public function createCore()
68
    {
69
        $config = new MemoryConfigCollection();
70
71
        // Set default middleware
72
        $config->setMiddlewares([
73
            new InheritanceMiddleware(Config::UNINHERITED),
74
            new ExtensionMiddleware(Config::EXCLUDE_EXTRA_SOURCES),
75
        ]);
76
77
        // Transform
78
        $config->transform([
79
            $this->buildStaticTransformer(),
80
            $this->buildYamlTransformer()
81
        ]);
82
83
        return $config;
84
    }
85
86
    /**
87
     * @return YamlTransformer
88
     */
89
    protected function buildYamlTransformer()
90
    {
91
        // Get all module dirs
92
        $modules = ModuleLoader::instance()->getManifest()->getModules();
93
        $dirs = [];
94
        foreach ($modules as $module) {
95
            // Load from _config dirs
96
            $path = $module->getPath() . '/_config';
97
            if (is_dir($path)) {
98
                $dirs[] = $path;
99
            }
100
        }
101
102
        return $this->buildYamlTransformerForPath($dirs);
103
    }
104
105
    /**
106
     * @return PrivateStaticTransformer
107
     */
108
    public function buildStaticTransformer()
109
    {
110
        return new PrivateStaticTransformer(function () {
111
            $classes = ClassLoader::instance()->getManifest()->getClasses();
112
            return array_keys($classes);
113
        });
114
    }
115
116
    /**
117
     * @param array|string $dirs Base dir to load from
118
     * @return YamlTransformer
119
     */
120
    public function buildYamlTransformerForPath($dirs)
121
    {
122
        // Construct
123
        $transformer = YamlTransformer::create(
124
            BASE_PATH,
125
            Finder::create()
126
                ->in($dirs)
127
                ->files()
128
                ->name('/\.(yml|yaml)$/')
129
        );
130
131
        // Add default rules
132
        $envvarset = function ($var, $value = null) {
133
            if (getenv($var) === false) {
134
                return false;
135
            }
136
            if ($value) {
137
                return getenv($var) === $value;
138
            }
139
            return true;
140
        };
141
        $constantdefined = function ($const, $value = null) {
142
            if (!defined($const)) {
143
                return false;
144
            }
145
            if ($value) {
146
                return constant($const) === $value;
147
            }
148
            return true;
149
        };
150
        return $transformer
151
            ->addRule('classexists', function ($class) {
152
                return class_exists($class);
153
            })
154
            ->addRule('envvarset', $envvarset)
155
            ->addRule('constantdefined', $constantdefined)
156
            ->addRule(
157
                'envorconstant',
158
                // Composite rule
159
                function ($name, $value = null) use ($envvarset, $constantdefined) {
160
                    return $envvarset($name, $value) || $constantdefined($name, $value);
161
                }
162
            )
163
            ->addRule('environment', function ($env) {
164
                $current = Director::get_environment_type();
165
                return strtolower($current) === strtolower($env);
166
            })
167
            ->addRule('moduleexists', function ($module) {
168
                return ModuleLoader::instance()->getManifest()->moduleExists($module);
169
            });
170
    }
171
}
172