BuildConstructionPlan   A
last analyzed

Complexity

Total Complexity 23

Size/Duplication

Total Lines 152
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
dl 0
loc 152
rs 10
c 0
b 0
f 0
wmc 23
lcom 1
cbo 1

9 Methods

Rating   Name   Duplication   Size   Complexity  
A fromConfig() 0 10 1
A fromConfigRecursive() 0 21 2
A fromConfigFile() 0 10 2
A validateConfig() 0 27 5
A overwriteParentData() 0 10 3
A addCustomData() 0 11 3
A applyDataModifications() 0 16 1
A addSubcomponents() 0 29 4
A mapAreaComponents() 0 7 2
1
<?php
2
3
namespace Flynt;
4
5
class BuildConstructionPlan
6
{
7
    public static function fromConfig($config)
8
    {
9
        do_action('Flynt/beforeBuildConstructionPlan', $config);
10
11
        $constructionPlan = self::fromConfigRecursive($config);
12
13
        do_action('Flynt/afterBuildConstructionPlan', $constructionPlan);
14
15
        return $constructionPlan;
16
    }
17
18
    protected static function fromConfigRecursive($config, $parentData = [])
19
    {
20
        // Check configuration for errors
21
        if (false === self::validateConfig($config)) {
22
            return [];
23
        }
24
25
        $config['data'] = [];
26
27
        // check for parent data overwrite
28
        $parentData = self::overwriteParentData($config, $parentData);
29
30
        // add data to component
31
        $config = self::addCustomData($config);
32
33
        // apply addComponentData filters to be used in a functions.php of a component for example
34
        $config = self::applyDataModifications($config, $parentData);
35
36
        // add subcomponents (dynamic + static) and return construction plan for the current component
37
        return self::addSubcomponents($config, $parentData);
38
    }
39
40
    public static function fromConfigFile($configFileName)
41
    {
42
        $configFilePath = apply_filters('Flynt/configPath', null, $configFileName);
43
        if (!is_file($configFilePath)) {
44
            trigger_error('Config file not found: ' . $configFilePath, E_USER_WARNING);
45
            return [];
46
        }
47
        $config = apply_filters('Flynt/configFileLoader', null, $configFileName, $configFilePath);
48
        return self::fromConfig($config);
49
    }
50
51
    protected static function validateConfig($config)
52
    {
53
        if (!is_array($config)) {
54
            trigger_error('Config needs to be an array! ' . gettype($config) . ' given.', E_USER_WARNING);
55
            return false;
56
        }
57
        if (empty($config)) {
58
            trigger_error('Config is empty!', E_USER_WARNING);
59
            return false;
60
        }
61
        if (!array_key_exists('name', $config)) {
62
            trigger_error(
63
                'No component name given! Please make sure every component has at least a \'name\' attribute.',
64
                E_USER_WARNING
65
            );
66
            return false;
67
        }
68
        // check if this component is registered
69
        $componentManager = ComponentManager::getInstance();
70
        if (false === $componentManager->isRegistered($config['name'])) {
71
            trigger_error(
72
                "Component '{$config['name']}' could not be found in component list. Did you forget to register the component?",
73
                E_USER_WARNING
74
            );
75
            return false;
76
        }
77
    }
78
79
    protected static function overwriteParentData(&$config, $parentData)
80
    {
81
        if (array_key_exists('parentData', $config)) {
82
            if (is_array($config['parentData'])) {
83
                $parentData = $config['parentData'];
84
            }
85
            unset($config['parentData']);
86
        }
87
        return $parentData;
88
    }
89
90
    protected static function addCustomData($config)
91
    {
92
        if (array_key_exists('customData', $config)) {
93
            if (is_array($config['customData'])) {
94
                // custom data overwrites original data
95
                $config['data'] = array_merge($config['data'], $config['customData']);
96
            }
97
            unset($config['customData']);
98
        }
99
        return $config;
100
    }
101
102
    protected static function applyDataModifications($config, $parentData)
103
    {
104
        $config['data'] = apply_filters(
105
            'Flynt/addComponentData',
106
            $config['data'],
107
            $parentData,
108
            $config
109
        );
110
        $config['data'] = apply_filters(
111
            "Flynt/addComponentData?name={$config['name']}",
112
            $config['data'],
113
            $parentData,
114
            $config
115
        );
116
        return $config;
117
    }
118
119
    protected static function addSubcomponents($config, $parentData)
120
    {
121
        // add dynamic subcomponents to areas
122
        $areas = array_key_exists('areas', $config) ? $config['areas'] : [];
123
        $config['areas'] = apply_filters(
124
            "Flynt/dynamicSubcomponents?name={$config['name']}",
125
            $areas,
126
            $config['data'],
127
            $parentData
128
        );
129
130
        // iterate areas and recursively map child component construction plan
131
        if (!empty($config['areas'])) {
132
            $areaNames = array_keys($config['areas']);
133
            $config['areas'] = array_reduce($areaNames, function ($output, $areaName) use ($config, $parentData) {
134
                $components = $config['areas'][$areaName];
135
                $output[$areaName] = array_filter(self::mapAreaComponents($components, $config, $areaName, $parentData));
136
                return $output;
137
            }, []);
138
        }
139
140
        // remove empty 'areas' key from config
141
        // this can happen if there were no areas defined to begin with
142
        if (empty($config['areas'])) {
143
            unset($config['areas']);
144
        }
145
146
        return $config;
147
    }
148
149
    protected static function mapAreaComponents($components, $config, $areaName, $parentData)
150
    {
151
        return array_map(function ($component) use ($config, $areaName, $parentData) {
152
            $data = empty($config['data']) ? $parentData : $config['data'];
153
            return self::fromConfigRecursive($component, $data);
154
        }, $components);
155
    }
156
}
157