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

ExtensionMiddleware::getExtraConfig()   C

Complexity

Conditions 8
Paths 10

Size

Total Lines 37
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 21
nc 10
nop 2
dl 0
loc 37
rs 5.3846
c 0
b 0
f 0
1
<?php
2
3
namespace SilverStripe\Core\Config\Middleware;
4
5
use Generator;
6
use InvalidArgumentException;
7
use SilverStripe\Config\MergeStrategy\Priority;
8
use SilverStripe\Config\Middleware\Middleware;
9
use SilverStripe\Core\ClassInfo;
10
use SilverStripe\Core\Config\Config;
11
use SilverStripe\Core\Object;
12
13
class ExtensionMiddleware implements Middleware
14
{
15
    use MiddlewareCommon;
16
17
    /**
18
     * Get config for a class
19
     *
20
     * @param string $class Name of class
21
     * @param int|true $excludeMiddleware Middleware disable flags
22
     * @param callable $next Callback to next middleware
23
     * @return array Complete class config
24
     */
25
    public function getClassConfig($class, $excludeMiddleware, $next)
26
    {
27
        // Get base config
28
        $config = $next($class, $excludeMiddleware);
29
30
        if (!$this->enabled($excludeMiddleware)) {
31
            return $config;
32
        }
33
34
        foreach ($this->getExtraConfig($class, $config) as $extra) {
35
            $config = Priority::mergeArray($extra, $config);
36
        }
37
        return $config;
38
    }
39
40
    /**
41
     * Applied config to a class from its extensions
42
     *
43
     * @param string $class
44
     * @param array $classConfig
45
     * @return Generator
46
     */
47
    protected function getExtraConfig($class, $classConfig)
48
    {
49
        if (empty($classConfig['extensions'])) {
50
            return;
51
        }
52
53
        $extensions = $classConfig['extensions'];
54
        foreach ($extensions as $extension) {
55
            list($extensionClass, $extensionArgs) = Object::parse_class_spec($extension);
56
            if (!class_exists($extensionClass)) {
57
                throw new InvalidArgumentException("$class references nonexistent $extensionClass in 'extensions'");
58
            }
59
60
            // Init extension
61
            call_user_func(array($extensionClass, 'add_to_class'), $class, $extensionClass, $extensionArgs);
62
63
            // Check class hierarchy from root up
64
            foreach (ClassInfo::ancestry($extensionClass) as $extensionClassParent) {
65
                // Merge config from extension
66
                $extensionConfig = Config::inst()->get($extensionClassParent, null, true);
67
                if ($extensionConfig) {
68
                    yield $extensionConfig;
69
                }
70
                if (ClassInfo::has_method_from($extensionClassParent, 'get_extra_config', $extensionClassParent)) {
71
                    $extensionConfig = call_user_func(
72
                        [ $extensionClassParent, 'get_extra_config' ],
73
                        $class,
74
                        $extensionClass,
75
                        $extensionArgs
76
                    );
77
                    if ($extensionConfig) {
78
                        yield $extensionConfig;
79
                    }
80
                }
81
            }
82
        }
83
    }
84
}
85